Skip to content

CreatorTrack dev testing (headless, as a test user)

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

How to exercise CreatorTrack UI flows from Console without touching Justin's real account or the shared dev server. Built 2026-07-04 during the mobile UX iteration. [Claude Code]

The recipe

  1. Do NOT test auth'd flows against http://127.0.0.1:3060 with a fresh login: AUTH_URL=https://dev.creatortrack.ai makes the session cookie __Secure- prefixed, and it will not stick over plain http, so every page renders "Not provisioned." even though signup/login succeeded. https://dev.creatortrack.ai itself is behind Cloudflare Access (email code), so headless login there is also out.
  2. Instead run a private dev server with the opt-in dev-auth bypass (lib/auth.ts devFallbackEmail):
cd ~/forge-suite && set -a && source ~/.forge-secrets/creatortrack-auth.env && set +a && \
PORT=3210 NODE_ENV=development WORKSPACE_DEV_AUTH=1 \
WORKSPACE_DEV_EMAIL=[email protected] \
CT_DIST_DIR=.next-devtest AUTH_URL=http://localhost:3210 npm run dev

Every request resolves as that email via core.login() (auto-creates the core user). No cookies needed; curl/fetch against /api/* is authenticated too (used it to POST /api/apps/install {"appId":"knowledge"} when clicking the App Library card was flaky). 3. CT_DIST_DIR MUST be unique (.next-devtest), never .next-dev: the shared creatortrack-dev service corrupts its Turbopack cache if another process shares the dist dir. Delete the dir when done. 4. Mobile viewport with agent-browser: npx agent-browser set viewport 390 844 before open. Re-snapshot before every click; refs (@e3) shift between renders, stale refs click the wrong element. 5. Standing test identity: [email protected] / testpass1234, lifeos user 79, workspace mobiletest0704 (id 69) with Tasks + Notes installed. Reuse it; do not create more throwaways. 6. Editing provider/shell components while a page is loaded can leave Fast Refresh state corrupted (buttons stop responding). Full-page reload before concluding a regression.

Prod deploy while the shared tree is busy (artifact swap)

When another agent is actively committing in ~/forge-suite (so you can neither switch its branch nor build its dirty WIP into prod), deploy from an isolated worktree (first run 2026-07-04, prod verified 200):

  1. git worktree add ~/forge-suite-wt/deploy-main main && cd $_ && git merge <sha> --no-edit (merge a pinned SHA, not the moving branch tip).
  2. If the merge brought a db/migrations/*.sql, confirm it is already applied before shipping code that needs it.
  3. cp -al ~/forge-suite/node_modules ./node_modules (hardlink clone; a SYMLINK fails: Turbopack rejects "points out of the filesystem root"). Only valid while package-lock.json is unchanged vs the source tree.
  4. source ~/.forge-secrets/creatortrack-auth.env; NODE_ENV=production npm run build, then smoke npm run start -- -p 3211 and check /login + /api/auth/providers = 200.
  5. Swap: systemctl stop creatortrack-prod; mv ~/forge-suite/.next ~/forge-suite/.next.bak-<date>; mv worktree/.next ~/forge-suite/.next; systemctl start creatortrack-prod. Works because next start serves only distDir + public/; confirm next.config.ts/proxy.ts/public are unchanged between the running tree and the merged SHA first.
  6. Verify https://app.creatortrack.ai/login = 200, then git worktree remove --force the deploy dir. Rollback = swap .next.bak-<date> back and restart.

Gotchas found while testing

  • The mobile cold-start menu, view-tab back stack, and quick-note focus chain live in components/workspace/MobileChrome.tsx + MobileNav.tsx; a query-only ?view= navigation does NOT re-render MobileChromeProvider, so any location tracking there must be fed from MobileNav's useSearchParams effect (see recordLocation).
  • Menu (components/ui/index.tsx) used to steal focus on every render via an inline callback ref; keep its focus mount-only or menu onSelect handlers that move focus (iOS keyboard raise) break again.