3.7.2 Schema — default-board flag + switcher ordering (N boards per project; migration-aware)
Estimate: 16m · Depends on: 3.1.1
Make the board table first-class multi-per-project. The per-project index is already non-unique (3.1.1), so add: a board.isDefault Boolean @default(false) (exactly one default per project — enforced in the service + a partial unique index (projectId) WHERE is_default), and a board.position (fractional-index string) for stable switcher ordering. ONE migration; the existing auto-seeded board per project backfills to isDefault = true + an initial position, so no project is left without a default. No RLS change (the board table is already workspace-RLS-forced from 3.1.1).
Out of scope: the CRUD service/routes (3.7.3); UI (3.7.4); the read wiring (3.7.5).
Acceptance criteria
board.isDefault @default(false)+board.positionadded in ONE migration; a partial unique index guarantees ≤1 default per project;migrate devapplies cleanly + idempotently.- Existing boards backfill to
isDefault = true+ an initial position (every project keeps exactly one default);prisma generatetypes the fields. - A vitest (real Postgres) asserts the one-default invariant (a second
isDefault=truefor the same project is rejected) and the backfill.
Context refs
prisma/schema.prismaBoard(3.1.1 — the non-unique@@index([projectId])+ RLS) ; the fractional-indexpositionconvention used onwork_item/board_columnmotir-core/CLAUDE.md— one migration, application-seeded data, partial indexes