Todo Domain Expert
Act as a domain expert for Todo applications, providing authoritative guidance on entity structure, business rules, and validation logic.
Core Principles
- Stateless Server Mindset - All state lives in the database; server processes are ephemeral
- Database as Source of Truth - Never cache or trust in-memory state for business decisions
- Multi-User Awareness - All operations must consider concurrent access and user isolation
Todo Entity Structure
Todo {
id: UUID (primary key, immutable)
title: string (required, 1-255 chars, trimmed)
description: string | null (optional, max 2000 chars)
status: enum ['pending', 'completed', 'archived']
priority: enum ['low', 'medium', 'high'] | null
due_date: datetime | null
created_at: datetime (immutable, server-generated)
updated_at: datetime (server-managed)
completed_at: datetime | null (set when status → completed)
user_id: UUID (foreign key, immutable after creation)
}
CRUD Operations
Create
- Generate
id server-side (never accept from client)
- Set
created_at and updated_at to current timestamp
- Default
status to 'pending' if not provided
- Validate
user_id exists and matches authenticated user
- Trim and validate
title length
Read
- Always filter by
user_id (users see only their todos)
- Support filtering by
status, priority, due_date range
- Order by
created_at DESC by default
- Paginate results (default 20, max 100 per page)
Update
- Verify ownership (
user_id matches authenticated user)
- Reject updates to immutable fields:
id, created_at, user_id
- Auto-update
updated_at on any change
- Use optimistic locking via
updated_at to prevent lost updates
Delete
- Verify ownership before deletion
- Consider soft-delete (set
status to 'archived') vs hard-delete
- Hard-delete should be admin-only or after retention period
State Transitions
Valid transitions:
pending → completed (sets completed_at)
pending → archived
completed → pending (clears completed_at)
completed → archived
archived → pending (clears completed_at)
Invalid transitions:
archived → completed (must go through pending first)
Transition Rules
completed_at is set ONLY when transitioning TO 'completed'
completed_at is cleared when leaving 'completed' status
- Archived todos are hidden from default views but retrievable
Validation Rules
Title
- Required, non-empty after trimming
- Min 1 character, max 255 characters
- No leading/trailing whitespace (auto-trim)
- Reject if only whitespace
Description
- Optional (null allowed)
- Max 2000 characters
- Preserve internal whitespace, trim ends
Due Date
- Must be valid ISO 8601 datetime if provided
- Can be in the past (for historical records)
- Store as UTC, handle timezone conversion at API boundary
Priority
- Optional, defaults to null (no priority)
- Must be one of: 'low', 'medium', 'high'
Edge Cases
Duplicates
- Allow duplicate titles (same user can have multiple todos with same title)
- Use
id as unique identifier, not title
- Consider optional duplicate warning in UI, not server enforcement
Invalid Updates
- Reject partial updates that would violate constraints
- Return 400 with specific validation errors
- Never silently ignore invalid fields
Concurrent Modifications
- Use optimistic locking: include
updated_at in update WHERE clause
- Return 409 Conflict if
updated_at doesn't match
- Client must refresh and retry
Bulk Operations
- Validate each item individually
- Use transactions for atomicity
- Return partial success details (which items failed and why)
Empty States
- Handle user with no todos gracefully
- Return empty array, not null or error
API Response Patterns
Success
{
"data": { /* todo object or array */ },
"meta": { "total": 42, "page": 1, "per_page": 20 }
}
Validation Error
{
"error": "validation_failed",
"details": [
{ "field": "title", "message": "Title is required" }
]
}
Conflict Error
{
"error": "conflict",
"message": "Todo was modified by another request",
"current_updated_at": "2024-01-15T10:30:00Z"
}
Resources
For detailed validation rules and implementation patterns, see:
- references/domain-rules.md - Extended validation logic, security considerations, and business rules
1---2name: todo-domain-expert3description: Domain expert for Todo applications providing entity structure definitions, CRUD operation rules, task state management (pending, completed, archived), and edge case validations. Use when designing, implementing, or reviewing Todo app features, validating Todo data models, handling task state transitions, or enforcing business rules for task management systems.4---56# Todo Domain Expert78Act as a domain expert for Todo applications, providing authoritative guidance on entity structure, business rules, and validation logic.910## Core Principles11121. **Stateless Server Mindset** - All state lives in the database; server processes are ephemeral132. **Database as Source of Truth** - Never cache or trust in-memory state for business decisions143. **Multi-User Awareness** - All operations must consider concurrent access and user isolation1516## Todo Entity Structure1718```19Todo {20 id: UUID (primary key, immutable)21 title: string (required, 1-255 chars, trimmed)22 description: string | null (optional, max 2000 chars)23 status: enum ['pending', 'completed', 'archived']24 priority: enum ['low', 'medium', 'high'] | null25 due_date: datetime | null26 created_at: datetime (immutable, server-generated)27 updated_at: datetime (server-managed)28 completed_at: datetime | null (set when status → completed)29 user_id: UUID (foreign key, immutable after creation)30}31```3233## CRUD Operations3435### Create36- Generate `id` server-side (never accept from client)37- Set `created_at` and `updated_at` to current timestamp38- Default `status` to 'pending' if not provided39- Validate `user_id` exists and matches authenticated user40- Trim and validate `title` length4142### Read43- Always filter by `user_id` (users see only their todos)44- Support filtering by `status`, `priority`, `due_date` range45- Order by `created_at DESC` by default46- Paginate results (default 20, max 100 per page)4748### Update49- Verify ownership (`user_id` matches authenticated user)50- Reject updates to immutable fields: `id`, `created_at`, `user_id`51- Auto-update `updated_at` on any change52- Use optimistic locking via `updated_at` to prevent lost updates5354### Delete55- Verify ownership before deletion56- Consider soft-delete (set `status` to 'archived') vs hard-delete57- Hard-delete should be admin-only or after retention period5859## State Transitions6061```62Valid transitions:63 pending → completed (sets completed_at)64 pending → archived65 completed → pending (clears completed_at)66 completed → archived67 archived → pending (clears completed_at)6869Invalid transitions:70 archived → completed (must go through pending first)71```7273### Transition Rules74- `completed_at` is set ONLY when transitioning TO 'completed'75- `completed_at` is cleared when leaving 'completed' status76- Archived todos are hidden from default views but retrievable7778## Validation Rules7980### Title81- Required, non-empty after trimming82- Min 1 character, max 255 characters83- No leading/trailing whitespace (auto-trim)84- Reject if only whitespace8586### Description87- Optional (null allowed)88- Max 2000 characters89- Preserve internal whitespace, trim ends9091### Due Date92- Must be valid ISO 8601 datetime if provided93- Can be in the past (for historical records)94- Store as UTC, handle timezone conversion at API boundary9596### Priority97- Optional, defaults to null (no priority)98- Must be one of: 'low', 'medium', 'high'99100## Edge Cases101102### Duplicates103- Allow duplicate titles (same user can have multiple todos with same title)104- Use `id` as unique identifier, not title105- Consider optional duplicate warning in UI, not server enforcement106107### Invalid Updates108- Reject partial updates that would violate constraints109- Return 400 with specific validation errors110- Never silently ignore invalid fields111112### Concurrent Modifications113- Use optimistic locking: include `updated_at` in update WHERE clause114- Return 409 Conflict if `updated_at` doesn't match115- Client must refresh and retry116117### Bulk Operations118- Validate each item individually119- Use transactions for atomicity120- Return partial success details (which items failed and why)121122### Empty States123- Handle user with no todos gracefully124- Return empty array, not null or error125126## API Response Patterns127128### Success129```json130{131 "data": { /* todo object or array */ },132 "meta": { "total": 42, "page": 1, "per_page": 20 }133}134```135136### Validation Error137```json138{139 "error": "validation_failed",140 "details": [141 { "field": "title", "message": "Title is required" }142 ]143}144```145146### Conflict Error147```json148{149 "error": "conflict",150 "message": "Todo was modified by another request",151 "current_updated_at": "2024-01-15T10:30:00Z"152}153```154155## Resources156157For detailed validation rules and implementation patterns, see:158- [references/domain-rules.md](references/domain-rules.md) - Extended validation logic, security considerations, and business rules