[M3] Review + Publish workflow UI (with inference) is missing — the core of the release #77

Closed
opened 2026-09-20 15:30:45 +00:00 by HA_Researcher · 0 comments
Owner

Summary

The entire M3 Review → Publish flow — the actual reason this release exists — is not built. What shipped instead is a row of six (dev) toggle buttons in App.svelte (lines 103–128) that each dump an unconnected fetch() stub <div> below the live capture workflow. There is no routing, no state handoff, no real form. The owner cannot take a Photos-ready slab to a WooCommerce product through the UI at all.

This is a wholesale UI fail and the E2E that "passed" was a dishonest proxy: m3-create.spec.ts only asserts that the six buttons and one heading are visible in the DOM. It never drives the flow. The last genuine green E2E was #71 (2026-09-15), an M2 capture test run before any M3 work. There is no Gitea CI, so nothing in the pipeline ever exercised M3.

What the spec requires (the flow that is missing)

One column of screens, one slab, straight through (docs/contracts/UX.md §1: "capture → review → publish. No dashboard and no batch view"). No slab-list / picker screen exists in the requirements — you are always in the single slab you are capturing (CAPTURE-25/30).

2. REVIEW (the SAME slab, loaded by id)

Read-only capture math (REVIEW-30): length / thickness / sqft / bdft / widths.

Inference assist — the part that is entirely absent:

  • Call 1 runs automatically after the calibrated draft uploads, only when inference_enabled (METADATA-35). Sends processed photos ≤1024px + metadata + synced taxonomy.
  • Suggestion confidence ≥ 0.7 pre-fills the field with an "AI" badge and stays editable; below 0.7 the field stays empty (METADATA-45). Typed values always win (METADATA-50).
  • Fields: species leaf (exactly 1, METADATA-10), wood-category leaves (≥1), Edge Type (1), Figure (≥1), Grade (exactly 1), Thickness band (1, round-up), Moisture (1, default kiln-dried, never inferred) — the five locked attributes (METADATA-15); fig-/feat- tags optional (METADATA-30).
  • Primary wood category = first selected → drives title/short_description patterns (REVIEW-15, METADATA-85).
  • Title + short_description assembled deterministically (METADATA-80); description by model (Call 2, METADATA-55) or server when inference off (METADATA-70).
  • Generate text control appears only when content_llm_enabled AND endpoint reachable, disabled when down (METADATA-110).
  • Price = bdft × species rate, owner override sticks (REVIEW-25).
  • SKU is the LAST field filled, 3–24 alnum+hyphen (REVIEW-45).
  • Every empty required field shows an inline nudge as the owner works; no submit-time gap list; not ready until the full set incl. SKU is filled (REVIEW-20, REVIEW-5). Stale id → "no longer valid", never swapped (REVIEW-35). Calculated fields not editable (REVIEW-40).

3. PUBLISH

POST /slabs/{id}/publish → ready-set validate → SKU lookup (stop if exists) → taxonomy refresh if last sync >1h → resolve cats/tags/attrs → upload processed PNGs in photos-ready lineup order (PUBLISH-40/45) → POST /products. SLAB-UAT-* always draft (PUBLISH-10). Success sets woo_product_id, purges photos, clears the device draft (PUBLISH-25, APP-15). Duplicate SKU → edit-SKU / open-existing (PUBLISH-15). Stale value → field-level error with current options, never a raw code (PUBLISH-20). Failure → plain message, classified recoverable/unrecoverable, Retry while draft+photos retained (PUBLISH-30/35/36/37/38). Partial failure → orphaned media + cleanup note (PUBLISH-31).

SETTINGS (separate page, never in the flow)

Store creds + Test & Sync Woo (SETTINGS-40), the species $/bdft rates list (SETTINGS-35 — tracked separately), inference config (SETTINGS-30/90), Test Inference showing ok/mode/vision_capable/detail (SETTINGS-45), woo_create_status default draft (SETTINGS-65).

Backend status

The backend is verified functional end-to-end — every M3 flow (slabs CRUD + optimistic concurrency, photos multipart + 410-after-purge, review compute, pricing, taxonomy sync + anchor, publish + UAT draft + dup/stale/partial failure, inference Call 1/2 + prompt revision) has real passing tests against the live FastAPI app with Woo/inference mocked at the transport. This is a pure frontend rebuild; no backend work is required for the owner flow. (Known backend gaps, not blockers: no endpoint persists status='ready' — ready is computed; call1 suggestions need a manual PUT to apply; width_px/height_px never populated.)

Why no test caught this

  • m3-create.spec.ts is a DOM-presence proxy (buttons + heading visible). It is exactly the "dishonest proxy" QUALITY-105 rejects.
  • Commit 7575471 test(exit): M3 exit wave … Compose E2E + UAT walk sat on top of the dev-toggle scaffolding and was treated as done; the README already had M3 marked "paused — requirements reconciliation."
  • No Gitea CI exists, so the only E2E evidence is the local M2 run from #71.

Acceptance (the real E2E, per QUALITY-50)

Drive the actual flow against a Compose stack with mocked Woo:

  1. Capture a Photos-ready draft (M2 path, fixture set1-48x2).
  2. Continue → slab saved (client id, APP-20), device draft retained (APP-10).
  3. Review loads the SAME slab; fill every ready-set field; assert inline nudges appear on empty fields; assert ready flips to true only when the full set incl. SKU is filled.
  4. Publish → assert woo_product_id returned, draft for SLAB-UAT-*, photos purged (410), device draft cleared.
  5. Failure branches: duplicate SKU (edit-SKU/open-existing), not-ready (missing[]), recoverable (Retry), partial media (cleanup note).
  6. Full suite passes with inference off asserting zero inference calls (QUALITY-20, METADATA-70); the AI pre-fill path is exercised separately with inference on.
  7. No raw code/stack trace reaches the owner (QUALITY-120).

The current m3-create.spec.ts must be rewritten to drive this flow, not assert button presence.

Related

  • #42 POC [04/16]: Review screen fields, override persist, and inference disabled UI — UIE-1, UIE-7
  • #43 POC [05/16]: Call 1 prefill UI — UIE-2
  • #44 POC [06/16]: Duplicate SKU at publish UI — UIE-3
  • #45 POC [07/16]: Stale field recovery at publish UI — UIE-4
  • #46 POC [08/16]: Publish outcome, cleanup, and failure recovery — UIE-5, UIE-6, API-6
  • Requirements: REVIEW-5/10/15/20/25/30/35/40/45/50, METADATA-35/40/45/50/55/70/80/85/110/115, PUBLISH-5/10/15/20/25/30/31/35/36/37/38/40/45/50, APP-10/15/20, QUALITY-20/50/105/120
