MOTIR-433Done
6.14.3 Schema — the epic-privacy flag on `work_item` (epic-kind) + migration
Estimate: 30m · Depends on: 6.14.2
Implement the epic-privacy flag on work_item per 6.14.2 — the data model the whole story rides, in ONE migration.
- Schema: add the flag chosen by 6.14.2 — a
publicChildrenHidden: Boolean @default(false)column (or the epicvisibilityenum, per the ADR) onwork_item, with a migration. Existing rows backfill to the non-private default (no behaviour change on deploy). Add the supporting index the exclusion predicate needs (so the descended-from-private-epic check stays an indexablewhere, finding #57). The flag is meaningful only for epic-kind items — enforce that at the write layer (6.14.7) rather than with a DB constraint unless a cheap CHECK fits; document the choice. - No enforcement / no UI here: this card is the column + migration + the regenerated Prisma types only; the server-side exclusion (6.14.4), the placeholders (6.14.5/6.14.6), and the admin set/unset (6.14.7) land in their own cards. (If the descendant walk needs a stored ancestor/path helper not already present, note it for 6.14.4 rather than building enforcement here.)
Stay 4-layer: the column lives in prisma/schema.prisma; any FK stays a Prisma @relation (CLAUDE.md migration rule — no raw-SQL-only FK).
Acceptance criteria
- The migration adds the epic-privacy flag (per 6.14.2) to
work_itemwith its default + the supporting index;prisma migrate devreports no drift; existing rows backfill to the non-private default (no behaviour change). prisma generatetypes the new field; a vitest (real Postgres) asserts the column defaults to non-private and round-trips on an epic-kind item.- 4-layer respected (the field in the schema; reads/writes added in later cards); any FK modelled as
@relation.
Context refs
- 6.14.2 — the model decision this implements (the flag shape + the index the predicate needs).
motir-core/prisma/schema.prisma— thework_itemmodel the flag is added to.motir-core/CLAUDE.md§ 4-layer + § migration FK-as-@relationrule.