feat(backend): S0 foundation (schema + stdlib sqlite3 db factory + health/meta + JSON logs)
- backend/db/schema.sql: all 12 tables from DATA-MODEL.md (taxonomy empty) - backend/db: stdlib sqlite3 factory, WAL/FK/busy_timeout/synchronous pragmas, single locked connection, explicit SLAB_DB_PATH/SLAB_IMAGES_DIR - backend/app.py: /api/health (non-200 on storage not writable), /api/v1/meta, JSON logging with request-id threading + secret redaction, startup guards (SETTINGS-10 WOO_BASE_URL https, SETTINGS-25 SLAB_AES_KEY) - tests: schema-loads, health happy/failure, startup guards (TDD) - docs/contracts: add requirement-ID citations to 12 sections so check_requirements.py passes (pre-existing gate debt) Gates: check_requirements.py + check_coverage.py exit 0; pytest 5 passed
This commit is contained in:
@@ -75,7 +75,7 @@ There is no `412 validation_module_stale` path.
|
||||
Multipart create of a calibrated draft. Returns `201` with the slab at `status: "calibrated"`.
|
||||
Stores the client-sent derived numbers and never recomputes them. Auto-runs Call 1 only when
|
||||
`inference_enabled` is true; inferred values persist only at confidence ≥ 0.7. `409 duplicate_sku`
|
||||
if the SKU already exists.
|
||||
if the SKU already exists. Cites APP-20, CAPTURE-135, METADATA-45, PUBLISH-15.
|
||||
|
||||
`SlabCreate` fields:
|
||||
|
||||
@@ -116,7 +116,7 @@ Partial update of editable fields plus `client_rev`. Stores client-sent derived
|
||||
not recompute them. Checks run in order: `409 revision_conflict`, then `409 duplicate_sku` (SKU
|
||||
field actions `edit_sku` / `open_existing`), then `422 stale_field` (current options included).
|
||||
`status` becomes `ready` only when the full required set is present; it is server-derived and a
|
||||
client never sets it.
|
||||
client never sets it. Cites APP-20, REVIEW-40, PUBLISH-15, PUBLISH-20.
|
||||
|
||||
### `DELETE /api/v1/slabs/{id}`
|
||||
Soft delete of unpublished drafts only (sets `deleted_at`); `204`. Deleted rows are excluded from
|
||||
@@ -141,7 +141,7 @@ Runs Call 2 on user action only. Fresh request carrying the processed photos, th
|
||||
metadata, the primary and secondary wood categories, the parent-category path, the dimension fact
|
||||
block, and brand/geo context; no provider thread id and no raw Call 1 result. Requires
|
||||
`test-inference` `ok`. Returns `202`; the client polls. The model writes the long description only
|
||||
and never touches dimensions.
|
||||
and never touches dimensions. Cites METADATA-55, METADATA-65.
|
||||
|
||||
Call 1 result fields: `species_id`, `species_confidence`, `wood_category_ids`,
|
||||
`edge_type_term_id`, `figure_term_ids`, `figure_confidence`, `grade_term_id`, `grade_confidence`,
|
||||
@@ -158,7 +158,7 @@ Preconditions are the full ready set, else `422 unpublishable` with field keys.
|
||||
the ready set; look up the SKU and stop if present; refresh taxonomy when the last sync is over
|
||||
one hour old; resolve categories, tags, and attributes; upload the processed PNGs to Woo media;
|
||||
`POST /products` per `docs/contracts/WOO-API.md`; finalize. `SLAB-UAT-*` always creates a draft.
|
||||
Returns `202`; the client polls.
|
||||
Returns `202`; the client polls. Cites PUBLISH-5, PUBLISH-10, PUBLISH-15, PUBLISH-25.
|
||||
|
||||
- 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.
|
||||
@@ -187,6 +187,8 @@ One flat `price_per_bdft` per species leaf, no tiers.
|
||||
|
||||
## 10. Settings
|
||||
|
||||
Cites SETTINGS-15, SETTINGS-20, SETTINGS-25, SETTINGS-80, SETTINGS-85.
|
||||
|
||||
- `GET /api/v1/settings` → `SettingsView` with secrets masked.
|
||||
- `PUT /api/v1/settings` — partial update. `woo_base_url` is not writable; the server rejects the
|
||||
write. Woo credentials are write-only and stored AES-GCM. Inference base URL and key are
|
||||
|
||||
@@ -104,6 +104,8 @@ successful publish.
|
||||
|
||||
## 5. Taxonomy cache
|
||||
|
||||
Cites METADATA-5, SETTINGS-50, SETTINGS-51, SETTINGS-55.
|
||||
|
||||
- `woo_categories` — species and wood-category leaves only; parents group and are never assigned.
|
||||
- `woo_attributes` / `woo_attribute_terms` — exactly the five locked attributes Edge Type, Figure,
|
||||
Grade, Thickness, Moisture, with their terms.
|
||||
@@ -148,6 +150,8 @@ revision it used (`METADATA-66`).
|
||||
|
||||
## 8. `sync_log`
|
||||
|
||||
Cites PUBLISH-25, PUBLISH-30.
|
||||
|
||||
Append-only; never deleted on publish. Columns: `id`, `slab_id`, `woo_product_id`, `status`
|
||||
(`success` | `failed`), `payload_hash` (sha256 of the outbound payload), `message`, `created_at`.
|
||||
|
||||
@@ -158,5 +162,7 @@ Append-only audit. Columns: `id`, `slab_id`, `call` (1 | 2), `prompt_revision_id
|
||||
|
||||
## 10. Status transitions
|
||||
|
||||
Cites APP-5.
|
||||
|
||||
`draft` → `calibrated` → `ready` → `publishing` → `published`, with `failed` reachable from any
|
||||
step and retryable. `calibrated` is set when the draft uploads; `ready` requires the full set.
|
||||
|
||||
@@ -39,6 +39,8 @@ The interface is reachable on the trusted network only until it is authenticated
|
||||
|
||||
## 3. Call 1 — vision classification
|
||||
|
||||
Cites METADATA-35, METADATA-40, METADATA-45, METADATA-50.
|
||||
|
||||
**When.** Runs automatically after a calibrated draft uploads only when `inference_enabled` is
|
||||
true; also on demand or retry. With inference off it is skipped and the fields are filled by hand.
|
||||
|
||||
|
||||
@@ -11,10 +11,10 @@ Status: SPEC · 2026-09-18. Presentation spec for the mill-owner flow on phone a
|
||||
| CAPTURE-20, CAPTURE-25, CAPTURE-30 | photo intake and calibration choice |
|
||||
| CAPTURE-40, CAPTURE-41, CAPTURE-45, CAPTURE-50, CAPTURE-55 | sheet/sensitivity controls, overlay, retake |
|
||||
| CAPTURE-60, CAPTURE-65, CAPTURE-70, CAPTURE-80, CAPTURE-85, CAPTURE-90 | axis, entry, derived numbers |
|
||||
| CAPTURE-105, CAPTURE-135, CAPTURE-141, CAPTURE-145, CAPTURE-150, CAPTURE-155 | crop guard, upload, preview/controls, failure |
|
||||
| CAPTURE-105, CAPTURE-130, CAPTURE-135, CAPTURE-141, CAPTURE-145, CAPTURE-150, CAPTURE-155 | crop guard, lineup order, upload, preview/controls, failure |
|
||||
| METADATA-10, METADATA-15, METADATA-30 | required taxonomy fields and cardinality |
|
||||
| METADATA-45, METADATA-55, METADATA-110 | pre-fill, Generate text availability |
|
||||
| PUBLISH-10, PUBLISH-15, PUBLISH-20, PUBLISH-25, PUBLISH-30, PUBLISH-35, PUBLISH-36, PUBLISH-37, PUBLISH-38, PUBLISH-50 | publish outcomes and messaging |
|
||||
| PUBLISH-5, PUBLISH-10, PUBLISH-15, PUBLISH-20, PUBLISH-25, PUBLISH-30, PUBLISH-35, PUBLISH-36, PUBLISH-37, PUBLISH-38, PUBLISH-50 | publish sequence, outcomes and messaging |
|
||||
| REVIEW-5, REVIEW-10, REVIEW-15, REVIEW-20, REVIEW-25, REVIEW-30, REVIEW-40, REVIEW-45, REVIEW-50 | ready set, gating, fields, limits |
|
||||
| SETTINGS-65 | create-status default |
|
||||
|
||||
@@ -26,6 +26,8 @@ flow runs on a PC browser.
|
||||
|
||||
## 2. Capture
|
||||
|
||||
Cites CAPTURE-20, CAPTURE-25, CAPTURE-40, CAPTURE-130.
|
||||
|
||||
1. **Photos.** Take one or more photos; the first is top-down with the lens parallel to the broad
|
||||
face. The owner chooses which photo is the calibration photo.
|
||||
2. **Mask overlay and controls.** The app draws the mask on the source photo. The controls are
|
||||
@@ -47,6 +49,8 @@ undersized source never guess; the resolution is retake.
|
||||
|
||||
## 3. Review
|
||||
|
||||
Cites REVIEW-5, REVIEW-15, REVIEW-20, METADATA-45.
|
||||
|
||||
- **Vision pre-fill.** At or above the threshold (default 0.7) a field is pre-filled and shown
|
||||
with an "AI" badge; below it the field starts empty. The badge is presentation only and clears
|
||||
on edit.
|
||||
@@ -63,6 +67,8 @@ undersized source never guess; the resolution is retake.
|
||||
|
||||
## 4. Publish
|
||||
|
||||
Cites PUBLISH-5, PUBLISH-10, PUBLISH-15, PUBLISH-25.
|
||||
|
||||
- A normal SKU uses `woo_create_status` (default draft); a `SLAB-UAT-*` SKU always creates a draft.
|
||||
"Published" means the store create succeeded, not that it is live.
|
||||
- **Success.** The local draft and photos are gone; the store product reference is shown.
|
||||
|
||||
Reference in New Issue
Block a user