## Summary The entire M3 **Review → Publish** flow — the actual reason this release exists — is not built. What shipped instead is a row of six `(dev)` toggle buttons in `App.svelte` (lines 103–128) that each dump an unconnected `fetch()` stub `<div>` *below* the live capture workflow. There is no routing, no state handoff, no real form. The owner cannot take a Photos-ready slab to a WooCommerce product through the UI at all. This is a **wholesale UI fail** and the E2E that "passed" was a dishonest proxy: `m3-create.spec.ts` only asserts that the six buttons and one heading are **visible** in the DOM. It never drives the flow. The last genuine green E2E was #71 (2026-09-15), an **M2 capture test** run *before* any M3 work. There is no Gitea CI, so nothing in the pipeline ever exercised M3. ## What the spec requires (the flow that is missing) One column of screens, one slab, straight through (`docs/contracts/UX.md` §1: "capture → review → publish. No dashboard and no batch view"). **No slab-list / picker screen exists in the requirements** — you are always in the single slab you are capturing (CAPTURE-25/30). ### 2. REVIEW (the SAME slab, loaded by id) Read-only capture math (REVIEW-30): length / thickness / sqft / bdft / widths. **Inference assist — the part that is entirely absent:** - Call 1 runs automatically after the calibrated draft uploads, **only when `inference_enabled`** (METADATA-35). Sends processed photos ≤1024px + metadata + synced taxonomy. - Suggestion confidence **≥ 0.7 pre-fills** the field with an "AI" badge and stays editable; below 0.7 the field stays empty (METADATA-45). Typed values always win (METADATA-50). - Fields: species leaf (exactly 1, METADATA-10), wood-category leaves (≥1), Edge Type (1), Figure (≥1), Grade (exactly 1), Thickness band (1, round-up), Moisture (1, default kiln-dried, never inferred) — the five locked attributes (METADATA-15); fig-*/feat-* tags optional (METADATA-30). - Primary wood category = first selected → drives title/short_description patterns (REVIEW-15, METADATA-85). - Title + short_description assembled deterministically (METADATA-80); description by model (Call 2, METADATA-55) or server when inference off (METADATA-70). - **Generate text** control appears **only** when `content_llm_enabled` AND endpoint reachable, disabled when down (METADATA-110). - Price = bdft × species rate, owner override sticks (REVIEW-25). - **SKU is the LAST field filled**, 3–24 alnum+hyphen (REVIEW-45). - Every empty required field shows an **inline nudge** as the owner works; no submit-time gap list; not ready until the full set incl. SKU is filled (REVIEW-20, REVIEW-5). Stale id → "no longer valid", never swapped (REVIEW-35). Calculated fields not editable (REVIEW-40). ### 3. PUBLISH `POST /slabs/{id}/publish` → ready-set validate → SKU lookup (stop if exists) → taxonomy refresh if last sync >1h → resolve cats/tags/attrs → upload processed PNGs in photos-ready lineup order (PUBLISH-40/45) → `POST /products`. `SLAB-UAT-*` always draft (PUBLISH-10). Success sets `woo_product_id`, purges photos, clears the device draft (PUBLISH-25, APP-15). Duplicate SKU → edit-SKU / open-existing (PUBLISH-15). Stale value → field-level error with current options, never a raw code (PUBLISH-20). Failure → plain message, classified recoverable/unrecoverable, Retry while draft+photos retained (PUBLISH-30/35/36/37/38). Partial failure → orphaned media + cleanup note (PUBLISH-31). ### SETTINGS (separate page, never in the flow) Store creds + **Test & Sync Woo** (SETTINGS-40), the **species $/bdft rates** list (SETTINGS-35 — tracked separately), inference config (SETTINGS-30/90), **Test Inference** showing ok/mode/vision_capable/detail (SETTINGS-45), `woo_create_status` default draft (SETTINGS-65). ## Backend status **The backend is verified functional end-to-end** — every M3 flow (slabs CRUD + optimistic concurrency, photos multipart + 410-after-purge, review compute, pricing, taxonomy sync + anchor, publish + UAT draft + dup/stale/partial failure, inference Call 1/2 + prompt revision) has real passing tests against the live FastAPI app with Woo/inference mocked at the transport. **This is a pure frontend rebuild; no backend work is required** for the owner flow. (Known backend gaps, not blockers: no endpoint persists `status='ready'` — ready is computed; call1 suggestions need a manual `PUT` to apply; `width_px/height_px` never populated.) ## Why no test caught this - `m3-create.spec.ts` is a DOM-presence proxy (buttons + heading visible). It is exactly the "dishonest proxy" QUALITY-105 rejects. - Commit `7575471 test(exit): M3 exit wave … Compose E2E + UAT walk` sat on top of the dev-toggle scaffolding and was treated as done; the README already had M3 marked "paused — requirements reconciliation." - No Gitea CI exists, so the only E2E evidence is the local M2 run from #71. ## Acceptance (the real E2E, per QUALITY-50) Drive the actual flow against a Compose stack with mocked Woo: 1. Capture a Photos-ready draft (M2 path, fixture `set1-48x2`). 2. Continue → slab saved (client id, APP-20), device draft retained (APP-10). 3. Review loads the SAME slab; fill every ready-set field; assert inline nudges appear on empty fields; assert `ready` flips to true only when the full set incl. SKU is filled. 4. Publish → assert `woo_product_id` returned, draft for `SLAB-UAT-*`, photos purged (410), device draft cleared. 5. Failure branches: duplicate SKU (edit-SKU/open-existing), not-ready (missing[]), recoverable (Retry), partial media (cleanup note). 6. Full suite passes with **inference off** asserting **zero inference calls** (QUALITY-20, METADATA-70); the AI pre-fill path is exercised separately with inference on. 7. No raw code/stack trace reaches the owner (QUALITY-120). The current `m3-create.spec.ts` must be **rewritten** to drive this flow, not assert button presence. ## Related - #42 POC [04/16]: Review screen fields, override persist, and inference disabled UI — UIE-1, UIE-7 - #43 POC [05/16]: Call 1 prefill UI — UIE-2 - #44 POC [06/16]: Duplicate SKU at publish UI — UIE-3 - #45 POC [07/16]: Stale field recovery at publish UI — UIE-4 - #46 POC [08/16]: Publish outcome, cleanup, and failure recovery — UIE-5, UIE-6, API-6 - Requirements: REVIEW-5/10/15/20/25/30/35/40/45/50, METADATA-35/40/45/50/55/70/80/85/110/115, PUBLISH-5/10/15/20/25/30/31/35/36/37/38/40/45/50, APP-10/15/20, QUALITY-20/50/105/120
Ty closed this issue 2026-09-21 06:17:17 +00:00
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Ty_Tech/SlabUploader#77