Accumulated branch work that was uncommitted alongside the pair-badge feature in the prior commit. Captured as a single sweep commit so the branch can merge cleanly; future work should commit per-feature to avoid this.
Replace the substring-match `"not found" in error` line in
`import_undo` with an explicit `get_undo_entry` existence check
before calling `undo_import`. The handler now returns 404 only
when the undo row is structurally absent, mirroring the typed-
exception pattern (`ModuleNotFound`, `BundleNotFound`,
`CategoryNotFound`) used elsewhere in wp_api. A future engine
wording change can no longer silently degrade the 404 to 400.
Both reads share a single `db_session` so the existence check
and the destructive undo stay in one transaction context.
Add two new POST handlers in wp_api/import_export.py wrapping the
engine.importer.commit_import / undo_import functions from Task 13.
- /wp/api/import/commit: body {adds, replaces, renames}; 200 with
{ok, undo_entry_id, summary} on success; 400 on contract/DB errors.
- /wp/api/import/undo: body {undo_entry_id}; 200 with {ok: True} on
success; 404 on unknown entry; 400 on shape/other errors.
- Both guard request body via validate_body_size (5 MB cap).
- Engine returns undo_id; handler renames to undo_entry_id at the
HTTP boundary to keep the locked endpoint contract decoupled from
the engine field name.
- Legacy export_bundle + import_bundle + new export_build handlers
remain unchanged.
Wraps engine.exporter.build_export_payload behind an HTTP route so the
SPA can drive a 7-bucket export with picker-selected UUID sets. Body
shape uses 7 keys (bundle_uuids, wildcard_uuids, fixed_values_uuids,
combine_uuids, derivation_uuids, constraint_uuids, category_uuids);
each key is optional and defaults to []. Mis-typed UUIDs are silently
dropped by the exporter (cross-bucket isolation guarantee). Response
is the exporter payload returned directly, matching the legacy
/wp/api/export shape convention.
Pipelines never paid off as a separate module kind, so peel out:
- Engine: drop pipeline_handler, remove "pipeline" from valid module
types in repositories + schema parity.
- Manager: delete Pipelines/PipelineEditor views, PipelineSteps +
PipelineStepPicker components and their tests. Router, sidebar,
topbar, dashboard, TestRunner, ImportExport, resolver and
bundleSelection repointed off the removed routes/types.
- wp_api: drop pipeline branch from modules.py + import_export.py
(and its test).
In its place, add a unified library view:
- src/manager/views/AllItems.vue — modules + bundles in one filter
panel with kind multi-select (OR across the 6 kinds). Reachable
via the Dashboard "View all" link.
- ModuleListView grew the slots/props AllItems needs; BundleAddChild
+ Dashboard + ImportExport updated alongside.
Misc polish along the way: kind-icons / theme tokens / display-prefs
touch-ups, ContextWidget + DebugViewer + AssemblerHelper small fixes,
MockModuleCard + ModulePickerModal tweaks, _shared widget cleanup.