Repository navigation
Fix section regeneration and workspace autosave ordering - #89
Conversation
Regenerating one Generate section set the full-generation loading flag, which unmounted every result and the toolbar until the call returned. It now tracks the regenerating section separately: only that card shows an overlay, and the other regenerate buttons and the form wait for it, so two regenerations cannot merge over each other. Crossfire and Sparring workspace autosaves fired an unordered RPC on every change. A slower, older save could land last and store shorter progress. A small queue now keeps one save in flight and sends only the newest payload per request ID, so a finished round's last save survives the next round starting. Also reuses useOnlineStatus in four components that rebuilt it, and replaces five copied Select blocks in GenerateForm with a local helper. Adds the gen-regenerate verify recipe. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CNnE2EyywE54QHAFuAFZr5
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reachedEnable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. Next included review available in 34 minutes. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Free Run ID: 📒 Files selected for processing (22)
Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Essentials by visiting https://app.coderabbit.ai/settings/billing. Comment |
|
@coderabbitai review |
|
Codex review found two ways a pending regeneration could overwrite a newer case. Leaving Generate and coming back reset the page-local in-flight state, so another generation could start and the older callback would then replace its result. And Undo, now reachable while a section regenerates, was reverted when the section came back. The regenerating section now lives in the session store (not persisted), so it survives a remount. A regeneration is dropped if the case changed since it started, and Undo is disabled while one runs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CNnE2EyywE54QHAFuAFZr5
|
CodeRabbit was rate-limited, so this PR was reviewed with Codex (
Rechecked locally at d393781: lint, typecheck and build pass, and the unit suite passes (118 files, 1218 tests). |
|
Codex re-review of d393781 ( |
Fixes the four findings from the ultrareview of the UI code.
Bugs
Regenerating one Generate section blanked the whole result.
handleRegenerateSectionsetgenerateLoading, the flag behind the full-page "generating case" screen. So clicking a section's Regenerate button unmounted every section and the Export/Save/Discuss toolbar until the call returned. The page now tracksregeneratingSectionon its own. Only thatSectionCardshows an overlay (Regenerating <section>…, translated into en/es/hu). The other regenerate buttons and the form's submit button wait for it to finish, because each regeneration merges into the result it started from, and two at once would overwrite each other.Crossfire and Sparring workspace autosaves could store older progress. Every state change, so every keystroke in Crossfire setup, fired an unordered
save_workspace_artifactRPC for the same request ID. The RPC overwrites the row with whatever arrives, so a slower, older save could land last. The newcreateArtifactSaveQueue(src/lib/workspace/artifact-save-queue.ts) keeps one save in flight and holds only the newest payload per request ID. A finished round's finalcompletesave is kept when the next round starts. A failed save is logged and doesn't stall the queue, and it's no longer an unhandled rejection. The fix is client-only; it needs no migration or Edge Function deploy.Cleanups
OfflineIndicator,SparringSetup,SparringRoundandSparringPagenow useuseOnlineStatus()instead of their own listeners. The hook now reads the event type (as the copies did) and guards a missingnavigator.SparringPagekeeps its retry-on-reconnect behavior through an effect onisOnline.GenerateForm's five copiedSelectblocks are now a localOptionSelecthelper. The rendered labels and values are unchanged.Verification (local, on this commit's tree)
GeneratePage.test.tsx("keeps the results on screen while one section regenerates"),CrossfirePage.test.tsx(workspace autosave fired 4 concurrent saves before the fix, 1 after),artifact-save-queue.test.ts(ordering, coalescing, per-request flush, failure recovery), andGenerateResultsRegenerate.test.tsx(overlay on the right card, buttons disabled).npm run lint,npm run typecheck,npm run docs:checkandnpm run buildpass.npm test -- --coveragepasses: 118 files, 1216 tests.npm run test:e2e(desktop and mobile Chromium): 249 passed, 6 skipped, 1 flaky (navigation-performancecold-route timing on desktop, passed on retry; unrelated to these files).drive recipes/case-generationpassed 14 of 14 on desktop-chromium and mobile-chromium. That includes the newgen-regeneraterecipe, which holds the regenerate request and checks that only the Arguments overlay shows while the thesis and toolbar stay visible. I also rangen-regenerateagainst the oldGeneratePage.tsx, and it failed at the overlay check as expected.VITE_COLLABORATION_URLunset) and the verify stack doesn't run it, so the unit and page tests are the evidence. No database gate was run because nothing undersupabase/changed.🤖 Generated with Claude Code
https://claude.ai/code/session_01CNnE2EyywE54QHAFuAFZr5