Files
Todo-App-Backend/DATABASE_DOCUMENTATION.md
2026-04-29 14:20:41 +02:00

549 lines
20 KiB
Markdown

# Todo App Backend - Database Documentation
## Overview
This document describes the database schema for the Todo App Backend, built with CodeIgniter 4 and MySQL. The database supports user accounts, todo management, recurring tasks, activity logging, theme marketplace, and AI-powered chat features.
## Database Schema
### Core Tables
#### 1. users
Stores user account information and application settings.
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| id | CHAR(36) | NO | Primary key (UUID) |
| email | VARCHAR(255) | NO | User email (unique) |
| password_hash | VARCHAR(255) | NO | Bcrypt hashed password |
| name | VARCHAR(255) | YES | Display name |
| avatar_url | TEXT | YES | Profile image URL |
| settings | JSON | YES | App preferences (language, default view, etc.) |
| created_at | DATETIME | YES | Creation timestamp |
| updated_at | DATETIME | YES | Last update timestamp |
**Indexes:**
- PRIMARY KEY (id)
- UNIQUE KEY (email)
---
#### 2. categories
Per-user categories for organizing todos.
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| id | CHAR(36) | NO | Primary key (UUID) |
| user_id | CHAR(36) | NO | Foreign key to users |
| name | VARCHAR(255) | NO | Category name |
| color | VARCHAR(7) | YES | Hex color code for UI |
| favorite | BOOLEAN | NO | Mark as favorite |
| created_at | DATETIME | YES | Creation timestamp |
**Indexes:**
- PRIMARY KEY (id)
- KEY (user_id)
- UNIQUE KEY (user_id, name)
**Foreign Keys:**
- user_id → users(id) ON DELETE CASCADE
---
#### 3. projects
Optional project grouping for todos.
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| id | CHAR(36) | NO | Primary key (UUID) |
| user_id | CHAR(36) | NO | Foreign key to users |
| name | VARCHAR(255) | NO | Project name |
| description | TEXT | YES | Project description |
| color | VARCHAR(7) | YES | Hex color code for UI |
| created_at | DATETIME | YES | Creation timestamp |
**Indexes:**
- PRIMARY KEY (id)
- KEY (user_id)
**Foreign Keys:**
- user_id → users(id) ON DELETE CASCADE
---
#### 4. todos
Main todo items.
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| id | CHAR(36) | NO | Primary key (UUID) |
| user_id | CHAR(36) | NO | Foreign key to users |
| title | VARCHAR(255) | NO | Todo title |
| description | TEXT | YES | Detailed description |
| status | ENUM | NO | open, in_progress, completed, archived |
| due_date | DATE | YES | Due date |
| due_time | TIME | YES | Due time |
| sync_enabled | BOOLEAN | NO | Sync with external services |
| reminder_enabled | BOOLEAN | NO | Enable reminders |
| recurring_enabled | BOOLEAN | NO | Mark as recurring |
| project_id | CHAR(36) | YES | Foreign key to projects |
| created_at | DATETIME | YES | Creation timestamp |
| updated_at | DATETIME | YES | Last update timestamp |
**Indexes:**
- PRIMARY KEY (id)
- KEY (user_id)
- KEY (due_date)
- KEY (status)
**Foreign Keys:**
- user_id → users(id) ON DELETE CASCADE
- project_id → projects(id) ON DELETE SET NULL
---
#### 5. todo_categories (Junction Table)
Many-to-many relationship between todos and categories.
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| todo_id | CHAR(36) | NO | Foreign key to todos |
| category_id | CHAR(36) | NO | Foreign key to categories |
**Indexes:**
- PRIMARY KEY (todo_id, category_id)
**Foreign Keys:**
- todo_id → todos(id) ON DELETE CASCADE
- category_id → categories(id) ON DELETE CASCADE
---
#### 6. recurring_tasks
Templates for recurring todo items.
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| id | CHAR(36) | NO | Primary key (UUID) |
| user_id | CHAR(36) | NO | Foreign key to users |
| title | VARCHAR(255) | NO | Task title |
| description | TEXT | YES | Task description |
| schedule | ENUM | NO | daily, weekly, monthly, custom |
| custom_days | JSON | YES | Array of days (e.g., ["mon","wed","fri"]) |
| favorite | BOOLEAN | NO | Mark as favorite |
| created_at | DATETIME | YES | Creation timestamp |
| updated_at | DATETIME | YES | Last update timestamp |
**Indexes:**
- PRIMARY KEY (id)
- KEY (user_id)
**Foreign Keys:**
- user_id → users(id) ON DELETE CASCADE
---
#### 7. recurring_task_categories (Junction Table)
Many-to-many relationship between recurring tasks and categories.
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| recurring_task_id | CHAR(36) | NO | Foreign key to recurring_tasks |
| category_id | CHAR(36) | NO | Foreign key to categories |
**Indexes:**
- PRIMARY KEY (recurring_task_id, category_id)
**Foreign Keys:**
- recurring_task_id → recurring_tasks(id) ON DELETE CASCADE
- category_id → categories(id) ON DELETE CASCADE
---
### Activity Logging
#### 8. activity_logs
Audit trail for user actions and system events.
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| id | CHAR(36) | NO | Primary key (UUID) |
| user_id | CHAR(36) | YES | Foreign key to users (nullable for anonymous) |
| action | VARCHAR(255) | NO | Action type (e.g., todo_created, login) |
| entity_type | VARCHAR(100) | YES | Entity type (todo, category, project, etc.) |
| entity_id | CHAR(36) | YES | Entity ID |
| details | JSON | YES | Additional metadata (before/after values) |
| ip_address | VARCHAR(45) | YES | User IP address |
| user_agent | TEXT | YES | Browser user agent |
| created_at | DATETIME | YES | Creation timestamp |
**Indexes:**
- PRIMARY KEY (id)
- KEY (user_id)
- KEY (created_at)
- KEY (action)
- KEY (entity_type, entity_id)
**Foreign Keys:**
- user_id → users(id) ON DELETE SET NULL
---
### Theme Marketplace
#### 9. marketplace_themes
Master list of available themes in the marketplace.
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| id | CHAR(36) | NO | Primary key (UUID) |
| name | VARCHAR(255) | NO | Theme identifier (unique) |
| display_name | VARCHAR(255) | NO | Human-readable name |
| description | TEXT | YES | Theme description |
| author | VARCHAR(255) | YES | Theme author |
| version | VARCHAR(50) | YES | Theme version |
| thumbnail_url | TEXT | YES | Preview image URL |
| download_url | TEXT | NO | Download URL |
| price | DECIMAL(10,2) | NO | Theme price (0 = free) |
| is_published | BOOLEAN | NO | Published status |
| metadata | JSON | YES | Tags, screenshots, etc. |
| created_at | DATETIME | YES | Creation timestamp |
| updated_at | DATETIME | YES | Last update timestamp |
**Indexes:**
- PRIMARY KEY (id)
- UNIQUE KEY (name)
---
#### 10. user_themes
Themes installed by users.
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| id | CHAR(36) | NO | Primary key (UUID) |
| user_id | CHAR(36) | NO | Foreign key to users |
| theme_id | CHAR(36) | NO | Foreign key to marketplace_themes |
| installed_at | DATETIME | YES | Installation timestamp |
| active | BOOLEAN | NO | Currently active theme |
| custom_settings | JSON | YES | User theme overrides |
**Indexes:**
- PRIMARY KEY (id)
- UNIQUE KEY (user_id, theme_id)
**Foreign Keys:**
- user_id → users(id) ON DELETE CASCADE
- theme_id → marketplace_themes(id) ON DELETE CASCADE
---
### AI Features
#### 11. ai_providers
Supported AI providers (OpenAI, Anthropic, Google, etc.).
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| id | CHAR(36) | NO | Primary key (UUID) |
| name | VARCHAR(100) | NO | Provider identifier (unique) |
| display_name | VARCHAR(255) | NO | Human-readable name |
| base_url | TEXT | YES | API endpoint override |
| is_builtin | BOOLEAN | NO | System vs custom provider |
| created_at | DATETIME | YES | Creation timestamp |
**Indexes:**
- PRIMARY KEY (id)
- UNIQUE KEY (name)
---
#### 12. user_api_keys
Encrypted API keys for each provider per user.
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| id | CHAR(36) | NO | Primary key (UUID) |
| user_id | CHAR(36) | NO | Foreign key to users |
| provider_id | CHAR(36) | NO | Foreign key to ai_providers |
| api_key_encrypted | TEXT | NO | Encrypted API key |
| label | VARCHAR(255) | YES | Key label (e.g., "Work Key") |
| is_active | BOOLEAN | NO | Active status |
| created_at | DATETIME | YES | Creation timestamp |
| last_used_at | DATETIME | YES | Last usage timestamp |
**Indexes:**
- PRIMARY KEY (id)
- UNIQUE KEY (user_id, provider_id)
**Foreign Keys:**
- user_id → users(id) ON DELETE CASCADE
- provider_id → ai_providers(id) ON DELETE CASCADE
---
#### 13. user_ai_settings
Per-user AI preferences.
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| user_id | CHAR(36) | NO | Primary key, Foreign key to users |
| default_provider_id | CHAR(36) | YES | Foreign key to ai_providers |
| default_model | VARCHAR(100) | YES | Default model (e.g., gpt-4) |
| max_tokens | INT | NO | Maximum tokens (default: 2048) |
| temperature | FLOAT | NO | Temperature (default: 0.7) |
| updated_at | DATETIME | YES | Last update timestamp |
**Indexes:**
- PRIMARY KEY (user_id)
**Foreign Keys:**
- user_id → users(id) ON DELETE CASCADE
- default_provider_id → ai_providers(id) ON DELETE SET NULL
---
#### 14. ai_chats
AI conversation threads.
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| id | CHAR(36) | NO | Primary key (UUID) |
| user_id | CHAR(36) | NO | Foreign key to users |
| title | VARCHAR(255) | YES | Chat title |
| provider_id | CHAR(36) | YES | Foreign key to ai_providers |
| model_used | VARCHAR(100) | YES | Model snapshot |
| system_prompt | TEXT | YES | Custom system prompt |
| created_at | DATETIME | YES | Creation timestamp |
| updated_at | DATETIME | YES | Last update timestamp |
**Indexes:**
- PRIMARY KEY (id)
- KEY (user_id)
- KEY (updated_at)
**Foreign Keys:**
- user_id → users(id) ON DELETE CASCADE
- provider_id → ai_providers(id) ON DELETE SET NULL
---
#### 15. ai_messages
Individual messages in AI chats.
| Column | Type | Nullable | Description |
|--------|------|----------|-------------|
| id | CHAR(36) | NO | Primary key (UUID) |
| chat_id | CHAR(36) | NO | Foreign key to ai_chats |
| role | ENUM | NO | user, assistant, system |
| content | TEXT | NO | Message content |
| tokens_used | INT | YES | Token count for billing |
| created_at | DATETIME | YES | Creation timestamp |
**Indexes:**
- PRIMARY KEY (id)
- KEY (chat_id)
**Foreign Keys:**
- chat_id → ai_chats(id) ON DELETE CASCADE
---
## Entity Relationship Diagram (ERD)
```
┌─────────────────┐
│ users │
├─────────────────┤
│ id (PK) │◄────────┐
│ email │ │
│ password_hash │ │
│ name │ │
│ settings │ │
│ created_at │ │
│ updated_at │ │
└─────────────────┘ │
┌───────────────────┼───────────────────┐
│ │ │
│ │ │
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ categories │ │ projects │ │ activity_logs │
├───────────────┤ ├───────────────┤ ├───────────────┤
│ id (PK) │ │ id (PK) │ │ id (PK) │
│ user_id (FK) │ │ user_id (FK) │ │ user_id (FK) │
│ name │ │ name │ │ action │
│ color │ │ description │ │ entity_type │
│ favorite │ │ color │ │ entity_id │
│ created_at │ │ created_at │ │ details │
└───────────────┘ └───────────────┘ │ ip_address │
│ │ │ user_agent │
│ │ │ created_at │
│ │ └───────────────┘
│ │
│ │
│ │
┌───────────────┐ ┌───────────────┐
│ todos │ │recurring_tasks│
├───────────────┤ ├───────────────┤
│ id (PK) │ │ id (PK) │
│ user_id (FK) │ │ user_id (FK) │
│ title │ │ title │
│ description │ │ description │
│ status │ │ schedule │
│ due_date │ │ custom_days │
│ due_time │ │ favorite │
│ project_id(FK)│ │ created_at │
│ created_at │ │ updated_at │
│ updated_at │ └───────────────┘
└───────────────┘ │
│ │
│ │
│ │
┌──────────────────┐ │
│ todo_categories │◄───────┘
├──────────────────┤
│ todo_id (PK,FK) │
│ category_id(PK,FK)│
└──────────────────┘
┌──────────────────────────┐
│recurring_task_categories │
├──────────────────────────┤
│ recurring_task_id (PK,FK) │
│ category_id (PK,FK) │
└──────────────────────────┘
┌─────────────────┐
│marketplace_themes│
├─────────────────┤
│ id (PK) │◄────────┐
│ name │ │
│ display_name │ │
│ description │ │
│ download_url │ │
│ price │ │
│ is_published │ │
└─────────────────┘ │
┌─────────┴─────────┐
│ user_themes │
├──────────────────┤
│ id (PK) │
│ user_id (FK) │
│ theme_id (FK) │
│ active │
│ custom_settings │
└──────────────────┘
┌─────────────┐
│ai_providers │
├─────────────┤
│ id (PK) │◄────────┐
│ name │ │
│ display_name│ │
│ base_url │ │
│ is_builtin │ │
└─────────────┘ │
┌───────────────┼──────────────┐
│ │ │
┌────────────────┐ ┌──────────────┐ ┌─────────────────┐
│ user_api_keys │ │user_ai_settin│ │ ai_chats │
├────────────────┤ ├──────────────┤ ├─────────────────┤
│ id (PK) │ │user_id (PK) │ │ id (PK) │
│ user_id (FK) │ │default_prv(FK)│ │ user_id (FK) │
│ provider_id(FK) │ │default_model │ │ provider_id(FK) │
│ api_key_enc │ │max_tokens │ │ title │
│ label │ │temperature │ │ model_used │
│ is_active │ │updated_at │ │ system_prompt │
│ last_used_at │ └──────────────┘ │ created_at │
└────────────────┘ │ updated_at │
└─────────────────┘
┌────────────────┐
│ ai_messages │
├────────────────┤
│ id (PK) │
│ chat_id (FK) │
│ role │
│ content │
│ tokens_used │
│ created_at │
└────────────────┘
```
## Relationships Summary
| Entity | Relations |
|--------|-----------|
| **users** | Has many: todos, categories, projects, recurring_tasks, activity_logs, user_themes, user_api_keys, ai_chats, user_ai_settings |
| **todos** | Belongs to: user, project (optional). Many-to-many with categories via todo_categories |
| **recurring_tasks** | Belongs to: user. Many-to-many with categories via recurring_task_categories |
| **categories** | Linked to: todos, recurring_tasks |
| **marketplace_themes** | Installed by users via user_themes |
| **ai_providers** | Referenced by: user_api_keys, ai_chats, user_ai_settings |
| **ai_chats** | Belongs to: user, provider (optional). Has many: ai_messages |
| **ai_messages** | Belongs to: chat |
## Key Design Decisions
1. **UUID Primary Keys**: Using CHAR(36) for UUIDs to support distributed systems and prevent ID enumeration attacks.
2. **Foreign Key Cascades**:
- CASCADE DELETE for user-owned entities to clean up data when users are deleted
- SET NULL for optional references (e.g., project_id in todos)
3. **JSON Fields**: Used for flexible data like settings, custom_days, and metadata.
4. **Junction Tables**: Proper normalization for many-to-many relationships (todo-categories, recurring_task-categories).
5. **Activity Logging**: Nullable user_id allows for anonymous/system events.
6. **Theme Marketplace**: Separation of global theme catalog and user installations.
7. **AI Multi-Provider**: Support for multiple AI providers with per-user encrypted API keys.
## Migration and Seeding
To set up the database:
```bash
# Run all migrations
php spark migrate
# Run seeders
php spark db:seed AiProvidersSeeder
php spark db:seed MarketplaceThemesSeeder
php spark db:seed SampleDataSeeder
```
## Model Files
All tables have corresponding CodeIgniter 4 models in `app/Models/`:
- UserModel
- CategoryModel
- ProjectModel
- TodoModel
- TodoCategoryModel
- RecurringTaskModel
- RecurringTaskCategoryModel
- ActivityLogModel
- MarketplaceThemeModel
- UserThemeModel
- AiProviderModel
- UserApiKeyModel
- UserAiSettingsModel
- AiChatModel
- AiMessageModel
Each model includes:
- Validation rules
- Timestamp handling
- Custom query methods for common operations
- Relationship helpers