docs: finish Gate A contradiction patches

Align PRD/README/CONTENT-WOO/DATA-MODEL/OPENAPI/DEPLOYMENT with AGENTS.md
and the POC review package: hybrid client SoT, bdft without /12, server AES
creds, woo_create_status draft|publish with SLAB-UAT-* firebreak, deploy smoke
and health path /api/health.
This commit is contained in:
2026-09-01 03:59:46 +00:00
parent 457711bd78
commit 4ec478f383
6 changed files with 68 additions and 47 deletions
+7 -5
View File
@@ -92,7 +92,7 @@ Failure → `502 woo_error`; previous cache retained (never delete-then-fail).
{
"name": "{title}",
"type": "simple",
"status": "pending", // test-target decision: NEVER "publish" automatically
"status": "{woo_create_status}", // draft | publish; default draft; SLAB-UAT-* forced draft
"sku": "{sku}",
"regular_price": "{price}", // 2 dp string, e.g. "2730.00"
"description": "{description}",
@@ -115,9 +115,11 @@ For reliability the server:
2. Reference those `source_url` values in `images` (≤5, per PRD 1–5 inventory photos).
3. Calibration photos are excluded (FR2).
**Status = `pending`** by default (test-target decision: test products must never go
live without human action). The Settings key `woo_publish_status` (default `pending`)
controls this; Ty flips it to `publish` only when intentionally going live.
**Status** comes from Settings key **`woo_create_status`** (`draft` | `publish`, default
**`draft`**). UAT on PROD uses Woo **draft** plus SKU prefix `SLAB-UAT-*` (hard rule:
`SLAB-UAT-*` always creates as Woo draft even if Settings say publish). Flip to
`publish` only for intentional live inventory after Ty review. Do not conflate with
slab lifecycle status `published` (means Woo create succeeded locally).
### 2.5 Dedupe & idempotency (FR24a)
Before create: `GET /products?sku={sku}`.
@@ -141,7 +143,7 @@ Before create: `GET /products?sku={sku}`.
3. (re)sync taxonomy if cache older than 1h → best-effort; use existing cache on fail
4. resolve category/tags/attributes (auto-assign + overrides)
5. upload normalized inventory images → media → source_urls
6. POST /products (status=pending) → woo_product_id
6. POST /products (status=woo_create_status) → woo_product_id
7. write sync_log(success), set slab published, purge images
on any failure at 2–6: write sync_log(failed), slab=failed, (images retained for retry)
```
+1 -1
View File
@@ -179,7 +179,7 @@ Keys:
- `inference_base_url`, `inference_api_key`, `inference_model`
- `inference_enabled`, `content_llm_enabled`
- `brand_voice`, `geo_context`
- `publish_status` ('published' | 'draft')
- `woo_create_status` ('draft' | 'publish'), default `draft` — Woo product create status; not slab lifecycle
- `aspect_ratio` ('3:4'), `output_px` (1600), `output_px_min` (1600), `fill_target` (0.80)
- `user_sensitivity`, `user_edge_offset`, `user_feather`, `user_sheet_mode`
+8 -6
View File
@@ -2,6 +2,8 @@
Status: SPEC (deliverable #4) · 2026-08-24 · SlabUploader
Target: TyUBUMini at 192.168.1.201. Domain: `slab.tyubumini.local` (LAN/Tailscale
> Gate A freeze (2026-08-31): hybrid client owns measure/crop SoT. Do not scaffold a server ruler/pipeline as authoritative. Woo UAT = draft + SLAB-UAT-* on PROD.
only — Decision). Inference is NOT on .201; it's a remote configurable endpoint
(.202 or elsewhere).
@@ -39,7 +41,7 @@ SlabUploader/
└── backend/ # FastAPI app (Phase 0)
├── app/
│ ├── main.py
│ ├── pipeline/ # deterministic core (constants.py, ruler, geometry, widths, pricing, normalize)
│ ├── (no happy-path pipeline SoT here) # hybrid: TECH-SPEC modules live in frontend/ or shared pure TS; backend = store/Woo/inference/U2Net stub
│ ├── woo/ # Woo client, taxonomy, publish
│ ├── inference/ # vision + content wrappers (toggleable)
│ ├── prompts/ # call1.txt, call2.txt (shipped defaults)
@@ -146,12 +148,12 @@ provide `python -m app.security.rekey NEW_KEY` (reads old key from env
| Reset one slab | delete its photos dir + `UPDATE slabs SET status='draft'` (admin script) |
## 8. Smoke test (after every deploy)
1. `GET /api/health` → ok
2. Settings: Woo creds configured + `test-woo` ok
1. `GET /api/health` → ok (from phone over HTTPS once CA trust is proven)
2. Settings: Woo creds + `test-woo` ok; `woo_create_status=draft`; inference OFF for early gates
3. Create a slab → upload test photos (fixture set) → poll to `ready`
4. Verify bdft/price match the fixture's expected values (golden test)
5. Publish test slab → `published`, Woo product visible as **pending** in store admin
6. Delete/leave the pending test product as a staging artifact (never published)
4. Verify bdft/price match the fixture's expected values (golden test; bdft = sqft × thickness)
5. Publish test slab with SKU `SLAB-UAT-…` → slab may show local `published`; Woo product must be **draft**
6. Leave or delete the Woo draft UAT product (never customer-visible). Final live publish is a non-UAT SKU after Ty review.
## 9. Scaling path (not v1)
- Postgres when SQLite write contention appears (schema already portable).
+2 -2
View File
@@ -126,7 +126,7 @@ the call returns. WooCommerce is the authoritative source for `feat-*` definitio
"inference_model": "<model>", "inference_enabled": true,
"content_llm_enabled": false,
"brand_voice": "...", "geo_context": "...",
"publish_status": "published",
"woo_create_status": "draft",
"aspect_ratio": "3:4", "output_px": 1600, "output_px_min": 1600,
"fill_target": 0.80,
"user_sensitivity": 0.5, "user_edge_offset": 0, "user_feather": 1,
@@ -139,7 +139,7 @@ Secrets (keys) are never returned. Only a `*_configured` boolean.
## Endpoints
### Health & meta
- `GET /api/v1/health` → `{ "status":"ok", "version":"...", "woo_reachable": bool }`
- `GET /api/health` → `{ "status":"ok", "version":"...", "woo_reachable": bool }` (canonical deploy/smoke path; may also be exposed as `/api/v1/health`)
- `GET /api/v1/meta` → `{ "version":"...", "templates_configured": bool }`
### Slabs