Repository navigation
Fix Flowchart QA issues (T9: FC-01–06, PF-03) - #206
Conversation
FC-01: the canvas controls, minimap, attribution and edge labels follow the theme. On phones the minimap is hidden, the controls sit in a row under the canvas, and the toolbar shows icons only. The attribution moves to the top right. Node and badge colours pass 4.5:1 contrast. FC-02: edge labels follow the language, including charts saved with the old English labels, and the attribution link has a localized name. FC-03: starter node text is stored with its translation key and shown in the current language. Text the student writes is never translated. FC-04: "Build from current case" maps the thesis, contentions with evidence, predicted attacks and counters onto the canvas, from a case in the same debate. Switching debates puts the template back. Generate's import uses the same mapping and the same debate check, and a case restored by Undo is not sent to the Flowchart or written over a recorded row. The Save dialog asks for a flowchart title. FC-05: an empty node label or save title shows an inline message. FC-06: each new chart fits the canvas with padding, and the chart refits when the canvas width changes. PF-03: no Flowchart leak; the growth comes from the delayed Jam recorder iframe. Layout reads on the page now come from a ResizeObserver. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ℹ️ Recent review info
📝 Walkthrough
Note 🎁 Summarized by CodeRabbit Free
Comment |
…02, PF-04, PF-05, PF-06, PF-09) (#215) * Cache every public icon file for 30 days C3 (#199) added icon-1024.png and the 192/512/maskable manifest icons, which still fell back to revalidating on every request. The test now reads public/ so a new icon size can't miss the rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Load only the active locale and keep app-only code off public pages - Spanish and Hungarian strings are their own chunks, fetched when chosen; English stays in the entry as the default and fallback. The first render waits for the chosen language, and a later choice wins over one still loading. - AppLayout (header, navigation, debate dialogs) loads only under /app. mountApp starts the page chunk and the layout while the entry starts, instead of when React first reaches them. - The landing reveal is a CSS transition, so / no longer loads framer-motion's 118 KB chunk. - The session check and layout load show the route's skeleton instead of a full-screen spinner. - check-build-boundaries fails if the es/hu catalogs or AppLayout re-enter the entry or the landing, login, home, generate or attack graphs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Open the main app pages offline and keep each page's own HTML The build writes a precache list into sw.js from the Vite manifest: the shell's scripts and styles, the signed-in layout, Home, Library, History, Timer and Settings, the es/hu strings and Inter's Latin fonts. A missing manifest key fails the build. Offline, app routes get the precached app-shell.html (the paths vercel.json rewrites) and a public page gets only its own HTML, stored under its own path. Before, every navigation was stored as /index.html, so any route could come back as the last page visited. /auth/callback, Supabase paths and /_vercel/ stay network-only. Caches carry the build's id and the next build's worker deletes them. vite preview applies the vercel.json rewrites, so the offline test loads what production serves. The test's async waitForFunction calls passed at once without checking (Playwright treats the returned Promise as truthy); they now poll. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Hold Supabase reads while offline instead of retrying them Offline, supabase-js retried every failed read three more times, so opening Settings sent about 70 doomed requests in 30 seconds (user_roles four times, user_settings 18). REST, Functions and Storage reads now wait for the 'online' event and go out once; an abort still ends them. Writes fail at once as before, and Auth is left alone because auth-js holds its session lock during a user lookup. TanStack Query also starts with the browser's real online state, so a page opened offline pauses its queries instead of running them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Don't reload for a missing chunk while offline Choosing a language whose strings were never cached, offline, failed its import and triggered the stale-deploy reload, which without a service worker replaces the page with the browser's offline error. Offline the chunk is unreachable, not stale, so the error stands and the app keeps the current language. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Treat /expocit/sources as a public page offline, and always leave the startup shell /expocit/sources is prerendered and Vercel serves that file before the rewrite, so offline it now gets its own stored HTML instead of the shell (whose page chunk is not precached). vite preview serves prerendered pages before the rewrites too. The non-prerendered first render now also runs if waiting for the language rejects. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Disable Upgrade Now while offline and say why Checkout needs the network. Offline the button stays disabled with a short notice under it (one new string, pricingModal.offlineUpgrade, in all three catalogs) and re-enables on the 'online' event. Done here now that T4 (#207) has merged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Load every language before the flowchart opens T9 (#206) recognises flowchart starter text saved in any language by comparing it with each catalog. With Spanish and Hungarian loaded only on demand, a chart saved in Hungarian and opened in English kept its Hungarian starter text. The flowchart route's loader now fetches every catalog before the page renders. Only that page (and a hover prefetch of it) pays for them, and they are precached for offline. The flowchart tests now load through the route loader; without this change four of them fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Address review round 1: stop retries offline instead of holding reads - Offline Supabase reads are no longer held until 'online'. A held read kept the token of whoever started it and could replay after sign-out, and a browser that wrongly reports offline would never send it. Every request is now sent; one that fails while the browser is offline ends as an abort, which postgrest-js does not retry. TanStack Query is no longer seeded from navigator.onLine; failed queries refetch on 'online' instead. - A language chosen offline before its strings were cached is applied when the connection returns. - The first render waits at most 3 s for the language's strings. - The service worker's build id also covers the unhashed public files it serves cache-first (theme-init.js, icons), and an offline public page prefers the copy saved on the last visit over the one stored at install. - The landing page's code is precached with its HTML, so / opened offline is not replaced by the error page. - test:sw now visits /auth/callback before checking it is never cached, and checks the precached files sit in the install-time shell cache. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Address review round 2: load layout and page together after sign-in - After a client-side navigation into /app (sign-in, the callback), the page chunk now starts with the layout chunk instead of after it. - The offline no-retry rule also matches reads through the dev:preview staging proxy path. - hero-visual.jpg and placeholder.svg also feed the worker's build id. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Fixes the Flowchart issues from the 22 Oct 2026 QA report (batch T9). Most changes are in
src/pages/FlowchartPage.tsxand a newsrc/lib/flowchart.ts, which Generate's "Import to Flowchart" now uses as well. Rebased onmainat 508f243 (#205). There are no migrations and no Edge Function changes.Issues
FC-01: dark mode, phone layout, attribution
--card,--border,--accent,--muted-foreground), viasrc/index.css. In dark mode the control background was#fefefeand is nowrgb(29,40,57).sm(640px), the minimap is hidden. The controls move out of the canvas into a row of four 44px buttons underneath it, so they no longer sit over nodes./app/flowchartwent from 18 (dark) and 23 (light) failures to 0.FC-02: edge names
mainfrom Fix the 11 bugs from today's QA pass (H1, M1–M5, L1–L5) #184. On a main build, Hungarian read "Kapcsolat: A tézised → 1. érv", so the QA builds were older than that fix.ariaLabelConfig, which arrived in v12, so the node and edge keyboard help is still replaced through theLocalizedA11yDescriptionsadded in Fix the 11 bugs from today's QA pass (H1, M1–M5, L1–L5) #184.PF-03: heap growth on navigation laps
I could not reproduce a Flowchart leak. React Flow 11 injects no styles at runtime, and
reactflow/dist/style.cssis imported once at module level. CSS rules and<style>elements stay flat across laps.Setup: a local production build (
vite preview) with a stubbed session, Chromium driven over CDP, and GC forced twice before each reading. Each lap goes from/appto/app/flowchartand back.<style>recorder.jam.dev/capture, delayed by Delay Jam and align cache, CSP, and robots #196) loads part-way through the run. After that the Flowchart adds about 0.05 MB per lap, the same as History.ResizeObserverobjects before and after the laps. The new canvasResizeObserveris disconnected on unmount and when a chart is replaced.C3 (#199) left the forced reflows on this page for this batch. Adding a node now centres it from the viewport and the size the ResizeObserver reports, instead of
getBoundingClientRect, and Export uses the observed size instead ofoffsetWidth/offsetHeight.FC-03: starter text in the creation language
labelKey,labelNumber,descriptionKey) next to the text in the language they were made in. They are shown in the current language, so switching language updates them on the canvas.labelKey: nulland are never translated, even if they read "Argument 2".FC-04: build from the current case, Save placeholder
main; it was fixed here because this PR changeshandleUndo.FC-05: empty label or title did nothing
aria-invalid,aria-describedbyand focus on the field.FC-06: right-most node clipped at 375px
minZoomis 0.2 so a large built case can fit.Verification
npm run verify(local, 23 Oct, on the tree of head b3c60e6)GitHub Actions minutes are used up, so this is a local run, not CI.
test:sw: all offline checks trueNew and updated tests
src/test/lib/flowchart.test.ts:src/test/pages/FlowchartPage.test.tsx:src/test/pages/GeneratePage.test.tsx:In the browser (local production build, stubbed session)
/app/flowchart, run on the page's<main>element:mainat 6962616 (before Name controls, headings, and the toast region (AX-01, AX-05, AX-06, AX-08, AX-09) #200): onebutton-name, 23color-contrastin light and 18 in dark, oneheading-order.button-nameandheading-order. This PR fixedcolor-contrast.Screenshots are on the
pr-assets/t9-flowchartbranch, which is not for merging; delete it after merge.Dark mode canvas, before and after:
375px, dark HU and light EN, before and after:
After, more views: dark desktop HU, light desktop EN, dark 375 EN, light 375 HU:
Built from a case with five contentions and eight attacks (desktop), the same at 375px in Hungarian, the save validation, and a 1280px window shrunk to 375px:
verify-debatelab skill
New recipe
gen-flowchartinrecipes/case-generation.spec.ts: build from the debate's case, no node clipped, the edge name, then switch the interface to Hungarian and check that the app-written titles change while the case text stays the same.Updated
features/case-generation.mdand thefeatures/README.mdindex.Not run yet. Another worktree (T8) has held the shared Supabase lock all night, and the batch rules say to wait rather than take it. I will drive
recipes/case-generation(includinggen-flowchart) andrecipes/account(flow-edit) ondesktop-chromiumandmobile-chromiumas soon as the lock is free, and add the results here.Left open
agentic/replay/495abc…jsonstill targets the Save textbox by its old name "Node title...". The name has been "Title" since Name controls, headings, and the toast region (AX-01, AX-05, AX-06, AX-08, AX-09) #200. On replay this falls back to a model call rather than failing. It should be re-recorded on the next agentic run.main. Only loaded, imported or built charts reset.Review rounds
Codex is rate-limited tonight, so each round was one fresh-context Opus subagent reading the full diff against
main.role=toolbar, duplicate titles, Hungarian wording and test overlap. All fixed.minZoom0.2). The old-chart heuristic could translate new student text (now null keys). Counter matching was weak. A built case could be saved into another debate (now reset on switch). Lows on toast dismissal and evidence line breaks were fixed.keptAppText), and charts imported from Generate skipped the debate guard (now every chart records its debate). Lows on Undo scope, stale Undo toasts, the reset toast and filler-word matching were fixed. One finding was wrong: the recipe already runs in debate mode.main, where a regeneration after Undo overwrote a recorded row, was fixed because it sits in the same handler.restoredSnapshotflag and Save behaves as onmain. The import refusal wording was fixed.Migrations and Edge Functions
None. No migration files and no Edge Functions to deploy.
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes