merge issue-89-metadata-lock → main (Create-string model, #89/#90)

Drop the metadata_locked column + "Save and lock" UI end-to-end. The
review endpoint now builds the deterministic title/short_description on
every call; the owner's Create title / Create short desc buttons fire
the build and write the result (force-overwrite contract). commitReview
auto-fills only empty fields (no owner-clobber) and folds the
deterministic copy into its single PUT (kills the client_rev 409
cascade).

Taken wholesale from the branch: photo strip, wood primary/secondary,
server-side thickness band (hidden from UI, passed to Woo on publish),
and fixes #80/#82/#83/#84.

- backend: remove metadata_locked from schema.sql, db sentinels,
  slabs.py client fields/exposure, review.py lock action; review
  always computes title/short_desc
- frontend: slabs.ts + Review.svelte drop the lock model, add
  Create-string workflow + wood primary + photo strip
- e2e: m3-create + review-photo-strip rewritten for the Create-string
  contract; thickness-band test asserts absence (per #90)
- deploy: recreate LAN binds (override-m3.yml was absent); verify
  metadata_locked gone, review builds title, PUT persists

Gates: backend 117/117, unit 88/88, tsc clean, e2e 6/6 (m3-create +
photo-strip). Live UAT verified at 192.168.1.202:10881.
This commit is contained in:
Ty
2026-09-21 11:54:48 -07:00
parent e5acef4c9b
commit 1a50fad0a5
11 changed files with 234 additions and 314 deletions
+25
View File
@@ -51,3 +51,28 @@ Do not put a host name in the product spec.
- Live verification: served HTML and bundle contain zero occurrences of "Thickness band" or "set from the measurement".
- Sample data unchanged (still 25 slabs post-recreate).
- All gates (unit, build, requirements, coverage, m3-create e2e) pass.
### 2026-09-21 11:52 PDT — merge `issue-89-metadata-lock` → main (Create-string model)
- Source: branch `work/merge-89-90` (base `origin/issue-89-metadata-lock` + Create-string re-applied).
`matches HEAD`: **no** — staged from the uncommitted working tree (local sync; Gitea push not
attempted this round). 9 files changed: Review.svelte, slabs.ts, review.py, slabs.py, schema.sql,
db/__init__.py, test_review.py, m3-create.spec.ts, review-photo-strip.spec.ts.
- Model change: `metadata_locked` DB column + "Save and lock" UI **dropped end-to-end**. The
deterministic title/short_description are now built by the review endpoint on every call; the
owner's **Create title / Create short desc** buttons fire the build and write the result
(overwrite contract). `commitReview` auto-fills only empty fields (no owner-clobber); `createTitle`
is the explicit force-overwrite. Photo strip, wood primary/secondary, and server-side thickness
band (item: not shown in UI, passed to Woo on publish) all taken from the branch.
- LAN binds: `deploy/override-m3.yml` was absent from disk; the live stack's 10881/10882 LAN binds
were re-created by editing `deploy/docker-compose.yml` ports in-place (loopback 18082/18083 from
`.env` + `0.0.0.0:10881`/`0.0.0.0:10882`), then `down --remove-orphans` + `up -d` (no `-v`).
- Bundle: `assets/index-YPAqx609.js` (new; contains `create-title`). API `/api/health`
`woo_reachable:true`.
- Sample data preserved: **yes** — 34 slabs before/after.
- Live verification (LAN URL, real DB): `slabs` table has **no** `metadata_locked` column;
`slab_photos.role` present. `POST /review` on slab `ec4088da…` → `title:'Curl Black Walnut Slab'`,
`ready:True`. `PUT` title persisted (rev 1→2) then restored (original sample value intact, rev 3).
- Not exercised live: the full browser Create-button click (verified via in-repo Playwright 6/6
m3-create + review-photo-strip; the endpoint + PUT path are proven live above). Woo publish path
not exercised this round.