Domain Model & Data Schema
The domain follows the Product Brief’s definitions (§5.1) exactly; the tables below are the Drizzle definitions in src/db/schema.ts.
Entities
Section titled “Entities”- User — a registered person, identified by email and name (
users). - List — a container for Tasks, owned by exactly one User; can be shared with Members and placed in at most one Group (
lists). - Task — an entry in a List with a title and attributes (done, starred, due date, notes, assignee); can be assigned to one Member of its List (
tasks). - Step — a child of a Task with only a title and done state; cannot be starred, assigned, shared, dated, or nested (
steps). - Group — a container that organizes related Lists; cannot nest (
groups). - View — a system-defined, read-only collection of Tasks (“My Day”, “Important”, “Planned”, “Assigned to me”, “Tasks”); aggregates across owned and member Lists and respects the authorization boundary.
- Member — a User a List has been shared with (
listMembers); a Member is always a User.
Key domain rules
Section titled “Key domain rules”- A List is owned by exactly one User; only the owner changes memberships; deleting a List permanently deletes its Tasks and Steps (Product Brief §5.2).
- A Task belongs to one List; deleting a Task deletes its Steps; a Task may be assigned to exactly one Member (assigning to the owner is allowed; removing the assignee clears the assignment).
- Steps have only title + done; no nesting.
- A Group holds zero or more Lists and cannot nest; deleting a Group ungroups its Lists rather than deleting them.
- Ordering is custom per scope: per-List for Tasks, per-Task for Steps, per-User for Lists and Groups; sorting is a temporary view, drag-and-drop sets the persisted order.
- The server is the single source of truth; concurrent edits to the same field reconcile last-write-wins at the field level (Product Brief §5.2–§5.3).
Data schema (D1, Drizzle)
Section titled “Data schema (D1, Drizzle)”The tables defined in src/db/schema.ts:
| Table | Represents | Notable columns / relationships |
|---|---|---|
users | Registered users | identity (email, name) |
lists | Lists | ownerId, optional groupId, per-owner rank |
groups | Groups of Lists | rank; Lists reference via groupId |
tasks | Tasks | listId, title, done, starred, dueDate, notes, assigneeId, rank |
steps | Steps | taskId, title, done, rank |
myDayEntries | ”My Day” view membership | per-user daily-focus entries (reset each local day) |
listMembers | List sharing | (listId, userId); per-viewer order/group for shared Lists |
idempotencyKeys | Replay dedup | stable key per queued mutation for safe outbox replay |
Per-member List placement (per-viewer order + group on
listMembers) and assignment (assigneeId) come from list-sharing and task-assignment (spec 011, spec 012). Therankcolumns implement the fractional ordering described in the Fractional Rank Algorithm module guide.