mirror of
https://github.com/JGH0/Todo-App-Backend.git
synced 2026-06-03 13:28:47 +02:00
added migration seeders models and test script
This commit is contained in:
548
DATABASE_DOCUMENTATION.md
Normal file
548
DATABASE_DOCUMENTATION.md
Normal file
@@ -0,0 +1,548 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user