feat(api,ui): showcase-completion E6 — export bundle mvp (#412)#419
Conversation
POST /demo/workspaces/{id}/export writes a checksum-validated bundle
(manifest.json + scenario-plan snapshots + sha256sum-compatible
checksums.sha256) under artifacts/showcase/<workspace_id>/, validating
every checksum before returning. Soft references resolve over in-process
HTTP; model artifacts are referenced (uri + registry hash + live verify),
never copied. Dangling refs are reported, not fatal; 404 missing, 409
while running, deterministic overwrite on re-export. Stateless: no
migration, no DB writes. Traversal guard + chunked sha256 mirror
registry/storage.py (pattern, not import).
Per-row Export button (between Replay and the actions menu) calls
POST /demo/workspaces/{id}/export via a new useExportWorkspace mutation.
Non-destructive, so no confirmation dialog; success toast shows the
bundle path, file count, checksum state, and any unresolved-reference
count; failure surfaces the problem-details message. Self-contained
block to survive an E2 row restyle. Adds WorkspaceExportResult /
ExportFileEntry / UnresolvedReference types.
API_CONTRACTS: add the POST /demo/workspaces/{id}/export row. RUNBOOKS:
add the export-semantics bullet to the showcase-workspace section
(overwrite-on-re-export, dangling-ref warnings, gitignored artifacts/,
sha256sum -c verification) and move export bundles off the out-of-scope
list (import/restore remains out).
There was a problem hiding this comment.
Sorry @w7-mgfcode, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
|
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 E6 of the showcase-completion initiative (umbrella #406, epic #412): an export-only bundle surface for saved showcase workspaces.
POST /demo/workspaces/{workspace_id}/exportwrites a self-describing, checksum-validated bundle underartifacts/showcase/<workspace_id>/:The Saved-workspaces panel gains a per-row Export button. Import/restore is explicitly out of scope for this umbrella; model artifacts are referenced (uri + registry hash + live verify), never copied. No migration, no DB writes — export is stateless and re-runnable.
What's in scope
app/features/demo/(+ one Settings field + one.env.exampleline). Soft references (winning_run_id/v2_run_id/stale_alias_run_id/scenario_plan_ids) resolve over the in-processhttpx.ASGITransportsurface — no cross-slice imports.LocalFSProvider._resolve_path(resolve()+relative_to(root)), reimplemented in the slice;rmtreetarget is always the guarded resolution;workspace_idcomes from the DB row, never the raw path.sha256sum-compatible format, excludes itself; the endpoint re-reads + recomputes every hash before returning (validated).404missing,409whilestatus="running",500on disk failure. Dangling refs →unresolved_references(export still200). Re-export overwrites deterministically.Decisions (frozen)
One dir per
workspace_id; re-export = overwrite; references resolved over in-process HTTP; artifacts referenced not copied; stateless (no DB writes);failedexportable /running→409;checksums.sha256excludes itself; newSHOWCASE_EXPORT_ROOTsetting. No story slot written, noconfig_schema_versionbump (E1 Decision 5).Validation
ruff+ruff format·mypy --strict(0) ·pyright --strict(0 errors)pytest -m "not integration"— 2112 passed (incl. newtest_export.py+ route 404/409/200)tsc -bno NEW errors vsdevbaselinesha256sum -c checksums.sha256OK · real-HTTP export OK · Export button dogfooded in a browser (success toast verified)Files
New:
app/features/demo/export.py,app/features/demo/tests/test_export.pyModified:
routes.py,schemas.py,app/core/config.py,.env.example,tests/test_routes.py,frontend/{WorkspacePanel.tsx, WorkspacePanel.test.tsx, hooks/use-workspaces.ts, types/api.ts},docs/_base/{API_CONTRACTS.md, RUNBOOKS.md}Closes #412.
🤖 Generated with Claude Code