Files
flatrender/docs/SESSION_HANDOFF.md
T
2026-06-05 10:55:02 +03:30

5.0 KiB

FlatRender V2 — Session Handoff & Gotchas

Context captured 2026-06-05 so it survives a Claude-account/machine change. The ~/.claude memory is machine-local; this file is the portable copy.

How to run (V2 stack)

# Backend services + infra (Postgres + MinIO) — V2 compose, NOT the default docker-compose.yml
docker compose -f docker-compose.v2.yml --env-file .env.v2 up -d
# Rebuild one service after a code change:
docker compose -f docker-compose.v2.yml --env-file .env.v2 build <svc> && \
docker compose -f docker-compose.v2.yml --env-file .env.v2 up -d <svc>
# Services: identity-svc, content-svc, file-svc, studio-svc, render-svc, notification-svc, gateway, frontend
  • Open the app at http://172.28.144.1:3000 (the host LAN IP), NOT localhost.
  • Gateway: :8088. JWT secret + service creds live in .env.v2.
  • DB: single Postgres flatrender, one schema per service (identity, content, studio, render, file, …). User postgres.
  • DB migrations: backend/db/migrations/NN_*.sql, applied once by scripts/init-db.sh on first volume creation. New SQL files must be applied manually: docker exec fr2-postgres psql -U postgres -d flatrender -f ... (or inline -c).

⚠️ Critical gotchas (these have each cost hours)

  1. Localhost is VPN-hijacked. EonVPN intercepts 127.0.0.1:*. Curl/loopback to localhost returns junk/000 even when the app is up. Use the LAN IP 172.28.144.1, or docker exec <container> wget -qO- http://<svc>:<port>.

  2. Non-secure browser context. Because the app is served over http://172.28.144.1 (plain HTTP, non-localhost), the browser is a non-secure contextcrypto.randomUUID, crypto.subtle, clipboard, etc. are undefined. NEVER call them in client code — use src/lib/uuid.ts uuid() (falls back to crypto.getRandomValues). This silently broke the entire studio editor (crypto.randomUUID is not a function).

  3. Studio service binds camelCase JSON (no snake_case naming policy, unlike identity/content which use SnakeCaseLower). Frontend→studio request bodies MUST be camelCase (originalProjectId, not original_project_id) or fields drop to defaults (Guid.Empty). Studio responses are camelCase too.

  4. EF Core global query filters (HasQueryFilter(DeletedAt==null)) require .IgnoreQueryFilters() to see/revive soft-deleted rows (bit the AEP import apply).

  5. AE automation runs on a Windows node via node-agent.exe (PULL model: agent dials render-svc with HMAC). Before each AE launch the agent kills stale AE processes + clears crash/Safe-Mode markers (SCRPriorState.json + registry AppStates) and launches AE with the project as an arg (bypasses the Home screen). Heavy expression-driven AEPs take >10min to open → FIX scans are now binary-only (services/render/internal/aep/parse.go ParseNames reads frl_/frd_ names from the .aep RIFX directly; no AE).

What this session built (commits 6e5efbd5b2617d)

  • AE scan hardening: binary FIX scanner (no AE, never hangs); kill stale AE + clear crash dialog before each launch.
  • Profile = data-collection surface (for future AI video gen, NO resume builder): full editable profile (avatar upload + slogan/about/company/website/country/birthdate/gender), /api/profile + user-scoped /api/profile/upload. Identity DTOs widened (no migration — columns existed).
  • Role-aware nav: UserMenu (avatar + dropdown; admins get Admin Panel link) replaces Sign-In when logged in; real avatars in dashboard sidebar + admin shell; Avatar primitive; getNavUser().
  • Template detail page wired to real content (fetchProject(slug); was hardcoded demo catalog → 404'd).
  • "Use template" works end-to-end: StudioService.CreateProjectAsync deep-copies the content template scene graph (scenes + content elements + scene colors + shared colors) into the editable studio project via one atomic cross-schema SQL copy (enum cols cast ::text; temp _scene_map). /api/projects resolves container slug → published variant project. Aspect-ratio picker (16:9/1:1/9:16) on the detail page drives which variant is copied.

Known follow-ups (not done)

  • Scene-graph copy skips repeater children, characters, color-presets (scenes + fields + colors ARE copied).
  • Admin can't edit other users' full profiles yet (self-edit works for everyone).
  • Test the studio editor itself once inside (large Konva surface — not exhaustively exercised).

Debugging client-side behavior

No Playwright/Puppeteer in the repo. To reproduce browser issues headlessly: npm i puppeteer-core in a temp dir, launch the user's Chrome (C:\Program Files\Google\Chrome\Application\chrome.exe), set the auth cookie via page.setCookie({name:'fr_access', value:<JWT>, url:'http://172.28.144.1:3000'}), and listen on page.on('pageerror') / console. Mint a test admin JWT with the .env.v2 JWT_SECRET (HS256; claims sub=real user id, tenant_id, is_admin:"true", role:"Admin", iss:"flatrender-identity", aud:"flatrender").