Add docs/CREATE.md as M3 SoT from Ty conversation (Woo attributes sync, ready-set use, create, OpenAI Settings dependency). Point AGENTS/PRODUCT here; mark main milestone splits obsolete for this branch.
5.7 KiB
Milestone 3 — Create
Builds on Milestones 1–2 (docs/CAPTURE.md, docs/PHOTOS.md).
Destination and field names also live in docs/PRODUCT.md.
Scope source of truth: this file and the Ty conversations that wrote it.
Task and milestone breakdowns on main (including older PRODUCT / IMPL-PLAN / CONTENT-WOO splits) are obsolete for M3. Do not cross-reference main for what M3 includes once this branch is the working set.
Goal
Phone path from Photos-ready device draft → store-synced Woo attributes filled and reviewed → WooCommerce product create (practice SKUs as draft) → clear device draft.
M3 also wires the OpenAI-compatible inference endpoint as a server dependency so inference ops can run when enabled. Create must still work with inference off.
Woo attributes
Locked name for the synced taxonomy package. WooCommerce is the source of truth; the app caches ids and never invents the lists.
Categories (product categories, leaf-only)
| Field | Cardinality | Notes |
|---|---|---|
| Species | exactly 1 required | Synced species leaves only; no hardcoded / fallback set |
| Wood category | 1+ required | Parents are grouping only; picks are leaves |
Attributes (exactly five locked Woo attributes)
| Attribute | Cardinality | Notes |
|---|---|---|
| Edge Type | 1 required | Term id from sync |
| Figure | 1+ required | Term ids from sync |
| Grade | 1+ required | Term ids from sync |
| Thickness | 1 required | Measured thickness rounded up into the store band |
| Moisture | 1 required | Default kiln-dried; user sets/keeps; never inferred |
v1: missing attributes are skipped, not created. Species, character, length, and free-text thickness are not product attributes.
Tags
| Tag prefix | Cardinality | Notes |
|---|---|---|
fig-* |
1+ required | Other Woo tags ignored |
feat-* |
0+ optional | Character / inclusions / voids / checks map onto existing feat tags only |
Listing facts beside taxonomy
- User: SKU, length, thickness (and app-computed widths / sqft / bdft from M1/M2)
- Price: propose
bdft × species $/bdftfrom pricing rules; user may override; missing rate → empty price - Copy: title / short title / description from templates (optional Generate text when inference is on; not required for ready)
Sync (Woo)
- FastAPI is the sole Woo client. Credentials never in the browser.
- Auth: WordPress application password for a dedicated low-privilege WP user (not Woo
ck_/cs_consumer keys). - Store URL:
WOO_BASE_URLfromdeploy/.env/ compose (https://only). Settings shows it read-only. Not a SQLite settings row. - Woo username + application password: Settings UI → AES-GCM in SQLite (
SLAB_AES_KEYenv). - Taxonomy sync pulls, in order: categories → tags (
fig-*/feat-*only) → attributes + terms (five locked). - Sync failure keeps the previous cache (never delete-then-fail). Stale picks show “no longer valid”; never silently swap.
Inference dependency
- OpenAI-compatible endpoint:
inference_base_url, API key, model in Settings (encrypted), not compose env. - Server proxies all inference calls.
- Feature-flagged. Create / ready path must pass with inference off (manual taxonomy + deterministic numbers + Woo draft).
- Vision may prefill taxonomy at ≥0.7 confidence when on; typed values always win; below threshold → leave empty.
Ready set (submission ready)
Review does not continue until the full ready set is filled. Species + one figure is not enough.
Required:
- ≥1 inventory PNG (from M2)
- SKU, length, thickness; widths / sqft / bdft present
- Species, ≥1 wood category, edge type, ≥1 figure, ≥1 grade, thickness band, moisture, ≥1
fig-*, price feat-*optional (0+)
Create
POSTproduct to Woo with categories, attributes, tags, price, copy, inventory PNG images.- Duplicate SKU (any store status) blocks create; no update path in this version.
SLAB-UAT-*always creates as Woo draft, even if Settings say publish.- Device draft ≠ Woo draft. After successful create, clear the device draft.
- Default create status from Settings
woo_create_status(draft|publish, defaultdraft), subject to the UAT force-draft rule.
Acceptance (done when)
Product state induced: overnight UAT app on ubudual5060 http://100.64.0.9:10881 (or the current M3 deploy of this branch), with Woo credentials and WOO_BASE_URL pointed at the intended store.
Evidence from that state:
- Taxonomy sync via application password retrieves Woo attributes into the app cache; pickers offer only synced ids.
- A Photos-ready slab can be filled to the full ready set using those synced lists (inference off is a required path).
- Create with
SLAB-UAT-*yields a WooCommerce draft product whose categories / attributes / tags / price / images match the reviewed ready set. - Duplicate SKU is blocked; device draft clears after success.
- Inference Settings accept an OpenAI-compatible base URL / key / model; create still succeeds with inference disabled.
Dishonest proxies (do not count as pass)
- Hardcoded or fixture taxonomy lists treated as “synced”
- Mock Woo client or in-process fake that never hit the real store
- Claiming ready / create green from unit tests alone without a real draft in the store
- Consumer-key auth instead of application password
- Inference “wired” only as dead config with no server proxy path, or create that requires inference on
- Touching
:10880(Ty Node/SvelteKit) or dumping work ontom2-ds/ doc-simplification branches
Out of scope (unless Ty expands M3 in chat)
- Full Assist UX beyond the OpenAI endpoint dependency and optional prefill rules above
- Creating new Woo attributes / terms / tags from the app
- Update-in-place of an existing store SKU
- Bulk create