Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5.0 KiB
FlatRender V2 — Session Handoff & Gotchas
Context captured 2026-06-05 so it survives a Claude-account/machine change. The
~/.claudememory 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), NOTlocalhost. - Gateway:
:8088. JWT secret + service creds live in.env.v2. - DB: single Postgres
flatrender, one schema per service (identity,content,studio,render,file, …). Userpostgres. - DB migrations:
backend/db/migrations/NN_*.sql, applied once byscripts/init-db.shon 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)
-
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 IP172.28.144.1, ordocker exec <container> wget -qO- http://<svc>:<port>. -
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 context →crypto.randomUUID,crypto.subtle, clipboard, etc. are undefined. NEVER call them in client code — usesrc/lib/uuid.tsuuid()(falls back tocrypto.getRandomValues). This silently broke the entire studio editor (crypto.randomUUID is not a function). -
Studio service binds camelCase JSON (no snake_case naming policy, unlike identity/content which use
SnakeCaseLower). Frontend→studio request bodies MUST be camelCase (originalProjectId, notoriginal_project_id) or fields drop to defaults (Guid.Empty). Studio responses are camelCase too. -
EF Core global query filters (
HasQueryFilter(DeletedAt==null)) require.IgnoreQueryFilters()to see/revive soft-deleted rows (bit the AEP import apply). -
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+ registryAppStates) 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.goParseNamesreadsfrl_/frd_names from the .aep RIFX directly; no AE).
What this session built (commits 6e5efbd → 5b2617d)
- 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;Avatarprimitive;getNavUser(). - Template detail page wired to real content (
fetchProject(slug); was hardcoded demo catalog → 404'd). - "Use template" works end-to-end:
StudioService.CreateProjectAsyncdeep-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/projectsresolves 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").