SLICE-5: products import spine — canonical CSV → preview → confirm (SD-0002 §7.2) #26

Merged
ben.stull merged 21 commits from worktree-slice-5-import-spine into main 2026-06-12 03:50:21 +00:00
Owner

Implements SD-0002 §7.2 SLICE-5 (anchor #13, epic #12): the products import spine, canonical dialect only, images stubbed.

Ships

  • products domain + §6.3 tables (migration 0002; images table present, fetch phase stubbed to no-op)
  • Canonical CSV codec (INV-18 caps), §6.5.1 row validation (INV-15 sanitization), diff engine with INV-11 fingerprint + apply plan
  • One-transaction confirm/apply (INV-10 upsert-only), import drafts/runs, TEL-1/2/6 telemetry
  • §6.4 endpoints: imports, draft records/confirm/cancel, runs, summary, sample.csv (DOC-3)
  • Admin Products section (§5.2–5.5): Products page + history, upload, preview with drill-in diffs (the BUC-2 consent gate), run detail; hash routing
  • First Playwright E2E suite: e2e_import_preview_confirm, e2e_import_errors_actionable, e2e_import_file_rejected, e2e_import_cancel_no_trace — all green
  • DOC-1 docs/OPERATIONS.md (RB-2 + ALR-2 gesture), DOC-4 docs/products-domain.md; version 0.5.0

DoD (§7.2): BUC-1/1a/2 canonical path ✓ · INV-10/11/13/14/15/18 enforced + tested (147 backend / 10 vitest / 4 E2E green) · TEL-1/2/6 emitting ✓ · ALR-2 gesture documented, run at PPE deploy ✓

Session: ecomm 0032. Export/round-trip = SLICE-6; images pipeline = SLICE-7; Shopify dialect = SLICE-8.

🤖 Generated with Claude Code

Implements SD-0002 §7.2 SLICE-5 (anchor #13, epic #12): the products import spine, canonical dialect only, images stubbed. **Ships** - `products` domain + §6.3 tables (migration 0002; images table present, fetch phase stubbed to no-op) - Canonical CSV codec (INV-18 caps), §6.5.1 row validation (INV-15 sanitization), diff engine with INV-11 fingerprint + apply plan - One-transaction confirm/apply (INV-10 upsert-only), import drafts/runs, TEL-1/2/6 telemetry - §6.4 endpoints: imports, draft records/confirm/cancel, runs, summary, sample.csv (DOC-3) - Admin Products section (§5.2–5.5): Products page + history, upload, preview with drill-in diffs (the BUC-2 consent gate), run detail; hash routing - First Playwright E2E suite: `e2e_import_preview_confirm`, `e2e_import_errors_actionable`, `e2e_import_file_rejected`, `e2e_import_cancel_no_trace` — all green - DOC-1 `docs/OPERATIONS.md` (RB-2 + ALR-2 gesture), DOC-4 `docs/products-domain.md`; version 0.5.0 **DoD (§7.2)**: BUC-1/1a/2 canonical path ✓ · INV-10/11/13/14/15/18 enforced + tested (147 backend / 10 vitest / 4 E2E green) · TEL-1/2/6 emitting ✓ · ALR-2 gesture documented, run at PPE deploy ✓ Session: ecomm 0032. Export/round-trip = SLICE-6; images pipeline = SLICE-7; Shopify dialect = SLICE-8. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ben.stull added 21 commits 2026-06-12 00:07:43 +00:00
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Also updates test_migrate_from_empty_applies_0001 → test_migrate_from_empty_applies_all
to assert both migrations apply on a fresh DB (mechanical consequence of adding 0002).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A Variant Position column previously produced a spurious update with a
false before:None (CatalogVariant keeps position as an attribute, not in
fields{}). Compare against the attribute, like images already do.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A blank Variant Position cell previewed position->null and aborted the
confirm transaction (variant.position is NOT NULL). Resolve the clear to
the variant's file order at diff time so preview and apply stay in
lockstep; carry file_order on VariantPlan instead of an identity-keyed
map; release the read snapshot before PreviewStale/NothingToApply.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
docs(products): operator guide (DOC-1) + domain notes (DOC-4); version 0.5.0
ci / check (push) Has been cancelled
ci / check (pull_request) Has been cancelled
2606fbf826
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ben.stull merged commit 011f4d5dc1 into main 2026-06-12 03:50:21 +00:00
Sign in to join this conversation.