feat(api,ui): showcase-completion E2 — safe replay & workspace lifecycle (#408)#415
Conversation
There was a problem hiding this comment.
Sorry @w7-mgfcode, your pull request is larger than the review limit of 150000 diff characters
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Implements epic #408 (umbrella #406) per
PRPs/PRP-showcase-completion-E2-safe-replay-lifecycle.md:buildReplayRequestis the single source for both the preview and the wire request). Areset=trueworkspace escalates to destructive copy + a destructive-styled "Replay & wipe database" button. No code path starts a replay without the dialog. This supersedes the E4 (feat(api,ui): showcase-workspace E4 — workspace restore/replay (list/load workspaces + replay through the run path) #393) "deliberately no confirm dialog" decision, as committed by feat(api,ui): showcase workspace completion — the forecastlab control story #406.replaybadge; the loaded view renders thereplayed_from_workspace_idancestor chain (depth-capped at 5, deleted ancestors render "(original deleted)" — never an error), ancestors clickable.q), show-archived toggle, allow-listed sort, clickable tag chips, pin toggle, per-row dropdown (pin / archive / edit details / delete), rename/notes/tags editor over the E1 PATCH endpoint.GET /demo/workspacesgainsq(name ILIKE), repeatedtags(JSONB containment),include_archived(default false — archived rows now hidden by default), allow-listedsort_by/sort_order(unknown → silent default, dimensions precedent); pinned rows always order first;totalrespects the active filters (scenarios precedent — shared_apply_filterson count + rows).DELETEs behind one confirmation; no new bulk endpoint (product-vision guardrail)./showcase/compare?a=&b=(frontend-only diff over two served details, mirroring run-compare): config diff, result diff with sign-only WAPE delta, created-objects presence matrix, lineage note, partial-run badges; bad ids degrade to the picker.GET /demo/workspaces/{id}/healthprobes the row's soft references in-process viahttpx.ASGITransport(thepipeline._Clientmechanism — no cross-slice imports): 2xx→alive, 404→dead, anything else→unknown (a probe never 500s the route). Loaded-workspace artifact cards get dead-link warnings + an alive/dead summary chip + a partial-run warning.CONTRACT(E1) reconciliation
All seven CONTRACT(E1) points reconciled against the merged #407 code with zero divergence — columns,
WorkspaceUpdateRequest, PATCH route, GET response fields,DemoRunRequest.replayed_from_workspace_id(+ frontend send),job_idsslot shape all matched the assumed names. One verify-or-add fallback fired: the frontendWorkspaceListItem/WorkspaceDetailTS types did not yet carry the E1 fields — added additively here.Deferral (Decision 1 of the PRP)
A replay-policy picker (exact / safe-keep / modified) is out of scope — replay stays verbatim. A "modified replay" already exists as Load → edit controls → Run; the confirm dialog carries a "Use Load instead" hint.
Validation
ruff check+format --check,mypy --strict,pyright --strict,pytest -m "not integration"— 2005 passed); demo integration suite green against real Postgres (30 passed, incl. new filter + health tests); strict-mode AST walker green.pnpm lintclean +pnpm test --rungreen (403 passed; 66 files).✕ 1 deadchip → confirmed replay records provenance and the replay badge → lineage strip renders the chain → pin/tags/notes round-trip → compare page renders config/result diff + lineage note → multi-select delete removed 2 metadata rows, created objects verified intact.