Spaces:
Running
Running
File size: 8,242 Bytes
9eafd9f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
# Data Model: Full-Stack Integration & UI Experience
**Feature**: 002-fullstack-ui-integration
**Date**: 2026-01-09
**Status**: Reference Only (No New Entities)
## Overview
This feature does not introduce new data entities. It integrates and polishes existing functionality from Specs 1 (Task CRUD) and 2 (Authentication & API Security). This document references the existing data model for completeness.
## Existing Entities
### User (from Spec 2: Authentication & API Security)
**Purpose**: Represents an authenticated user with task management capabilities
**Attributes**:
- `id` (integer, primary key): Unique identifier for the user
- `email` (string, unique, required): User's email address for authentication
- `name` (string, required): User's display name
- `password_hash` (string, required): Bcrypt-hashed password (never exposed in API)
- `created_at` (datetime, auto): Timestamp of account creation
- `updated_at` (datetime, auto): Timestamp of last profile update
**Relationships**:
- One-to-Many with Task: A user can have multiple tasks
**Validation Rules**:
- Email must be valid RFC 5322 format
- Email must be unique across all users
- Password must be at least 8 characters with uppercase, lowercase, and number
- Name must be 1-100 characters
**Security**:
- Password is hashed with bcrypt (cost factor 12) before storage
- Password hash is never returned in API responses
- User ID is extracted from JWT token for all authenticated requests
**Database Table**: `users`
**Indexes**:
- Primary key on `id`
- Unique index on `email`
**Source**: `backend/src/models/user.py`
---
### Task (from Spec 1: Task CRUD)
**Purpose**: Represents a todo item belonging to a specific user
**Attributes**:
- `id` (integer, primary key): Unique identifier for the task
- `user_id` (integer, foreign key, required): Owner of the task (references User.id)
- `title` (string, required): Task title (max 200 characters)
- `description` (string, optional): Task description (max 1000 characters)
- `completed` (boolean, default false): Completion status
- `created_at` (datetime, auto): Timestamp of task creation
- `updated_at` (datetime, auto): Timestamp of last task update
**Relationships**:
- Many-to-One with User: Each task belongs to exactly one user
**Validation Rules**:
- Title is required and must be 1-200 characters
- Description is optional, max 1000 characters
- Completed defaults to false
- User ID must reference an existing user
**Business Rules**:
- Users can only access their own tasks (enforced by JWT authentication)
- Tasks are automatically filtered by authenticated user_id in all queries
- Deleting a user cascades to delete all their tasks
**Database Table**: `tasks`
**Indexes**:
- Primary key on `id`
- Index on `user_id` (for filtering by user)
- Index on `completed` (for filtering by status)
- Composite index on `(user_id, completed)` (for combined filtering)
- Index on `created_at` (for sorting)
**Source**: `backend/src/models/task.py`
---
### AuthSession (Frontend Only - from Spec 2)
**Purpose**: Client-side session state for authenticated users
**Attributes**:
- `token` (string, nullable): JWT token from backend
- `user` (object, nullable): User profile information
- `id` (integer): User ID
- `email` (string): User email
- `name` (string): User display name
**Storage**: Browser localStorage (key: `auth_session`)
**Lifecycle**:
- Created on successful signin (POST /api/auth/signin)
- Persisted across page refreshes
- Cleared on signout or 401 Unauthorized response
- Expires when JWT token expires (7 days)
**Security**:
- Token is included in Authorization header for all API requests
- Session is cleared on any authentication error
- No sensitive data stored (password never stored client-side)
**Source**: `frontend/src/lib/auth.ts`
---
## Entity Relationships
```
User (1) ----< (Many) Task
|
| JWT Token (stateless)
|
v
AuthSession (Frontend)
```
**Relationship Details**:
1. **User → Task** (One-to-Many):
- A user can have zero or more tasks
- Each task belongs to exactly one user
- Foreign key: `Task.user_id` references `User.id`
- Cascade delete: Deleting a user deletes all their tasks
2. **User → AuthSession** (Stateless):
- JWT token contains user_id and email
- No server-side session storage
- Frontend stores token and user profile in localStorage
- Token is verified on every API request
## Data Flow
### Authentication Flow
```
1. User signs up/signs in
↓
2. Backend creates JWT token with user_id
↓
3. Frontend stores token + user profile in AuthSession
↓
4. Frontend includes token in Authorization header
↓
5. Backend verifies token and extracts user_id
↓
6. Backend filters all queries by user_id
```
### Task Management Flow
```
1. User creates/updates/deletes task
↓
2. Frontend sends request with JWT token
↓
3. Backend verifies token → extracts user_id
↓
4. Backend performs operation (filtered by user_id)
↓
5. Backend returns result
↓
6. Frontend updates UI (optimistic or after response)
```
## Data Isolation
**Critical Security Requirement**: All task queries MUST be filtered by authenticated user_id
**Implementation**:
- JWT token contains user_id in 'sub' claim
- `get_current_user()` dependency extracts user_id from token
- All task endpoints use `current_user_id = Depends(get_current_user)`
- SQLModel queries include `.where(Task.user_id == current_user_id)`
**Verification**:
- User A cannot access User B's tasks
- API returns 404 (not 403) for unauthorized task access
- No data leakage through error messages
## State Transitions
### Task State Transitions
```
[New Task]
↓
[Active] ←→ [Completed]
↓
[Deleted]
```
**Transitions**:
- New → Active: Task created with `completed=false`
- Active → Completed: User marks task as done (`completed=true`)
- Completed → Active: User marks task as not done (`completed=false`)
- Any → Deleted: User deletes task (hard delete from database)
**No Soft Deletes**: Tasks are permanently deleted (no `deleted_at` field)
### User State Transitions
```
[New User]
↓
[Active]
↓
[Deleted] (future - not implemented)
```
**Current Implementation**:
- New → Active: User signs up successfully
- No user deletion implemented yet (out of scope)
## Schema Migrations
**Existing Migrations**:
1. `001_initial.py`: Created users and tasks tables (Spec 1)
2. `002_add_user_password.py`: Added password_hash to users table (Spec 2)
**No New Migrations Required**: This feature does not modify the database schema
## Data Validation
### Backend Validation (Pydantic Schemas)
**User Validation** (`backend/src/schemas/auth.py`):
- Email: RFC 5322 format validation
- Password: Min 8 chars, uppercase, lowercase, number
- Name: 1-100 characters
**Task Validation** (`backend/src/schemas/task.py`):
- Title: Required, 1-200 characters
- Description: Optional, max 1000 characters
- Completed: Boolean (defaults to false)
### Frontend Validation
**Client-Side Validation**:
- Email format validation (regex)
- Password strength validation (min 8 chars, complexity)
- Form field required/optional indicators
- Inline error messages
**Note**: Backend validation is authoritative - frontend validation is for UX only
## Performance Considerations
**Indexes** (already implemented):
- `users.email` (unique): Fast user lookup during signin
- `tasks.user_id`: Fast filtering of user's tasks
- `tasks.completed`: Fast filtering by completion status
- `tasks.(user_id, completed)`: Fast combined filtering
- `tasks.created_at`: Fast sorting by creation date
**Query Patterns**:
- Most common: Get all tasks for user (filtered by user_id)
- Second most common: Get active/completed tasks for user
- Sorting: By created_at or updated_at
**No N+1 Queries**: All queries are direct (no nested loops)
## Summary
This feature reuses the existing data model from Specs 1 and 2:
- **User**: Authentication and ownership
- **Task**: Todo items with user isolation
- **AuthSession**: Frontend session state
No new entities, relationships, or migrations are required. The focus is on UI integration and polish rather than data model changes.
|