suhail
spoecs
9eafd9f
# 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.