Root cause of the mismatch: Deliverable.status is a denormalised
column that was only written at create-time (default NOT_STARTED)
and never refreshed when stages moved. The Projects board read it
live and showed "Not Started" while the pipeline ring + dominant-
stage view correctly showed "at Client Feedback (6/11 stages
complete)".
Fix in two parts:
1. New deliverable-status-service with:
- computeDeliverableStatus(stageStatuses[]) — pure function with
the summary rule:
all stages terminal → APPROVED
any IN_REVIEW → IN_REVIEW
any IN_PROGRESS/CHANGES_REQUESTED → IN_PROGRESS
else → NOT_STARTED
ON_HOLD is producer-managed and never overwritten.
- recomputeDeliverableStatus(deliverableId, txClient?) —
executes the rule + writes if different. Accepts an optional
Prisma tx client so callers can run inside their own
transaction.
2. Wired into every stage-write path:
- stage-service.updateStageStatus (single-stage transitions)
- stage-service bulk transaction (bulkUpdateStages) — dedups
touched deliverable IDs so we don't recompute twice.
- stage-transition-service forward + rework (board drag) —
inline inside the same $transaction so the board bucket is
correct on the next refetch.
3. Backfill script scripts/recompute-deliverable-statuses.ts —
one-off sweep to fix existing stale rows:
npx tsx scripts/recompute-deliverable-statuses.ts
Run once after deploy.
|
||
|---|---|---|
| .. | ||
| app | ||
| components | ||
| hooks | ||
| lib | ||
| stores | ||
| types | ||
| instrumentation.ts | ||
| middleware.ts | ||