Skip to content

CreatorTrack , Master Roadmap & Architecture Decisions

URL: https://mkdocs.justinsforge.com/memory/plans/creatortrack-roadmap-2026-06-18/

Canonical build sequence for CreatorTrack (the productivity-for-creators app at creatortrack.ai). Consolidates the layered plan as of 2026-06-18. Sub-plans: [[tier2-notion-engine-2026-06-18]], [[property-type-system-2026-06-18]], [[clips-frameio-media-app-2026-06-18]].

Status (2026-06-18)

Layer State
Foundation (tokens, Section 0 primitives, Studio) ✅ DONE
Tier 1 component library (21 components) ✅ DONE
Property type system (23 Notion-parity types, one registry) ✅ DONE
Tier 2 Notion engine (block editor + page chrome + database views) ✅ DONE (merged 1700937)
Auth / login ⬜ NEXT
Site-wide polish pass ⬜ (NEW , between auth and files)
Files / streaming backend ⬜ (gates the entire media side)
Media components → Clips app → Review app ⬜ (see clips-frameio plan)
Apps: finance re-skin, fitness, etc.

The sequence from here

  1. Auth / login. See decisions below. Real per-user accounts so the product is usable.
  2. Site-wide polish pass (NEW). A dedicated polish phase across the WHOLE app before the media build: visual consistency, spacing/hover/focus states, empty/loading/error states, responsive/mobile, a11y, microcopy, transitions, dark-mode token audit, performance pass. This is the "make it feel finished" sweep , done once the Notion surface + auth exist so there's a complete product to polish, and before media adds a new surface.
  3. Files / streaming backend. The gate for media (range-request streaming from Finn NVMe + thumbnail serving) AND for uploads everywhere (covers, file property type).
  4. Media components (player/scrubber, clip grid, import buttons, annotation canvas).
  5. Clips app then Review app (Frame.io clone). See [[clips-frameio-media-app-2026-06-18]].
  6. More apps (finance re-skin onto the kit, fitness, etc.) , mostly composition.

Justin's own feature-building (Notion-style: pages, databases, blocks, views) is unlocked NOW by Tier 2; auth makes it real per-user; the polish pass makes it feel shipped.

LOCKED DECISIONS (2026-06-18)

Auth

  • Both providers, linked by email: email+password AND Google login; same email = one linked account (sign up either way, add the other later).
  • Self-hosted, owned: use Auth.js (NextAuth) in the Next app , open-source, native Google OAuth + credentials + account linking + sessions, users/sessions in our core Postgres (users table exists). No SaaS auth (no Clerk/Auth0). Not hand-rolled crypto either.
  • Assess the existing auth.ts first (wire-up vs swap).

Marketing site + workspace URL architecture (Linear/Notion model)

Surface URL
Marketing one-pager (what-it-is + sign-up CTA, Notion/Linear style) creatortrack.ai (apex)
The authenticated app app.creatortrack.ai
A workspace app.creatortrack.ai/{workspace-slug}/… (path-based)
  • Path-based workspaces, NOT per-workspace subdomains. Rationale: path-based = one TLS cert, one cookie domain, one app, and our multi-tenant RLS already scopes by workspace, so it rides what's built with zero new infra. Per-workspace subdomains (monday.com style, justin.creatortrack.ai) need wildcard DNS + wildcard TLS + per-tenant routing , deferred as a future enterprise/white-label option on the same RLS.
  • The …/{workspace}/{team}/ deep path + short team keys (Linear-style JUS-123) are a nice touch, just path segments under app..
  • Marketing can be a public route tree in the same repo served at the apex; app at app..

