Refactor code structure for improved readability and maintainability

This commit is contained in:
Leivur R. Djurhuus 2026-03-14 13:17:19 -05:00
parent fb72ef6dc4
commit b37c7d0bf4
5 changed files with 831 additions and 0 deletions

831
ROADMAP.md Normal file
View file

@ -0,0 +1,831 @@
# 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*
---
## Table of Contents
1. [What's Built](#whats-built)
2. [Remaining Work — Priority Order](#remaining-work--priority-order)
- [A. Image Comparison & Visual Review](#a-image-comparison--visual-review)
- [B. Collaboration Enhancements](#b-collaboration-enhancements)
- [C. Reporting Completions](#c-reporting-completions)
- [D. Automation Completions](#d-automation-completions)
- [E. Asset Intelligence](#e-asset-intelligence)
- [F. Quality of Life](#f-quality-of-life)
- [G. Docker Deployment](#g-docker-deployment)
3. [Data Model Status](#data-model-status)
4. [Architecture Reference](#architecture-reference)
---
## What's Built
### Core Foundation (Phases 14)
| 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 |
| **Utilization heatmap** | Color-coded heatmap on calendar + workload page, toggle between views |
| **Calendar view** | Monthly calendar with event pills, filters, day detail, heatmap overlay. *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** |
---
## Remaining Work — Priority Order
---
### A. Image Comparison & Visual Review
The highest-impact remaining feature area. CG production review is fundamentally visual — everything else supports this core workflow.
---
#### A1 — Reference Image Comparison (Lightweight, in Stage Detail)
**What:** A-B comparison tools embedded in the existing stage detail sheet. Producers and artists compare the reference/approved image against the current WIP render without leaving the deliverable page.
**Why first:** Lower complexity than the full review viewer (A2). Directly improves the daily review loop for existing users and unblocks meaningful visual feedback on revision rounds.
**Implementation:**
- New "Compare" tab in the stage detail sheet (alongside Revisions and Comments tabs)
- Upload zones for reference image + current render per revision round
- Three comparison modes:
- **A-B Slider** — draggable vertical divider (CSS clip-path + pointer events, no dependency)
- **Toggle** — click/Space to crossfade between images
- **Side-by-side** — synced zoom/pan on wide screens
- Scroll-to-zoom + click-drag pan, synced across both images in all modes
- Image gallery: thumbnails of all uploaded images across all revision rounds with round labels
- **PNG alpha compositing on upload** — flatten transparent PNGs onto white background server-side using `sharp`, so CG renders with transparent drop shadows compare correctly
- Extend `Revision.attachments` JSON schema: `{ referenceImage?: {...}, currentImage?: {...}, annotations?: [...] }`
- Lightweight markup overlay (optional): arrow, rectangle, freehand, text pin drawn on top of current image
**New API endpoints:**
- `POST /api/stages/[stageId]/revisions/[revisionId]/upload` — multipart, reference or current image
- `DELETE /api/stages/[stageId]/revisions/[revisionId]/upload` — remove image
**Key files:**
- `src/components/revisions/image-compare-slider.tsx` — A-B slider with drag handle
- `src/components/revisions/image-toggle.tsx` — Toggle/crossfade
- `src/components/revisions/image-side-by-side.tsx` — Synced side-by-side with zoom/pan
- `src/components/revisions/image-upload-zone.tsx` — Drag-and-drop upload
- `src/components/revisions/revision-image-gallery.tsx` — Browse images across revision rounds
- `src/components/revisions/compare-tab.tsx` — Orchestrator: mode selector + comparison view
- `src/components/revisions/markup-overlay.tsx` — Lightweight annotation layer
**New dependency:** `sharp` (server-side PNG alpha compositing on upload)
---
#### A2 — Full-Screen Image Viewer
**What:** Dedicated full-screen viewer with high-fidelity zoom (up to 200%+) for pixel-level inspection of CG renders.
**Implementation:**
- Canvas-based viewer with WebGL acceleration for large images
- Zoom: scroll wheel, pinch, keyboard (+/-), toolbar buttons (fit, 50%, 100%, 150%, 200%, free)
- Pan via click-drag when zoomed; minimap overlay showing viewport position
- Pixel coordinate + color value readout (RGB/Hex) in status bar
- High-DPI display support (retina)
**Key files:**
- `src/components/review/image-viewer.tsx`
- `src/components/review/zoom-controls.tsx`
- `src/components/review/minimap.tsx`
- `src/hooks/use-image-viewer.ts`
---
#### A3 — Pixel-Accurate Annotations
**What:** Draw annotations directly on images — circles, rectangles, arrows, freehand, text labels, pins. Anchored to image coordinates so they stay accurate at any zoom level.
**New data model:**
```prisma
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 }
imageX Float
imageY Float
createdById String
createdBy User @relation(fields: [createdById], references: [id])
createdAt DateTime @default(now())
}
enum AnnotationType { RECTANGLE ELLIPSE ARROW FREEHAND TEXT PIN }
```
**Key files:**
- `src/components/review/annotation-layer.tsx`
- `src/components/review/annotation-tools.tsx`
- `src/components/review/annotation-renderer.tsx`
- `src/lib/services/annotation-service.ts`
- `src/lib/validators/annotation.ts`
- `src/hooks/use-annotations.ts`
**Dependencies:** Requires A2 (Image Viewer)
---
#### A4 — Side-by-Side Version Comparison (Full Viewer)
**What:** Compare two revisions in the full-screen viewer using side-by-side, overlay (opacity slider), wipe (draggable divider), or onion skin modes.
**Key files:**
- `src/components/review/comparison-viewer.tsx`
- `src/components/review/wipe-divider.tsx`
- `src/components/review/overlay-controls.tsx`
- `src/app/(app)/projects/[projectId]/deliverables/[deliverableId]/review/page.tsx`
**Dependencies:** Requires A2
---
#### A5 — Revision History Timeline
**What:** Collapsible panel in the review viewer showing all revision rounds as a vertical timeline. Each node shows thumbnail, status badge, submitter, annotation count, comment summary, and decision record.
**No new data model** — aggregation over existing `Revision`, `Comment`, and `Annotation` records.
**Key files:**
- `src/components/review/revision-timeline.tsx`
- `src/components/review/revision-node.tsx`
- `src/components/review/revision-comments.tsx`
- `src/components/review/revision-annotations-summary.tsx`
- `src/hooks/use-revision-history.ts`
**Dependencies:** Requires A2 + A3
---
#### A6 — Feedback Action Items (Artist Checklist)
**What:** Every annotation and actionable comment auto-creates a FeedbackItem on a structured checklist. Artists work through items (Critical / Major / Minor / Suggestion), check them off with resolution notes. Unresolved critical items block resubmission. Checklist appears in three places: review viewer panel, My Work page, and stage card badge.
**New data model:**
```prisma
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
severity FeedbackSeverity @default(MAJOR)
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 FeedbackSeverity { CRITICAL MAJOR MINOR SUGGESTION }
enum FeedbackStatus { OPEN IN_PROGRESS RESOLVED VERIFIED REOPENED }
```
**Key files:**
- `src/components/review/feedback-checklist.tsx`
- `src/components/review/feedback-item.tsx`
- `src/components/review/feedback-progress-bar.tsx`
- `src/components/my-work/feedback-summary.tsx`
- `src/components/stages/feedback-indicator.tsx`
- `src/lib/services/feedback-service.ts`
- `src/hooks/use-feedback-items.ts`
**Dependencies:** Requires A3 + A5
---
#### A7 — Review Sessions & Playlists
**What:** Curate an ordered set of deliverables into a review session. Walk through them in presenter mode with per-item approve/request-changes/reject decisions. Shareable via link.
**New data model:**
```prisma
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`
- `src/app/(app)/reviews/[sessionId]/page.tsx`
- `src/components/review/session-builder.tsx`
- `src/components/review/session-presenter.tsx`
- `src/components/review/session-summary.tsx`
- `src/lib/services/review-session-service.ts`
**Dependencies:** Requires A2 + 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.tsx`
- `src/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:**
```prisma
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.tsx`
- `src/components/activity/activity-entry.tsx`
- `src/lib/services/activity-service.ts`
- `src/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.tsx`
- `src/components/review/watermark-overlay.tsx`
- `src/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.tsx`
- `src/components/dashboard/cycle-time-chart.tsx`
- `src/components/dashboard/bottleneck-chart.tsx`
- `src/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.tsx`
- `src/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:**
```prisma
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.tsx`
- `src/app/(portal)/[token]/projects/[projectId]/page.tsx`
- `src/components/portal/portal-header.tsx`
- `src/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:**
```prisma
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.tsx`
- `src/components/dashboard/sla-compliance-chart.tsx`
- `src/components/stages/sla-indicator.tsx`
- `src/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.tsx`
- `src/components/automations/rule-builder.tsx`
- `src/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:**
```prisma
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.tsx`
- `src/components/approvals/chain-builder.tsx`
- `src/components/approvals/approval-progress.tsx`
- `src/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:**
```prisma
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.tsx`
- `src/components/templates/template-card.tsx`
- `src/components/templates/template-builder.tsx`
- `src/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:**
```prisma
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.tsx`
- `src/components/upload/file-validator.tsx`
- `src/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.ts`
- `src/lib/jobs/generate-previews.ts`
- `src/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:**
```prisma
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.ts`
- `src/components/review/ai-review-overlay.tsx`
- `src/components/review/ai-review-summary.tsx`
- `src/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:**
```prisma
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.tsx`
- `src/components/views/save-view-dialog.tsx`
- `src/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.tsx`
- `src/components/assignments/skill-match-suggestions.tsx`
- `src/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.tsx`
- `src/components/upload/file-matcher.tsx`
- `src/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 script
- `docker/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 | ✅ |
| Project, Deliverable, DeliverableStage | ✅ (with pgvector embedding columns) |
| StageAssignment, Revision, Comment | ✅ |
| Notification | ✅ |
| AutomationRule, AutomationExecution | ✅ |
| Skill, UserSkill, StageSkillRequirement | ✅ |
| SearchLog | ✅ |
| ChatMessage | ✅ |
### Models Needed (not yet in schema)
| Model | Feature |
|---|---|
| Annotation, FeedbackItem | A3, A6 |
| ReviewSession, ReviewSessionItem | A7 |
| 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/
│ ├── (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
│ ├── 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
│ ├── 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 push`** for schema changes (no migrations dir — use db push)
### Local Dev
```bash
# 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 |
|---|---|---|
| `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.0 — Created 2026-03-14*
*To be updated as features are built and priorities shift.*