-
Notifications
You must be signed in to change notification settings - Fork 0
Data Model
Source of truth: apps/server/prisma/schema.prisma. This page summarizes
it β if the two ever disagree, the schema file wins and this page is
stale (please open an issue).
User βββ¬ββ created ββ> Project βββ¬ββ has many ββ> Task βββ¬ββ has many ββ> Todo (optional taskId)
β β β
β βββ has many ββ> Todo βββ has many ββ> Comment
β β (project-level, βββ has many ββ> FileAsset
β β taskId: null) β
β βββ has many ββ> Comment β
β βββ has many ββ> FileAsset β
β βββ has many ββ> Activity β
β β
βββ acts as actor/author/uploader on ββ> Task, Todo, Comment, FileAsset, Activity
Comment attaches to exactly one of Project, Task, or Todo (a
hand-added Postgres CHECK constraint enforces this β see
Architecture). Todo attaches to a Project always, and
optionally to a Task (see FAQ for the project-level vs
task-scoped distinction).
No auth β created the first time a name is seen in the X-User-Name
header. name is unique.
| Field | Type | Notes |
|---|---|---|
id |
String (cuid) |
|
name |
String |
unique |
createdAt |
DateTime |
The top-level container. Soft-deleted.
| Field | Type | Notes |
|---|---|---|
id, name, description?
|
||
color |
String |
hex, defaults to the app accent #6E5AF0
|
createdById |
String |
FK β User |
createdAt, updatedAt, deletedAt?
|
Belongs to exactly one Project. Soft-deleted.
| Field | Type | Notes |
|---|---|---|
id, title, description?
|
||
status |
enum | TODO | IN_PROGRESS | IN_REVIEW | DONE |
priority |
enum | LOW | MEDIUM | HIGH | URGENT |
dueDate? |
DateTime |
|
projectId |
String |
FK β Project, onDelete: Cascade
|
createdById |
String |
FK β User |
createdAt, updatedAt, deletedAt?
|
Belongs to a Project always, and optionally to a Task. Hard-deleted
(no deletedAt β see Architecture for why that matters
for Activity logging).
| Field | Type | Notes |
|---|---|---|
id, title
|
||
isDone |
Boolean |
default false
|
position |
Int |
manual sort order within its list (project-level or task-level) |
projectId |
String |
FK β Project, onDelete: Cascade
|
taskId? |
String |
FK β Task, onDelete: Cascade. null = project-level todo |
createdById |
String |
FK β User |
createdAt, updatedAt
|
As of Phase 8, the UI only creates/lists todos with taskId: null
(project-level). The schema, repository, and service all support
task-scoped todos already β it's a UI scope decision, not a data-model
gap. See handoffs/PHASE_8_HANDOFF.md.
Attaches to exactly one of Project/Task/Todo. Hard-deleted.
| Field | Type | Notes |
|---|---|---|
id, content
|
||
authorId |
String |
FK β User |
projectId?, taskId?, todoId?
|
String |
exactly one is non-null (CHECK constraint) |
createdAt, updatedAt
|
Not yet built β this is Phase 9.
Metadata row for an uploaded file. storageKey is an opaque key from
StorageProvider.save(), never a raw filesystem path β this is what
makes swapping to S3/MinIO later a new StorageProvider implementation,
not a schema change.
| Field | Type | Notes |
|---|---|---|
id, originalName, mimeType
|
||
sizeBytes |
Int |
|
storageKey |
String |
unique, opaque |
projectId |
String |
FK β Project, onDelete: Cascade
|
taskId? |
String |
FK β Task, onDelete: Cascade
|
uploadedById |
String |
FK β User |
createdAt |
Not yet built β this is Phase 10.
Append-only audit/feed log β never updated or deleted by user action, only inserted by services.
| Field | Type | Notes |
|---|---|---|
id, type
|
see ActivityType enum below |
|
projectId |
String |
FK β Project, onDelete: Cascade
|
actorId |
String |
FK β User |
taskId?, todoId?, commentId?, fileId?
|
String |
all onDelete: SetNull, not Cascade |
metadata? |
Json |
snapshot data (e.g. a deleted task's title) so the feed still renders a label after the row is gone |
createdAt |
ActivityType values, and which have shipped so far:
| Entity | Created | Updated | Completed/Reopened | Deleted |
|---|---|---|---|---|
| Project | β | β | β | β |
| Task | β | β | β | β |
| Todo | β | β (no such type, by design) | β / β | β |
| Comment | not built yet | β | β | not built yet |
| File | not built yet | β | β | not built yet |
Todo deliberately has no generic "updated" type β a title-only edit or a
reorder records nothing; only create, delete, and an actual
done/not-done flip do. See Architecture's note on
hard-delete ordering and handoffs/PHASE_8_HANDOFF.md Β§5.3.
Migration SQL lives in apps/server/prisma/migrations/. As of Phase 8,
every table above already existed from the single Phase 2 migration β no
schema changes have been needed since. See
Development Workflow for the sandbox limitation
around prisma generate/migrate dev.
SyncRoot Β· pre-1.0, phase-by-phase development Β· see SECURITY.md before deploying anywhere public
Using SyncRoot
How it's built
Project status
Working on SyncRoot