Marketing landing

  • DONE (2026-06-18): /landing built in worktree mkt-landing , app/(marketing)/landing/page.tsx + components/marketing/* (Notion-dark, theme.css tokens, Bricolage Grotesque display via next/font, AI-core orbit hero, connected-apps bento, CTAs → /signup & /login); tsc --noEmit clean, committed on branch mkt-landing.

Workspace shell polish

  • DONE (2026-06-18): account section pinned to sidebar BOTTOM with upward popup menu (worktree shell-account, AccountMenu.tsx on branch shell-account) , rebuilt on floating primitives (useAnchoredFloating top-start + FloatingPortal + usePresence), email header / Settings / billing / help / apps / log out; avatar shows photoUrl else initials with CHANGE-PHOTO hook awaiting the deferred files backend; B&W, var(--token), tsc --noEmit clean. No WorkspaceShell.tsx change needed (footer already mounts AccountMenu).
  • DONE (2026-06-18): PageHeader top polished to Notion-class (worktree shell-pageheader, branch shell-pageheader) , drag-to-reposition image covers (focal point persisted via #pos= URL fragment, zero backend change), B&W gradient/solid "Color" covers rendered as
    fills, live Saving…/Saved indicator on LastEdited, keyboard-submit pickers, and removed all blue accents (now var(--txt)/--bg/--mut). tsc --noEmit clean. INTEGRATOR NOTE: breadcrumb + Share + …menu already live in components/workspace/Topbar.tsx (not owned by this worker); a top-bar "saved" indicator next to the breadcrumb was left to the Topbar owner.

Worker status

  • shell-pagetree: DONE , PageTree rows (chevron expand, hover + add-subpage, hover ⋯ menu: rename/duplicate/copy-link/move-to/delete) + drag-to-reorder & nest via flattened-tree DnD; tsc clean, 2 commits on branch shell-pagetree (cf9dcdd). Awaiting live QA.

Marketing v2

  • DONE , strictly B&W (Linear-style) rebrand of the marketing surface + auth logo, branch mkt-v2 (worktree forge-suite-wt/mkt-v2, 4 commits, npx tsc --noEmit clean). All purple/blue removed (accent tokens scope-overridden to a monochrome ramp on .ctl-root; app/theme.css untouched). Single landing → multi-page site under a shared (marketing)/layout.tsx (nav + footer): Home (/landing, unchanged route), new /product (connected-apps deep dive), new /pricing (everything-included table + one plan card "Free! for Michael and Justin", $0). White transparent logo wired via static import in nav/footer/auth. Flat-white pill buttons; right-aligned nav links.
  • INTEGRATOR: add these to PUBLIC_PATHS in proxy.ts so they're publicly reachable: /product and /pricing. (/landing, /login, /signup, /reset, /api/auth already public; the logo asset is served from /_next/static/*, already excluded by the middleware matcher, so no /brand allowlist needed.) , DONE: merged to main (bee5968 merge: mkt-v2) and routes allowlisted (5c0d81b). Live on dev (creatortrack-dev.service :3060 / dev.creatortrack.ai via HMR).
  • Follow-up polish (post-merge): pure-CSS section reveal (content no longer depends on hydration , fixed "black space"); richer pages + Linear-style CSS app-window mock (components/marketing/AppMock.tsx), home Showcase+stats+Steps, product split-hero+capabilities, pricing centered hero+FAQ; flat pill buttons (sized .ctl-btn-arrow so full-width pills aren't ellipses); auth: white logo (2x) + Google "G" on the sign-in button, tagline removed. All on main via the merge above.
  • DEPLOY DECISION (Justin, 2026-06-18): do NOT deploy marketing to prod alone , ship as one batch once the in-flight workspace-shell agents (shell-sidebar / pagetree / account / pageheader) finish & merge. Prod = creatortrack-prod.service (npm run start -- -p 3070, WorkingDirectory /home/justinwieb/forge-suite). Batch deploy steps: on main, NODE_ENV=production npm run build then sudo systemctl restart creatortrack-prod.service; verify :3070 serves /landing, /product, /pricing. NOTE: dev (:3060) and prod (:3070) share the same default .next distDir, so the prod build briefly disrupts the dev server , run the build when the shell agents are paused/merged.
  • INTEGRATOR , also fold branch mkt-colors into this batch (worktree /home/justinwieb/forge-suite-wt/mkt-colors, off main @ efafe6d, 1 commit 1630e44): marketing palette pass , strictly monochrome but re-based onto the app's real surfaces (drops the custom deep-black bg, inherits --bg #191919 / --card #202020 / --line #2e2e2e + text greys from app/theme.css; accents stay grey, no blue/purple). Touches only components/marketing/landing.css. tsc clean; approved live by Justin.

Open / later

  • Pretty page URLs (workspace + slug) , today pages are raw /n/{id} (the node's DB id; rename-safe but opaque, Notion-style). Refine to app.creatortrack.ai/{workspace}/{slug}-{id}: a human slug for readability + the workspace prefix (per the locked URL architecture), with the numeric id staying the canonical rename-safe anchor. (Requested by Justin 2026-06-18.)
  • Workspace switcher , a control in the sidebar header (between the CreatorTrack brand and the Home/Chat row) showing the current workspace + a dropdown to switch between the user's workspaces or create a new one. Data already supports it (multi core.memberships; Justin has 2 workspaces: "Justin's Workspace" + "Swag"; core.create_workspace (0013) + core.provision_default_workspace (0034) exist; .ws-switcher/.ws-wsname/.ws-avatar CSS stubs already in workspace.css). NEEDS an "active workspace" concept (session/pref or, better, the URL workspace-prefix above) so the (suite) layout knows which workspace to load. Tied to the pretty-URL item , the workspace prefix IS the switch mechanism. Shell feature (ct-builder's domain). (Requested by Justin 2026-06-18.)
  • Files storage backend specifics (object storage vs files table + NVMe) , decided at step 3.
  • Per-workspace subdomains (enterprise/white-label) , future.
  • Segment/moment-level clip search , future (keyframe embeddings stored from day one so no re-ingest; see clips plan).