feat(board): daily board linked to shots
A /board page that replaces the shared doc used as the day-to-day tracker. One card per active/on-hold project with a status line, dated milestones and to-do lines typed or pasted in the doc's own format: DH2_VFX_027_090 finalise (CHRIS) DH2_VFX_005_010 gfx update @michelle wait: client GFX ADH_GFX_005_020 Shot codes link to the shot (live status + latest version), (NAME)/@name assigns, wait: marks a blocker, headings group lines. Codes that match no shot are flagged, with a relink when there is an obvious near miss. Board lines are their own model, not Tasks: tasks drive shot status and notifications, and a note like "finalise" must not touch either. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
-- Daily board: the day-to-day tracker that used to live in a shared doc,
|
||||
-- now linked to shots. Board items are notes, not tasks, so nothing here
|
||||
-- feeds shot status.
|
||||
ALTER TABLE "projects" ADD COLUMN "boardStatus" TEXT;
|
||||
ALTER TABLE "projects" ADD COLUMN "boardStatusAt" TIMESTAMP(3);
|
||||
|
||||
CREATE TABLE "board_items" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"shotId" TEXT,
|
||||
"code" TEXT,
|
||||
"text" TEXT NOT NULL,
|
||||
"group" TEXT NOT NULL DEFAULT '',
|
||||
"assigneeId" TEXT,
|
||||
"waitingOn" TEXT,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
"doneAt" TIMESTAMP(3),
|
||||
"doneById" TEXT,
|
||||
"createdById" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "board_items_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "project_milestones" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"label" TEXT NOT NULL,
|
||||
"date" TIMESTAMP(3) NOT NULL,
|
||||
"doneAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "project_milestones_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE INDEX "board_items_projectId_doneAt_idx" ON "board_items"("projectId", "doneAt");
|
||||
CREATE INDEX "board_items_shotId_idx" ON "board_items"("shotId");
|
||||
CREATE INDEX "project_milestones_projectId_date_idx" ON "project_milestones"("projectId", "date");
|
||||
|
||||
ALTER TABLE "board_items" ADD CONSTRAINT "board_items_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "board_items" ADD CONSTRAINT "board_items_shotId_fkey" FOREIGN KEY ("shotId") REFERENCES "shots"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE "board_items" ADD CONSTRAINT "board_items_assigneeId_fkey" FOREIGN KEY ("assigneeId") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE "project_milestones" ADD CONSTRAINT "project_milestones_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -262,6 +262,7 @@ model User {
|
||||
createdShootDays ShootDay[] @relation("ShootDayCreator")
|
||||
createdTakes Take[] @relation("TakeCreator")
|
||||
uploadedTakeAttachments TakeAttachment[] @relation("TakeAttachmentUploader")
|
||||
assignedBoardItems BoardItem[] @relation("BoardItemAssignee")
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
@@ -382,6 +383,14 @@ model Project {
|
||||
deliveryPackages DeliveryPackage[]
|
||||
deliveryRequests DeliveryRequest[]
|
||||
|
||||
/// The one-line "where are we" on the daily board ("Official bid sent",
|
||||
/// "Awaiting feedback on pick-ups"). Free text on purpose: it is what the
|
||||
/// producer would have typed at the top of the project's section in the doc.
|
||||
boardStatus String? @db.Text
|
||||
boardStatusAt DateTime?
|
||||
boardItems BoardItem[]
|
||||
milestones ProjectMilestone[]
|
||||
|
||||
@@map("projects")
|
||||
}
|
||||
|
||||
@@ -487,6 +496,7 @@ model Shot {
|
||||
loggedTakes Take[] @relation("TakeToShot")
|
||||
exports Export[]
|
||||
deliveryRequestLines DeliveryRequestLine[]
|
||||
boardItems BoardItem[]
|
||||
|
||||
@@unique([projectId, shotCode])
|
||||
@@map("shots")
|
||||
@@ -1255,6 +1265,57 @@ model DeliveryRequestLine {
|
||||
@@map("delivery_request_lines")
|
||||
}
|
||||
|
||||
/// A line on the daily board — the day-to-day to-do the team used to keep in
|
||||
/// a shared doc ("DH2_VFX_027_090 finalise (CHRIS)"). Deliberately not a Task:
|
||||
/// tasks are the pipeline's one-per-shot work items whose state drives shot
|
||||
/// status, and a note like "finalise" or "awaiting gfx" must not move a shot
|
||||
/// back to IN_PROGRESS or notify anyone.
|
||||
///
|
||||
/// `code` is the shot code as typed. When it matches a shot, `shotId` links it
|
||||
/// and the board shows the shot's live status; when it does not, the line is a
|
||||
/// flag ("not on our tracker?") until the shot exists or the code is fixed.
|
||||
model BoardItem {
|
||||
id String @id @default(cuid())
|
||||
projectId String
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
shotId String?
|
||||
shot Shot? @relation(fields: [shotId], references: [id], onDelete: SetNull)
|
||||
code String?
|
||||
text String @db.Text
|
||||
/// Heading the line sits under on the board ("WATER DROPS"); "" = none
|
||||
group String @default("")
|
||||
assigneeId String?
|
||||
assignee User? @relation("BoardItemAssignee", fields: [assigneeId], references: [id], onDelete: SetNull)
|
||||
/// What the line is blocked on ("client GFX ADH_GFX_013_010"); null = not blocked
|
||||
waitingOn String?
|
||||
sortOrder Int @default(0)
|
||||
doneAt DateTime?
|
||||
doneById String?
|
||||
createdById String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([projectId, doneAt])
|
||||
@@index([shotId])
|
||||
@@map("board_items")
|
||||
}
|
||||
|
||||
/// A dated project milestone — batch deliveries, picture locks, shoot start,
|
||||
/// colour & mix review. Episode due dates stay in EpisodeDueDate because the
|
||||
/// shot-status board keys off them; these are the dates around the work.
|
||||
model ProjectMilestone {
|
||||
id String @id @default(cuid())
|
||||
projectId String
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
label String
|
||||
date DateTime
|
||||
doneAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([projectId, date])
|
||||
@@map("project_milestones")
|
||||
}
|
||||
|
||||
model SketchTemplate {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
|
||||
Reference in New Issue
Block a user