Replace FeedbackSeverity enum (Critical/Major/Minor/Suggestion) with a simple isActionItem boolean. Annotations default to action items (things the artist must fix). Any item can be toggled to an info callout (context that doesn't need action). Progress bar and carry-forward only count action items. Screenshot paste limited to 5MB with user notification. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
39 KiB
HP CG Production Tracker — Roadmap
Single source of truth for project status and remaining work. Previous planning documents (IMPLEMENTATION_PLAN.md, UPGRADE_PLAN.md) are archived in
docs/archive/.
Last updated: 2026-03-14 (Phase 2 complete)
Table of Contents
What's Built
Core Foundation (Phases 1–4)
| Feature | Status |
|---|---|
| Project scaffold (Next.js, TS, Tailwind, Prisma, Auth.js) | ✅ Complete |
| Design system (Oliver Agency palette, Montserrat + Inter, light/dark) | ✅ Complete |
| Auth — SSO (Google + Microsoft Entra ID) + dev bypass | ✅ Complete |
| Project CRUD + deliverable CRUD with auto-pipeline | ✅ Complete |
| User management + role assignment | ✅ Complete |
| Dependency engine + stage state machine | ✅ Complete |
| Artist assignments + My Work page | ✅ Complete |
| Table view (TanStack Table, filters, sort, column visibility) | ✅ Complete |
| Board view (Kanban drag-and-drop) | ✅ Complete |
| Timeline view (Gantt with dependencies) | ✅ Complete |
| Dashboard (KPIs, charts, overdue alerts) | ✅ Complete |
| Revision tracking (rounds, feedback notes, history) | ✅ Complete |
| Threaded comment system | ✅ Complete |
| Notification system (in-app bell + full page) | ✅ Complete |
| Excel import (bulk upload from Master CG Tracker) | ✅ Complete |
| Excel export | ✅ Complete |
| Deadline tracking (approaching/overdue + notifications) | ✅ Complete |
| Command palette (Cmd+K) | ✅ Complete |
| Bulk operations (multi-select → batch status/assignment/priority) | ✅ Complete |
| Loading skeletons, error boundaries, empty states | ✅ Complete |
| Responsive design + mobile sidebar | ✅ Complete |
| Accessibility (skip-to-content, ARIA, focus-visible) | ✅ Complete |
| Stage date override + scheduling features | ✅ Complete |
Beyond Phase 4 (implemented opportunistically)
| Feature | Notes |
|---|---|
| Workload capacity grid | Artist × Week grid with status bars, overallocation warnings, 4/8/12-week projections |
| Workload utilization heatmap | Color-coded heatmap on workload page (green → yellow → red by load). Added in c8f88c6. |
| Calendar view | Monthly calendar with event pills, filters, day detail. Not in original plan. |
| Calendar heatmap | Heatmap overlay on calendar grid with toggle and bar visualization. Added in bac6d4c. Not in original plan. |
| Automation rule engine | Full trigger/action engine with event bus, rule evaluator, action executor, execution log |
| Semantic search (pgvector + Ollama) | Embedding service, hybrid search, pgvector columns on Project + Deliverable |
| AI Chat panel | SSE streaming chat with tool calls (search_entities), entity cards, project/deliverable context. Not in original plan. |
| Weekly executive report | Full report page at /reports/weekly/[date] with KPI strip, completed, deadlines, at-risk, upcoming sections |
| Skill data model | Skill, UserSkill, StageSkillRequirement in schema with seed data — no assignment UI yet |
Phase 2: Multi-Brand Ready (Dynamic Pipelines)
| Feature | Status |
|---|---|
| WP1 — RBAC Foundation | ✅ Complete |
Permission enum (20 perms) + OrgRolePermission model |
✅ |
requireAuth(permission?) replaces getAuthSession() across all 28 API routes |
✅ |
| Default permissions per role (ADMIN/PRODUCER/ARTIST) with org-level overrides | ✅ |
Permission matrix settings page (/settings/permissions) |
✅ |
| WP2 — Org Hardening | ✅ Complete |
Denormalized organizationId on Deliverable + DeliverableStage |
✅ |
assertOrgAccess() on all project/deliverable/stage API routes |
✅ |
Backfill script (scripts/backfill-org-ids.ts) |
✅ |
| WP3 — Dynamic Pipeline Schema | ✅ Complete |
PipelineTemplate, PipelineStageDefinition, PipelineStageDependencyV2 models |
✅ |
pipelineTemplateId on Project, stageDefinitionId on DeliverableStage |
✅ |
| Stage resolver normalizes old/new definitions | ✅ |
deliverable-service.ts creates stages from project's dynamic pipeline |
✅ |
Migration script (scripts/migrate-to-dynamic-pipelines.ts) |
✅ |
| WP4 — Pipeline Template CRUD | ✅ Complete |
| Full service: list, get, create, update, archive, duplicate | ✅ |
| Stage CRUD: add, update, remove, reorder | ✅ |
| Dependency management with cycle detection | ✅ |
| Pipeline validation (cycles, orphans, root stages) | ✅ |
8 API routes under /api/pipelines/ |
✅ |
| WP5 — Pipeline Builder UI | ✅ Complete |
@xyflow/react dependency graph visualization |
✅ |
Pipeline list page (/settings/pipelines) with create, duplicate, archive |
✅ |
| Pipeline editor page with two-panel layout (stage list + dependency graph) | ✅ |
| Stage edit sheet, validation banner, custom edge with delete | ✅ |
| WP6 — Invite System & Org Onboarding | ✅ Complete |
Invitation model with token-based accept flow |
✅ |
| Invitation service: create, list, revoke, accept | ✅ |
Team settings page (/settings/team) with member list + invite form |
✅ |
| WP7 — Custom Fields & Notification Rules | ✅ Complete |
CustomFieldDefinition model + customFields JSON on Project/Deliverable |
✅ |
NotificationRule model (org-scoped event + conditions + channels) |
✅ |
| CRUD services, validators, hooks, API routes for both | ✅ |
Custom fields settings page (/settings/fields) |
✅ |
Notification rules settings page (/settings/notifications) |
✅ |
Remaining Work — Priority Order
A. Visual Review Tool
The highest-impact remaining feature. CG production review is fundamentally visual — this is a single, unified review tool built in stages, each independently useful. No throwaway prototypes.
The review tool lives at its own dedicated page (/projects/[projectId]/deliverables/[deliverableId]/review) and is also accessible from the stage detail sheet via a "Review" button. It's the primary interface for inspecting renders, comparing revisions, annotating feedback, and making approve/reject decisions.
Infrastructure built so far:
- Review page at
/projects/[projectId]/deliverables/[deliverableId]/reviewwith image viewer, upload, gallery - Canvas-based image viewer with zoom/pan/minimap, retina support
- Image upload API with PNG alpha compositing + TIFF conversion (sharp)
Revision.attachmentsJSON stores{ referenceImage, currentImage }with metadata- Comparison viewer with 4 modes: side-by-side, wipe, overlay, toggle
- SVG annotation layer with 7 tools (rect, ellipse, arrow, freehand, text, pin, screenshot paste)
- Annotation model in Prisma schema (requires
db pushto sync) - Annotation API: GET/POST
/api/revisions/[id]/annotations, PATCH/DELETE/api/revisions/[id]/annotations/[id] - Annotations linked to comments (transactional create), undo/redo stack
- Screenshot paste: Cmd+V pastes clipboard image as draggable/resizable callout
- "Review" button on stage cards in deliverable detail page
New dependency for all stages: sharp (server-side PNG alpha compositing + image processing)
A1 — Review Viewer & Image Upload [x]
The foundation. A dedicated review page with a high-fidelity image viewer and the upload infrastructure to get images into the system.
What gets built:
- Review page at
/projects/[projectId]/deliverables/[deliverableId]/review— full-width layout with image viewer as the centerpiece, toolbar at top, panels on the sides - Image viewer — canvas-based with WebGL acceleration for large CG renders (4000×4000px+)
- Zoom: scroll wheel, pinch gesture, keyboard (+/-), toolbar presets (Fit, 50%, 100%, 150%, 200%)
- Pan: click-drag when zoomed, minimap overlay showing viewport position
- Pixel info: coordinate display (x, y) + color readout (RGB/Hex) in status bar
- High-DPI (retina) support with proper pixel ratio handling
- Image upload — drag-and-drop zone + click-to-browse for reference and current render per revision round
- Supports PNG, TIFF, JPEG, WebP up to 50MB
- PNG alpha compositing on upload — flatten transparent PNGs onto white (#FFF) background server-side using
sharp, so CG renders with semi-transparent drop shadows display correctly in all comparison and overlay modes - Store flattened version for viewing + optionally keep original transparent PNG for download
- Extend
Revision.attachmentsJSON:{ referenceImage?: { url, filename, size, uploadedAt, originalUrl? }, currentImage?: { ... } }
- Image gallery — thumbnail strip of all uploaded images across revision rounds, with round number labels. Click any to load it in the viewer.
- "Review" button on stage cards in the deliverable detail page — opens the review page for that stage
New API endpoints:
POST /api/stages/[stageId]/revisions/[revisionId]/upload— multipart form upload (type: "reference" | "current")DELETE /api/stages/[stageId]/revisions/[revisionId]/upload— remove an uploaded image
Key files:
src/app/(app)/projects/[projectId]/deliverables/[deliverableId]/review/page.tsx— Review pagesrc/components/review/image-viewer.tsx— Core canvas viewersrc/components/review/zoom-controls.tsx— Zoom toolbar + keyboard handlersrc/components/review/minimap.tsx— Navigation minimap overlaysrc/components/review/image-upload-zone.tsx— Drag-and-drop uploadsrc/components/review/image-gallery.tsx— Thumbnail strip across roundssrc/hooks/use-image-viewer.ts— Pan/zoom state managementsrc/lib/services/upload-service.ts— File storage + PNG alpha compositing
A2 — Version Comparison [x]
Compare two revisions of the same deliverable stage. This is the daily workhorse — producers and artists check what changed between rounds.
What gets built:
- Comparison modes (toolbar toggle in the review page):
- Side-by-side — dual panes with synced zoom/pan, version labels
- A-B Slider (wipe) — draggable vertical/horizontal divider revealing one image on each side
- Overlay — second image overlaid with adjustable opacity (0–100%)
- Toggle — click or press Space to crossfade between images (default on narrow screens)
- Revision selectors — dropdowns for left/right revision (default: previous round vs. current)
- Synced navigation — zoom/pan one pane, both move together across all modes
- Keyboard shortcuts — 1/2/3/4 to switch modes, left/right arrows to cycle revisions
Key files:
src/components/review/comparison-viewer.tsx— Dual-pane orchestratorsrc/components/review/wipe-divider.tsx— Draggable split controlsrc/components/review/overlay-controls.tsx— Opacity slider + mode toggles
Dependencies: Requires A1
A3 — Annotations [x]
Draw pixel-accurate annotations directly on images. Each annotation is anchored to image coordinates so it stays accurate at any zoom level, and is linked to a comment for context.
What gets built:
- SVG overlay layer on top of the canvas viewer (annotations in SVG for crisp scaling, image in canvas for performance)
- Annotation tools — toolbar with: rectangle, ellipse, arrow, freehand path, text label, pin (point marker)
- Screenshot paste callouts — Cmd+V / Ctrl+V pastes a clipboard image directly onto the review image as a floating, repositionable callout. Use case: paste a screenshot of a Maya attribute editor panel, a Photoshop layer setting, or a cropped reference to show the artist exactly what you mean. Callouts can be:
- Moved — drag to reposition anywhere on the image
- Resized — corner handles to scale up/down
- Bordered — automatic contrast border so the callout stands out against the render
- Linked to a comment — same as other annotations, the pasted screenshot becomes part of the feedback thread
- Stored as a small image (uploaded to server, URL in annotation data) anchored to image coordinates like any other annotation
- Color picker for annotation stroke (default: accent red for visibility against CG renders)
- Image-coordinate anchoring — annotations stored in image space, rendered correctly at any zoom
- Comment linking — each annotation creates or attaches to a Comment record; clicking an annotation highlights its comment in the sidebar, and vice versa
- Visibility controls — show/hide all, show/hide per revision round, show resolved vs. open
- Undo/redo for drawing sessions
New data model:
model Annotation {
id String @id @default(cuid())
commentId String
comment Comment @relation(fields: [commentId], references: [id], onDelete: Cascade)
revisionId String
revision Revision @relation(fields: [revisionId], references: [id], onDelete: Cascade)
type AnnotationType
data Json // { x, y, width, height, points[], text, color, strokeWidth, imageUrl? }
imageX Float // anchor point in image coordinates
imageY Float
createdById String
createdBy User @relation(fields: [createdById], references: [id])
createdAt DateTime @default(now())
}
enum AnnotationType { RECTANGLE ELLIPSE ARROW FREEHAND TEXT PIN SCREENSHOT }
Key files:
src/components/review/annotation-layer.tsx— SVG overlay with tool switchingsrc/components/review/annotation-tools.tsx— Toolbar with tool selectionsrc/components/review/annotation-renderer.tsx— Renders individual shapessrc/components/review/screenshot-callout.tsx— Pasted screenshot with drag/resize handlessrc/lib/services/annotation-service.ts— CRUDsrc/lib/validators/annotation.ts— Zod schemassrc/hooks/use-annotations.ts— TanStack Query hook
Dependencies: Requires A1
A4 — Revision History Timeline [x]
A collapsible sidebar panel in the review page showing the full version history for a deliverable stage. The connective tissue between annotations, comparison, and feedback — provides the longitudinal view across all rounds.
What gets built:
- Vertical timeline in a collapsible right-side panel, each revision round as a node:
- Thumbnail preview of that round's submitted image
- Round number + status badge (Submitted, Changes Requested, Approved)
- Submitted by (name + avatar) + timestamp
- Annotation count (clickable to filter annotation layer to that round)
- Comment thread summary — first line + total count
- Decision record — who approved/rejected, when, with what note
- Click any round to load that version in the viewer with its annotations
- Keyboard navigation — up/down arrows to move through rounds
- Comparison integration — select two rounds from the timeline to open them in comparison mode (A2)
- Filtering — show all rounds, show only rounds with feedback, show only decision points
No new data model — read-only aggregation over existing Revision, Comment, and Annotation records.
Key files:
src/components/review/revision-timeline.tsx— Main timeline panelsrc/components/review/revision-node.tsx— Individual round nodesrc/components/review/revision-comments.tsx— Per-round comment displaysrc/components/review/revision-annotations-summary.tsx— Annotation count + filterssrc/hooks/use-revision-history.ts— TanStack Query hook aggregating revisions + comments + annotations
Dependencies: Requires A1. Enhanced by A3 (annotation counts and filtering).
A5 — Feedback Checklist (Artist Action Items) [x]
Every annotation and actionable comment becomes a structured to-do item on a checklist for the assigned artist. Closes the feedback-to-fix loop.
The feedback loop:
- Reviewer draws annotation or posts actionable comment
- System auto-creates a FeedbackItem linked to the annotation/comment
- Artist sees checklist — action items with direct links to annotations on the image
- Artist works through items — checks each off with optional resolution note
- Artist submits new revision — unchecked action items carry forward with a warning
- Reviewer verifies — can confirm resolution or reopen
Two item types (simplified from 4-level severity):
- Action Item (default) — something the artist needs to fix. Has checkbox, can be resolved/verified.
- Info Callout — context or reference that doesn't require action (e.g., "FYI the client prefers warmer tones"). No checkbox. Can be toggled from action item and vice versa.
Where the checklist appears (3 locations):
- Review page — Feedback Panel (primary): full checklist with action items first, then info callouts. Progress bar counts only action items. Filter by type and status.
- My Work page — feedback badge per assignment ("5 open items")
- Stage card on deliverable page — compact badge ("4/7 resolved") for action items
New data model:
model FeedbackItem {
id String @id @default(cuid())
deliverableStageId String
deliverableStage DeliverableStage @relation(...)
revisionId String
revision Revision @relation(...)
annotationId String?
annotation Annotation? @relation(...)
commentId String?
comment Comment? @relation(...)
summary String
isActionItem Boolean @default(true)
status FeedbackStatus @default(OPEN)
sortOrder Int @default(0)
assignedToId String?
createdById String
resolvedById String?
resolvedAt DateTime?
resolutionNote String?
verifiedById String?
verifiedAt DateTime?
carriedFromId String? // carried forward from prior round
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("feedback_items")
}
enum FeedbackStatus { OPEN IN_PROGRESS RESOLVED VERIFIED REOPENED }
Key files:
src/components/review/feedback-checklist.tsx— Main checklist panelsrc/components/review/feedback-item.tsx— Individual item with resolve actionsrc/components/review/feedback-progress-bar.tsx— Progress barsrc/components/my-work/feedback-summary.tsx— Inline checklist on My Worksrc/components/stages/feedback-indicator.tsx— Compact badge for stage cardssrc/lib/services/feedback-service.ts— CRUD, auto-creation, carry-forward logicsrc/hooks/use-feedback-items.ts
Dependencies: Requires A3 (annotations to generate items from) + A4 (timeline for round context)
A6 — Review Sessions & Playlists [ ]
Curate a batch of deliverables into a structured review session. Walk through them sequentially in presenter mode with per-item decisions. The formal review workflow for HP stakeholder reviews.
What gets built:
- Session builder — pick deliverables/stages to include, drag to reorder, auto-generate from filters ("all Catalog Images in Review for Project X")
- Presenter mode — full-screen, navigate with arrow keys, image viewer with annotations, comment sidebar, prominent approve/request-changes/reject buttons per item
- Summary view — thumbnail grid with decision status badges, overall session progress
- Session states — DRAFT → IN_PROGRESS → COMPLETED
- Shareable link with optional expiry and access control
New data model:
model ReviewSession {
id String @id @default(cuid())
name String
status ReviewSessionStatus @default(DRAFT)
createdById String
organizationId String
shareToken String? @unique
expiresAt DateTime?
items ReviewSessionItem[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model ReviewSessionItem {
id String @id @default(cuid())
sessionId String
deliverableStageId String
revisionId String?
sortOrder Int
decision ReviewDecision?
decisionNote String?
decidedById String?
decidedAt DateTime?
}
enum ReviewSessionStatus { DRAFT IN_PROGRESS COMPLETED }
enum ReviewDecision { APPROVED CHANGES_REQUESTED REJECTED }
Key files:
src/app/(app)/reviews/page.tsx— Session listsrc/app/(app)/reviews/[sessionId]/page.tsx— Session presenter viewsrc/components/review/session-builder.tsx— Create/edit sessionsrc/components/review/session-presenter.tsx— Full-screen walkthroughsrc/components/review/session-summary.tsx— Thumbnail grid with decisionssrc/lib/services/review-session-service.ts
Dependencies: Requires A1 + A3
B. Collaboration Enhancements
B1 — Rich @Mentions with Deep Linking
What: @ trigger in comment input opens user autocomplete. Mentioned users get a notification with a direct link to the comment.
Key files:
src/components/comments/mention-input.tsxsrc/components/comments/mention-renderer.tsx- Update
src/lib/services/comment-service.ts— extract mentions + create notifications
B2 — Project Activity Feed
What: Unified chronological stream of all activity on a project — status changes, comments, uploads, assignments, approvals.
New data model:
model ActivityEntry {
id String @id @default(cuid())
projectId String
deliverableId String?
stageId String?
userId String
type ActivityType
summary String
metadata Json?
createdAt DateTime @default(now())
}
enum ActivityType {
STATUS_CHANGE COMMENT_ADDED REVISION_SUBMITTED ASSIGNMENT_CHANGED
APPROVAL_DECISION FILE_UPLOADED DEADLINE_CHANGED PRIORITY_CHANGED
PROJECT_CREATED DELIVERABLE_CREATED
}
Key files:
src/components/activity/activity-feed.tsxsrc/components/activity/activity-entry.tsxsrc/lib/services/activity-service.tssrc/app/api/projects/[projectId]/activity/route.ts
B3 — External Review Links
What: Token-based URLs for external HP stakeholders to view specific deliverables without an account. Optional watermark (reviewer name, date, CONFIDENTIAL), configurable expiry, access logging, revoke capability.
Key files:
src/app/(external)/review/[token]/page.tsxsrc/components/review/watermark-overlay.tsxsrc/lib/services/external-link-service.ts
C. Reporting Completions
C1 — Velocity & Throughput Metrics
What: Deliverables completed per week, average time per stage, bottleneck detection. Trend charts over 4/8/12/26-week windows.
Key files:
src/components/dashboard/velocity-chart.tsxsrc/components/dashboard/cycle-time-chart.tsxsrc/components/dashboard/bottleneck-chart.tsxsrc/lib/services/analytics-service.ts
C2 — Burndown Charts
What: Per-project burndown with ideal line, actual line, and velocity-based projection with confidence interval. Warning when projection exceeds deadline.
Key files:
src/components/dashboard/burndown-chart.tsxsrc/components/dashboard/projection-engine.ts
C3 — Client-Facing Dashboard (Read-Only Portal)
What: Simplified read-only view for HP stakeholders via secure share link. No account required. Configurable visibility, optional password + expiry.
New data model:
model PortalLink {
id String @id @default(cuid())
token String @unique
organizationId String
projectIds String[]
createdById String
password String?
expiresAt DateTime?
lastAccessedAt DateTime?
accessCount Int @default(0)
isActive Boolean @default(true)
createdAt DateTime @default(now())
}
Key files:
src/app/(portal)/[token]/page.tsxsrc/app/(portal)/[token]/projects/[projectId]/page.tsxsrc/components/portal/portal-header.tsxsrc/lib/services/portal-service.ts
New dependency: bcryptjs (password hashing for portal links)
C4 — SLA Tracking
What: Target turnaround times per stage type. Real-time on-track / at-risk / breached status. Business-hours-aware calculation. Compliance dashboard widget.
New data model:
model SLATarget {
id String @id @default(cuid())
organizationId String
stageType String
targetHours Int
warningThreshold Float @default(0.75)
isActive Boolean @default(true)
createdAt DateTime @default(now())
}
Key files:
src/app/(app)/settings/sla/page.tsxsrc/components/dashboard/sla-compliance-chart.tsxsrc/components/stages/sla-indicator.tsxsrc/lib/services/sla-service.ts
D. Automation Completions
The automation rule engine (Phase 7.1) is fully built. These features extend it.
D1 — Automation Rules UI
What: Admin interface to create, edit, enable/disable automation rules. The engine exists — this is the management UI it's missing.
Key files:
src/app/(app)/settings/automations/page.tsxsrc/components/automations/rule-builder.tsxsrc/components/automations/execution-log.tsx
D2 — Multi-Level Approval Chains
What: Approval workflows requiring sign-off from multiple stakeholders in sequence. Each step: approver role/user, required/optional, auto-advance on approve. Visual progress indicator.
New data model:
model ApprovalChain {
id String @id @default(cuid())
name String
organizationId String
stageType String?
steps ApprovalStep[]
createdAt DateTime @default(now())
}
model ApprovalStep {
id String @id @default(cuid())
chainId String
stepOrder Int
approverRole Role?
approverUserId String?
isRequired Boolean @default(true)
autoAdvance Boolean @default(true)
approvalRecords ApprovalRecord[]
}
model ApprovalRecord {
id String @id @default(cuid())
deliverableStageId String
stepId String
decision ReviewDecision
note String?
decidedById String
decidedAt DateTime @default(now())
}
Key files:
src/app/(app)/settings/approvals/page.tsxsrc/components/approvals/chain-builder.tsxsrc/components/approvals/approval-progress.tsxsrc/lib/services/approval-service.ts
D3 — Project Templates
What: Save a full project configuration (deliverables, stage settings, default assignments) as a reusable template. One-click project creation for repeat HP SKU types.
New data model:
model ProjectTemplate {
id String @id @default(cuid())
name String
description String?
organizationId String
createdById String
isShared Boolean @default(true)
configuration Json
deliverables ProjectTemplateDeliverable[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model ProjectTemplateDeliverable {
id String @id @default(cuid())
templateId String
name String
type String?
priority Priority @default(MEDIUM)
defaultAssignments Json?
sortOrder Int
}
Key files:
src/app/(app)/templates/page.tsxsrc/components/templates/template-card.tsxsrc/components/templates/template-builder.tsxsrc/lib/services/template-service.ts
E. Asset Intelligence
E1 — File Validation on Upload
What: Automatically validate uploaded files against spec requirements (resolution, color space, format, file size, aspect ratio). Reject non-conforming files with clear error messages. Override option for producers.
New data model:
model AssetSpec {
id String @id @default(cuid())
organizationId String
stageType String
name String
rules Json // { minWidth, minHeight, maxFileSize, allowedFormats[], colorSpace, dpi }
isActive Boolean @default(true)
validationResults AssetValidationResult[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model AssetValidationResult {
id String @id @default(cuid())
revisionId String
specId String
passed Boolean
results Json // [{ check, expected, actual, passed }]
overrideById String?
overrideReason String?
validatedAt DateTime @default(now())
}
Key files:
src/app/(app)/settings/asset-specs/page.tsxsrc/components/upload/file-validator.tsxsrc/lib/services/asset-validation-service.ts
New dependency: sharp (already needed for A1 PNG compositing)
E2 — Thumbnail & Preview Generation
What: Auto-generate web-optimized thumbnails (200px), previews (1200px), and full copies from uploaded high-res assets. Background processing queue.
Key files:
src/lib/services/preview-service.tssrc/lib/jobs/generate-previews.tssrc/components/common/optimized-image.tsx
E3 — AI Review Engine Integration Point
What: Webhook endpoint for an external AI Review Engine to post structured quality analysis results. AI-flagged regions rendered as dashed-border annotations in the viewer. Configuration per stage type.
New data model:
model AIReviewResult {
id String @id @default(cuid())
revisionId String
overallScore Float
passed Boolean
checks Json
flaggedRegions Json
engineVersion String
processingTimeMs Int
createdAt DateTime @default(now())
}
Key files:
src/app/api/webhooks/ai-review/route.tssrc/components/review/ai-review-overlay.tsxsrc/components/review/ai-review-summary.tsxsrc/lib/services/ai-review-service.ts
F. Quality of Life
F1 — Saved Filters & Custom Views
What: Save current filter/sort/column config as a named view. Personal and shared views. URL-encodable for link sharing.
New data model:
model SavedView {
id String @id @default(cuid())
name String
userId String
organizationId String
projectId String?
viewType ViewType
configuration Json
isShared Boolean @default(false)
isPinned Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum ViewType { TABLE BOARD TIMELINE }
Key files:
src/components/views/saved-view-picker.tsxsrc/components/views/save-view-dialog.tsxsrc/lib/services/saved-view-service.ts
F2 — Skill-Based Assignment UI
What: The Skill / UserSkill / StageSkillRequirement data models already exist. This adds the UI: skill tags on user profiles, skill requirements on stage templates, and best-fit artist suggestions in the assignment dialog (sorted by skill match + lowest current load).
Key files:
src/app/(app)/settings/skills/page.tsxsrc/components/assignments/skill-match-suggestions.tsxsrc/lib/services/skill-service.ts— matching algorithm
F3 — Batch Upload with Auto-Matching
What: Drop multiple files onto a project; auto-match to deliverables by file naming convention (configurable regex). Preview table shows match confidence, manual override available.
Key files:
src/components/upload/batch-upload-zone.tsxsrc/components/upload/file-matcher.tsxsrc/lib/services/file-matching-service.ts
F4 — Extended Command Palette Actions
What: Add quick-action commands to the existing Cmd+K palette: "approve and advance," "assign to me," "mark blocked," "start review session." Context-aware based on current page.
Key files:
- Update
src/components/layout/command-palette.tsx src/lib/commands/action-registry.ts
G. Docker Deployment
G1 — Docker Compose Stack
What: docker-compose.yml with three services — Next.js app, PostgreSQL + pgvector, Ollama with pre-configured models. One docker compose up starts everything.
Note: Dockerfile and docker-compose.yml already exist in the repo root — review and complete as needed.
Services:
| Service | Image | Purpose |
|---|---|---|
app |
Custom Dockerfile | Next.js production build |
db |
pgvector/pgvector:pg17 |
PostgreSQL with pgvector |
ollama |
ollama/ollama:latest |
Local AI (nomic-embed-text + qwen3.5:9b) |
Key files:
Dockerfile— multi-stage Next.js build (review existing)docker-compose.yml— full stack (review existing)docker/ollama-entrypoint.sh— model bootstrap scriptdocker/db-init.sql—CREATE EXTENSION IF NOT EXISTS vector;.env.example— environment template
G2 — Health Checks & Startup Orchestration
What: pg_isready health check on db, Ollama API health check, prisma migrate deploy runs on app startup before next start. depends_on: condition: service_healthy ensures correct start order.
G3 — Dev Environment Override
What: docker-compose.dev.yml that mounts source code and runs next dev for hot reloading, while keeping database and Ollama in containers.
Key files:
docker-compose.dev.yml
Data Model Status
Models Currently in Schema
| Model | Status |
|---|---|
| Organization, User, Account, Session | ✅ |
| PipelineStageTemplate, PipelineStageDependency | ✅ (legacy global, kept for backward compat) |
| PipelineTemplate, PipelineStageDefinition, PipelineStageDependencyV2 | ✅ (Phase 2 — org-scoped dynamic pipelines) |
| OrgRolePermission | ✅ (Phase 2 — RBAC) |
| Invitation | ✅ (Phase 2 — invite system) |
| CustomFieldDefinition | ✅ (Phase 2 — custom fields) |
| NotificationRule | ✅ (Phase 2 — notification rules) |
| Project, Deliverable, DeliverableStage | ✅ (with pgvector, customFields JSON, org denormalization) |
| StageAssignment, Revision, Comment | ✅ |
| Notification | ✅ |
| AutomationRule, AutomationExecution | ✅ |
| Skill, UserSkill, StageSkillRequirement | ✅ |
| SearchLog | ✅ |
| ChatMessage | ✅ |
Models Needed (not yet in schema)
| Model | Feature |
|---|---|
| Annotation | A3 |
| FeedbackItem | A5 |
| ReviewSession, ReviewSessionItem | A6 |
| ApprovalChain, ApprovalStep, ApprovalRecord | D2 |
| ProjectTemplate, ProjectTemplateDeliverable | D3 |
| AssetSpec, AssetValidationResult | E1 |
| AIReviewResult | E3 |
| PortalLink | C3 |
| SLATarget | C4 |
| ActivityEntry | B2 |
| SavedView | F1 |
Architecture Reference
src/
├── app/
│ ├── (auth)/login/ # SSO login
│ ├── (app)/ # Authenticated routes
│ │ ├── dashboard/
│ │ ├── projects/[projectId]/
│ │ │ ├── table/ board/ timeline/
│ │ │ └── deliverables/[deliverableId]/
│ │ ├── my-work/
│ │ ├── workload/ # ✅ Capacity grid + heatmap
│ │ ├── calendar/ # ✅ Calendar view
│ │ ├── reports/weekly/ # ✅ Weekly executive report
│ │ ├── reviews/ # A7 Review sessions
│ │ ├── templates/ # D3 Project templates
│ │ └── settings/
│ │ ├── permissions/ # ✅ Phase 2 RBAC matrix
│ │ ├── pipelines/ # ✅ Phase 2 Pipeline builder
│ │ ├── team/ # ✅ Phase 2 Team + invitations
│ │ ├── fields/ # ✅ Phase 2 Custom fields
│ │ ├── notifications/ # ✅ Phase 2 Notification rules
│ │ └── skills/ # ✅ Skills management
│ ├── (portal)/[token]/ # C3 Client portal (external)
│ ├── (external)/review/ # B3 External review links
│ └── api/
├── components/
│ ├── ui/ # shadcn/ui primitives
│ ├── layout/ # Sidebar, topbar, command palette
│ ├── views/ # Table, Board, Timeline, Dashboard
│ ├── workload/ # ✅ Capacity grid + heatmap components
│ ├── calendar/ # ✅ Calendar components
│ ├── reports/weekly/ # ✅ Weekly report components
│ ├── pipeline-builder/ # ✅ Phase 2 Pipeline graph + stage list
│ ├── revisions/ # A1 Image comparison (to build)
│ ├── review/ # A2-A7 Full review viewer (to build)
│ ├── automations/ # D1 Automation UI (to build)
│ └── search/ # ✅ Smart search panel
├── lib/
│ ├── pipeline/ # ✅ Dependency engine + stage machine + stage resolver
│ ├── rbac/ # ✅ Phase 2 permissions + org scope + requireAuth
│ ├── automation/ # ✅ Event bus + rule engine + executor
│ ├── services/ # Business logic per entity
│ └── validators/ # Zod schemas
├── hooks/ # TanStack Query hooks
└── stores/ # Zustand (UI state, filters)
Key Patterns
- Thin API routes → delegate to
lib/services/for all business logic - Service layer → Prisma queries + business rules (testable, reusable)
- URL-synced filters via
nuqs— views are shareable/bookmarkable - Server Components for initial fetch, TanStack Query for mutations/cache
npx prisma db pushfor schema changes (no migrations dir — use db push)
Local Dev
# Start DB
brew services start postgresql@17
# Start app (must source nvm)
export NVM_DIR="$HOME/.nvm" && [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && npm run dev
Third-Party Libraries Needed for Remaining Work
| Library | Purpose | Feature |
|---|---|---|
@xyflow/react |
Pipeline dependency graph visualization | ✅ Phase 2 WP5 (installed) |
sharp |
PNG alpha compositing + image validation + thumbnail generation | A1, E1, E2 |
bcryptjs |
Password hashing for portal links | C3 |
@react-pdf/renderer |
PDF export for weekly report download button | C — weekly report enhancement |
Document version: 1.1 — Updated 2026-03-14 (Phase 2: Dynamic Pipelines complete) To be updated as features are built and priorities shift.