Юрий Белк – Full stack Developer (страница 35)
Практический нюанс:
– owner можно хранить и в workspaces.owner_user_id, и как запись membership с ролью owner.
Это полезно: membership даёт единый механизм прав, а поле owner – быстрый доступ и “один владелец”.
Тогда важно синхронизировать (обычно в коде + ограничениями).
9.4.4. projects
– id
– workspace_id (FK → workspaces.id)
– name
– description (nullable)
– status (active/archived)
– created_at, updated_at
– deleted_at (если soft delete проектов)
Индексы:
– (workspace_id, status) – список проектов по workspace
– возможно (workspace_id, name) если хотите искать по имени
Constraints:
– CHECK (status IN ('active','archived'))
9.4.5. tasks
– id
– workspace_id (FK → workspaces.id) – можно держать для ускорения фильтров
– project_id (FK → projects.id)
– title (not null)
– description (nullable)
– status (todo/in_progress/done/canceled)
– priority (low/medium/high, nullable)
– assignee_user_id (nullable, FK → users.id)
– reporter_user_id (not null, FK → users.id)
– due_date (nullable, date or timestamptz – зависит от требований)
– created_at, updated_at
– deleted_at (nullable; soft delete задач часто полезен)
Индексы (важное):
– (project_id, created_at desc, id desc) – для списков задач в проекте
– (workspace_id, status, created_at desc) – для фильтра по статусу
– (workspace_id, assignee_user_id, status) – “мои задачи”
– индекс на deleted_at не нужен, но частичный индекс полезен (см. ниже)
Partial index (практика):
– индекс только по “живым” задачам:
например индекс по (project_id, created_at desc) WHERE deleted_at IS NULL.
Это часто сильно помогает, потому что приложение почти всегда работает с живыми задачами.
Constraints:
– CHECK на статус и priority
– CHECK (title <> '')
Нюанс консистентности:
– если tasks.workspace_id хранится отдельно от projects.workspace_id, вы должны гарантировать, что они совпадают.
В простом варианте – правило в коде (при создании задачи берем workspace_id из проекта).
В строгом варианте – триггер или сложный constraint (в Postgres это решаемо, но для учебной книги можно оставить на уровне кода + тестов).
9.4.6. comments
– id
– task_id (FK → tasks.id)
– author_user_id (FK → users.id)
– body (not null)
– created_at, updated_at
– deleted_at (nullable)
Индексы:
– (task_id, created_at, id) – список комментариев к задаче
Constraints:
– CHECK (body <> '')
9.4.7. labels
– id
– workspace_id (FK → workspaces.id)
– name (not null)
– color (nullable)
– created_at, updated_at
– deleted_at (nullable)
Индексы: