spec(SD-0002 §2): solution proposal — canonical CSV, Shopify dialect, upsert + preview-confirm
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -226,7 +226,79 @@ Scenario: BUC-4 — The catalog leaves whole, on demand
|
||||
|
||||
## 2. Solution Proposal
|
||||
|
||||
*(not yet authored — next in the section-at-a-time loop)*
|
||||
**Build software:** CSV file import/export in the storefront admin — a new
|
||||
**Products** surface where a merchant uploads a CSV to add and update products
|
||||
in bulk, and downloads a CSV of the full catalog at any time.
|
||||
|
||||
**The shape of it:**
|
||||
|
||||
- **One canonical CSV format**, Shopify-flavored: one row per variant,
|
||||
consecutive rows sharing a `Handle` form one product (with its options,
|
||||
variants, and images). The column set is a deliberate superset of Shopify's
|
||||
product CSV — adding component columns (the kits seam, #15), volume,
|
||||
cost/tax fields — so a Shopify export is structurally familiar and our
|
||||
format never needs to churn when siblings arrive. The full column
|
||||
specification is §6.
|
||||
- **Two accepted dialects, auto-detected:** the canonical format, and
|
||||
Shopify's own product-CSV export (mapped onto canonical at the boundary).
|
||||
The header row identifies the dialect; the merchant never picks from a
|
||||
menu. This is the migrating merchant's path (BUC-1): their existing export
|
||||
imports directly.
|
||||
- **Import is upsert-only.** A row whose `Handle` is new creates a product; a
|
||||
known `Handle` updates it (variants matched by option-value combination).
|
||||
Nothing is ever deleted by an import — the mechanism is non-destructive by
|
||||
construction, so a partial file can never silently destroy catalog
|
||||
(BUC-2's safety, structurally).
|
||||
- **Validate-all → preview → confirm.** The whole file is validated and
|
||||
diffed against the catalog before anything is written. The merchant sees a
|
||||
summary — N products to add, M to update, K rows in error — and can drill
|
||||
into any record to see exactly which fields will change and to what.
|
||||
Nothing applies until they confirm; confirming applies the valid records
|
||||
and leaves the error rows listed, unapplied, and actionable (BUC-1a,
|
||||
BUC-2). Unrecognized columns are warned about in the preview and ignored,
|
||||
never silently dropped.
|
||||
- **Synchronous, with a stated capacity** of ~5,000 rows per file. No job
|
||||
queue in the MVP; the design names the async seam for when catalogs
|
||||
outgrow it (§6.9). One deliberate exception rides that seam's first rail:
|
||||
**images**.
|
||||
- **Images are fetched and hosted.** `Image Src` URLs are downloaded into
|
||||
platform object storage after the catalog rows commit, with renditions
|
||||
(thumbnail / card / detail) generated at fetch. Images that can't be
|
||||
fetched, aren't images, or fall below the resolution bar are **rejected**
|
||||
(the product shows a placeholder), with the outcome reported per image.
|
||||
The catalog is self-contained: exports reference our hosted copies, and
|
||||
the storefront never depends on a third-party host staying alive.
|
||||
- **Imports are first-class records.** Every import run is kept — file name,
|
||||
dialect detected, who ran it, add/update/error counts, image-fetch
|
||||
outcomes — with a detail view the merchant can leave and return to
|
||||
(the post-commit image phase reports there and on the Products page).
|
||||
- **Export is one gesture:** the complete catalog (optionally filtered by
|
||||
status) as a canonical CSV. Export → re-import is lossless and idempotent —
|
||||
the acceptance bar from #13 and BUC-4's round-trip guarantee.
|
||||
|
||||
**Why this approach.** CSV is the medium merchant catalogs already live in:
|
||||
every platform exports it, every spreadsheet tool speaks it, and the
|
||||
migrating merchant (the sharpest pain, PP-2) holds one today. Accepting
|
||||
Shopify's dialect directly converts the largest migration population's
|
||||
existing artifact into a working catalog with zero transformation effort.
|
||||
Upsert-only plus preview-confirm makes a powerful bulk mechanism safe to hand
|
||||
to a non-technical merchant: the destructive operations simply don't exist,
|
||||
and every change is consented to with full knowledge (OHM: consent & agency).
|
||||
|
||||
**Alternatives weighed** (detail in §6.7): a per-item editing UI first
|
||||
(rejected — Epic #12's explicit boundary, and it does nothing for migration);
|
||||
integration APIs / direct platform connectors (rejected — heavy, narrow, and
|
||||
premature before the catalog model exists); accepting spreadsheet formats
|
||||
(XLSX) (rejected for MVP — CSV covers the actual artifacts merchants hold;
|
||||
XLSX is an adapter behind the same boundary later); do-nothing / concierge
|
||||
data entry by the operator (rejected — doesn't scale past a demo and builds
|
||||
no product capability).
|
||||
|
||||
**Solution-specific non-goals:** no deletion semantics of any kind in the
|
||||
CSV; no scheduled/automated re-import; no foreign dialects beyond Shopify's
|
||||
product CSV in the MVP; no kit *semantics* (the format carries the columns;
|
||||
#15 defines their meaning); no image editing/cropping — the platform hosts
|
||||
what the merchant's URLs provide, or rejects it.
|
||||
|
||||
## 3. Product Personas
|
||||
|
||||
|
||||
Reference in New Issue
Block a user