diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index b11ce52..7e710e9 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -1,6 +1,6 @@ # Implementable compose for SlabUploader. # Phase 0 deliverable targets: frontend/Dockerfile, backend/Dockerfile, -# backend/app/prompts/, and deploy/.env.example are not yet in the tree on +# and deploy/.env.example are not yet in the tree on # docs-only main. This file pins their paths so scaffolding does not invent them. # From repo root (after those scaffolds exist): # cp deploy/.env.example deploy/.env && chmod 600 deploy/.env @@ -34,7 +34,6 @@ services: volumes: - slab_db:/data - slab_images:/images - - ../backend/app/prompts:/app/prompts:ro ports: ["127.0.0.1:${FASTAPI_PORT:-18081}:8000"] mem_limit: 2g restart: unless-stopped diff --git a/docs/REQUIREMENTS.md b/docs/REQUIREMENTS.md index 6e69bd7..2573f5f 100644 --- a/docs/REQUIREMENTS.md +++ b/docs/REQUIREMENTS.md @@ -102,7 +102,7 @@ Sources reconciled 2026-09-18 from the current branch docs plus the `pre-simplif | PUBLISH-10 | SKUs matching SLAB-UAT-* always create a WooCommerce draft regardless of the create-status setting. | M3 | — | | PUBLISH-15 | A duplicate SKU blocks create and offers edit-SKU or open-existing; this version has no update path. | M3 | — | | PUBLISH-20 | A stale value on submit is a field-level error that shows the current options and never a raw code. | M3 | — | -| PUBLISH-25 | On success the server sets woo_product_id, purges photos, deletes the local slab row, and clears the device draft; WooCommerce is the source of truth. | M3 | — | +| PUBLISH-25 | On success the server sets woo_product_id and returns it on the terminal poll, purges photos, discards the local working slab row, and clears the device draft; the app never deletes from WooCommerce; WooCommerce is the source of truth. | M3 | — | | PUBLISH-30 | On failure the submission attempt is marked failed, photos are retained, sync_log is written, and a plain message is shown on the affected field or action; retry works from the same screen. | M3 | — | | PUBLISH-31 | If image uploads succeed but the product POST fails, the orphaned WooCommerce media is left in place, the failure is logged, and a manual cleanup note is surfaced; this version does not auto-delete it. | M3 | — | | PUBLISH-35 | The owner never sees raw status codes, stack traces, or internal error codes. | M3 | — | diff --git a/docs/contracts/API.md b/docs/contracts/API.md index e7908fd..786d8a4 100644 --- a/docs/contracts/API.md +++ b/docs/contracts/API.md @@ -102,7 +102,9 @@ Returns `[Slab]`, most recent first. ### `GET /api/v1/slabs/{id}` Returns the `Slab`. Also the poll endpoint for inference and publish. The client backs off -(1s, 2s, 4s, cap 10s). +(1s, 2s, 4s, cap 10s). On publish success the terminal response carries `woo_product_id`; the +working row is then discarded, so a later GET may return `404`, which the client treats as +completion. ### `PUT /api/v1/slabs/{id}` Partial update of editable fields plus `client_rev`. Stores client-sent derived fields and does @@ -110,7 +112,8 @@ not recompute them. `409 revision_conflict`, `409 duplicate_sku` (SKU field acti `open_existing`), `422 stale_field` (current options included). ### `DELETE /api/v1/slabs/{id}` -Soft delete of unpublished drafts only; `204`. Published slabs cannot be deleted from the app. +Soft delete of unpublished drafts only (sets `deleted_at`); `204`. Deleted rows are excluded from +all GET responses. Published slabs cannot be deleted from the app. ## 5. Photos @@ -147,7 +150,8 @@ one hour old; resolve categories, tags, and attributes; upload the processed PNG `POST /products` per `docs/contracts/WOO-API.md`; finalize. `SLAB-UAT-*` always creates a draft. Returns `202`; the client polls. -- Success: `woo_product_id` set, photos purged, local slab row deleted, device draft cleared. +- Success: `woo_product_id` set and returned on the terminal poll, photos purged, the local working + slab row discarded, device draft cleared. Nothing is deleted from WooCommerce. - Failure: attempt marked failed, photos retained, `sync_log` written, plain message on the affected field or action, retry from the same screen. - Partial failure (media uploaded, product POST failed): orphaned media left, logged, manual diff --git a/docs/contracts/DATA-MODEL.md b/docs/contracts/DATA-MODEL.md index 2df3b03..5c8349d 100644 --- a/docs/contracts/DATA-MODEL.md +++ b/docs/contracts/DATA-MODEL.md @@ -27,8 +27,14 @@ Status: SPEC · 2026-09-18. Store: SQLite. - Multi-select taxonomy values are JSON arrays of Woo ids. - Secrets are stored as `value_enc = nonce(12) || ciphertext`, AES-GCM; the master key is the env `SLAB_AES_KEY` and is never in the DB. -- The local slab row is deleted on successful publish; `sync_log` and `inference_log` are - append-only and retained. +- On successful publish the local working slab row is discarded (photos purged, device draft + cleared); `sync_log` and `inference_log` are append-only and retained. Nothing is deleted from + WooCommerce. +- Soft delete sets `deleted_at` (text, null until then) on unpublished drafts; deleted rows are + excluded from all GET responses. +- Photo bytes live in `slab_photos` BLOBs; the `/images` volume is not a second store. It holds a + health-probe file and short-lived staging for 1024 px Call-1 JPEGs and Woo media uploads, purged + after use. ## 2. `slabs` @@ -61,6 +67,7 @@ Status: SPEC · 2026-09-18. Store: SQLite. | `client_rev`, `server_rev` | int | default 1 | | `woo_product_id` | int | null until publish | | `published_at` | text | null until publish | +| `deleted_at` | text | null until soft-deleted; unpublished drafts only | | `created_at`, `updated_at` | text | UTC ISO-8601 | No `inference_thread_id` column exists; provider threads are not used.