Skip to content

URL: https://mkdocs.justinsforge.com/memory/general/reference_creatortrack_work_hierarchy/

CreatorTrack Work Hierarchy + Dashboard

DEPLOYED to prod 2026-07-12 (merged to main f5dafb6, plain code merge, no migration, creatortrack-prod restarted). Built on branch feat/work-hierarchy-dashboard (base 1b4a3b4). Plan: creatortrack-tasks-projects-goals-visibility-2026-07-12. Nine build commits + 4 review-fix commits. Review found 1 blocker (goals project-picker wrong workspace param -> cross-workspace link; fixed 0d73aea) + 3 cautions (board-drag recurrence spawn cc4aaa8, 0-task goal 0% override d6bbcfd, dashboard double-query c15841a), all fixed + verified. Verified live: board reads real Status pipeline, Dashboard endpoint 200, goals unaffected.

North star: everything generic, NO "dev mode"/"software" label. The dev pipeline (Send to Forge / In Development / In Review / Ready to Merge / Deployed / Done / Blocked) is just one configuration of a workspace's universal Status options; a content workspace shows whatever statuses its tasks use.

Phase 1 - see and drive the pipeline (Tasks)

  • Pipeline Board surface (1dd55f3): board added to SurfaceViewType/SURFACE_VIEW_TYPES/DEFAULT_SURFACE_VIEWS (lib/tasks.ts) + ViewTabsBar types. Tasks app board surface reuses components/apps/projects/ProjectBoardView.tsx, columns = the workspace's REAL Tasks Status prop options via a new taskStatuses field on the tasks aggregate (listTasks reads the Status prop config, ordered union preserving pipeline order, default To do/Doing/Done). Dragging a card sends ONLY {status} (the server derives done; the PATCH route's done fast-path would otherwise drop the status). Group-by also offers Priority + custom selects.
  • Any-property filter bar (934edb3): TaskFilterSortBar gains status (multi-select from the pipeline) + fields (per custom SELECT, e.g. Type/Milestone) axes on EVERY surface incl. Board. Persist through the tasks_app prefs blob (filterStatus array + filterFields object) in lib/tasks.ts + the settings route; applyTaskFilterSort applies status (any-of) + fields (exact, AND across fields).
  • Richer quick-add (38a1336): Composer gets a Status chip (from taskStatuses) so a task can be filed straight into e.g. Send to Forge at creation; status on ComposerSubmit, applied via createTask's post-create PATCH. Type/custom-select were already pickable.

Phase 2 - projects show how-far-along

  • Progress rollup with pipeline breakdown (c18e45c): shared components/apps/projects/ProjectProgress.tsx (segmented done/in-progress/blocked/to-do bar + "N tasks: X Done, Y In Review, ..." legend) fed by the existing counts.byStatus rollup (no new math). On overview cards, status-board cards (compact), project peek.
  • Roadmap (0f1ba60): new overview-only "Roadmap" tab (lib/projects-shared.ts view types + ProjectRoadmap.tsx): each project a dated bar Start->Target on a month axis, progress fill, today line, unscheduled tray.
  • Milestones (ad18149): a milestone = a value of the tasks' Milestone SELECT field (a dated checkpoint a set of tasks rolls into). components/apps/projects/milestones.ts (computeMilestones) + ProjectMilestones summary in the peek (each milestone done/total + bar + date); roadmap bars get diamond milestone markers. The task Board already groups by Milestone.

Phase 3 - roll up to goals + command center

  • Projects -> goals rollup (44cdd3b): new "Linked Projects" relation on the goals db (lib/system-apps.ts, targets the Projects db, idempotent-backfilled). getGoalsData reads it and rolls each goal's linked projects' task completion into a combined progress via listProjects (SAME rollup the Projects app uses, no new goal math). Goal editor multi-select; goal card ring + rollup line + detail-panel headline reflect it when linked.
  • Dashboard command center (11fc9c8): read-only lens over the whole hierarchy. Sidebar entry directly below Home/Chat (WorkspaceShell.tsx), show/hide toggled + remembered per user (localStorage ct-dashboard-visible:<email>; when hidden a "Show Dashboard" affordance remains). Route /dashboard (app/(suite)/dashboard/page.tsx -> DashboardClient.tsx) fetches /api/apps/dashboard -> lib/dashboard.ts getDashboardData, which aggregates LIVE (no new storage): pipeline status counts (workspace Status order), a Needs-your-attention list (In Review + Blocked), project progress bars, a goal summary (using the rollup above), and recent build/automation/GitHub/edit activity (listWorkspaceActivity).

Gotchas learned

  • The tasks PATCH route (/api/tasks/[id]) short-circuits when done is a boolean; a status write must send {status} alone (server derives done). PeekPatch gained status.
  • This dev clone splits ws67's projects across two "Projects" nodes (system-keyed 5994 empty vs app db 5658); /api/projects route resolves the workspace via cookie so it can disagree with the app UI. Verified goals rollup in ws74 where the app db = system db. Not a product bug; a clone data quirk.
  • Playwright on this app: raw JS element.click() on popover options doesn't reliably commit React state into the submit closure; use native locator.click(). Tab clicks are swallowed by the ContextMenuShell wrapper on single native click.

Report: forge/comms/results/creatortrack-work-hierarchy-dashboard.md.