docs(#10): add UX-DESIGN wireframes for review
Publish the phone screen inventory, ASCII wireframes, error states, and UAT cases so Ty can review issue #10 on docs/refactor-v2. UX.md points at UX-DESIGN for presentation.
This commit is contained in:
@@ -0,0 +1,486 @@
|
||||
# UX Design — SlabUploader Phone App
|
||||
|
||||
Status: DESIGN · 2026-09-03 · SlabUploader
|
||||
Screens for the online-only POC flow. Mobile-first, 375px viewport.
|
||||
|
||||
Functional rules live in `docs/UX.md`. Confidence gating: `AGENTS.md` §6.
|
||||
Data model and status machine: `docs/DATA-MODEL.md`.
|
||||
|
||||
---
|
||||
|
||||
## Screen inventory
|
||||
|
||||
1. Settings (once)
|
||||
2. First-run guidance (once per device)
|
||||
3. Capture
|
||||
4. Length axis
|
||||
5. Type values
|
||||
6. Review
|
||||
7. Title / Description
|
||||
8. Publish
|
||||
9. Error states
|
||||
|
||||
---
|
||||
|
||||
## 1. Settings
|
||||
|
||||
One-time setup. All screen. Back to home after save.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Settings │
|
||||
├─────────────────────────────────────┤
|
||||
│ Store URL │
|
||||
│ https://www.whidbeywoodstore.com │
|
||||
│ │
|
||||
│ WP Username │
|
||||
│ [ slab-uploader ] │
|
||||
│ Application Password │
|
||||
│ [ •••••••••••••••••••• ] │
|
||||
│ [ Test Connection ] │
|
||||
│ │
|
||||
│ Inference │
|
||||
│ Endpoint: [ http://192.168.x.x:v1 ]│
|
||||
│ API Key: [ •••••••••••••••••••• ]│
|
||||
│ [ Test Connection ] │
|
||||
│ [ Enable Vision ] │
|
||||
│ [ Enable Content ] │
|
||||
│ │
|
||||
│ Pricing Rules │
|
||||
│ [+ Add Rule] [Edit] │
|
||||
│ │
|
||||
│ Publish Status: [ Draft ▼ ] │
|
||||
│ Brand Voice: [ Premium lumber... ]│
|
||||
│ GEO Context: [ Locally milled... ]│
|
||||
│ │
|
||||
│ [ Reset Capture Knobs ] │
|
||||
│ [ Refresh Store Lists ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Interaction:
|
||||
- Test Connection (WP): attempts REST v3 auth, shows green check or red error. Always pulls fresh taxonomy on success.
|
||||
- Test Connection (Inference): two-turn probe. Shows stateful/stateless/fail.
|
||||
- Enable Vision: feature flag for Call 1. Defaults off.
|
||||
- Enable Content: feature flag for Call 2. Defaults off.
|
||||
- Publish Status: dropdown, default Draft.
|
||||
|
||||
---
|
||||
|
||||
## 2. First-run guidance
|
||||
|
||||
One short card shown on first launch. Dismissed via swipe or tap.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ │
|
||||
│ First run on the floor │
|
||||
│ │
|
||||
│ Lay a green or black sheet │
|
||||
│ under the slab. │
|
||||
│ │
|
||||
│ Shoot from above with the lens │
|
||||
│ parallel to the face. │
|
||||
│ │
|
||||
│ Put a tape measure in the shot │
|
||||
│ so you can type the length later. │
|
||||
│ │
|
||||
│ ────────────────────────────────── │
|
||||
│ [ Got it ] │
|
||||
│ │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Capture
|
||||
|
||||
Camera view. Source photo on screen. Mask overlay draws on the source.
|
||||
Four knobs sit next to the overlay.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Capture [R] │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ [ SOURCE PHOTO ] │ │
|
||||
│ │ │ │
|
||||
│ │ ~ mask overlay ~ │ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Sheet: [ Auto ▼ ] │
|
||||
│ Sensitivity: [◄─────●───►] │
|
||||
│ Edge Offset: [◄───●───►] │
|
||||
│ Feather: [◄─────●───►] │
|
||||
│ │
|
||||
│ [ Retake ] [ Confirm ] │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
R = retake current photo (new shot, same knobs)
|
||||
```
|
||||
|
||||
Interaction:
|
||||
- Moving any knob immediately re-runs background removal on the current photo.
|
||||
- The overlay refreshes on the source image. No apply/save step. No server round-trip.
|
||||
- Confirm moves to length axis. Retake takes a new photo.
|
||||
- Knobs persist in localStorage until reset-to-default in Settings.
|
||||
|
||||
---
|
||||
|
||||
## 4. Length axis
|
||||
|
||||
Bounding rectangle and length axis drawn over the confirmed mask.
|
||||
Width sample lines every 6 inches.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Length Axis │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ ┌───────────────┐ │ │
|
||||
│ │ │ SLAB MASK │ │ │
|
||||
│ │ │ ──── AXIS ── │ │ │
|
||||
│ │ │ ┌──┐ ┌──┐ ┌──┐ │ │
|
||||
│ │ │ │ 6"│ │6"│ │6"│ │ │
|
||||
│ │ └───────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
│ │
|
||||
│ [ Rotate ↻ ] [ Confirm ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Interaction:
|
||||
- Rotate adjusts the axis. Width samples and sqft update live.
|
||||
- On nearly square slabs, user picks which side is length.
|
||||
- Confirm moves to type values.
|
||||
|
||||
---
|
||||
|
||||
## 5. Type values
|
||||
|
||||
Manual values win. Phone computes sqft, bdft, widths.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Type Values │
|
||||
│ │
|
||||
│ SKU │
|
||||
│ [ BW-0042 ] │
|
||||
│ │
|
||||
│ Length (inches) │
|
||||
│ [ 96.0 ] │
|
||||
│ │
|
||||
│ Thickness (inches) │
|
||||
│ [ 1.5 ] │
|
||||
│ │
|
||||
│ Computed (read-only) │
|
||||
│ sqft: 0.64 bdft: 0.96 │
|
||||
│ widths: 14.0 — 22.0 (avg 18.2) │
|
||||
│ │
|
||||
│ [ Done ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Interaction:
|
||||
- SKU: `[A-Z0-9-]{3,24}`. Field-exit check against validation rules.
|
||||
- Length: 1/8" step. Typing recalculates widths/sqft/bdft live.
|
||||
- Thickness: 1/8" step pick.
|
||||
- Done moves to review screen. Draft uploads, status → calibrated.
|
||||
|
||||
---
|
||||
|
||||
## 6. Review
|
||||
|
||||
All store fields. Per-field nudges for missing mandatory fields.
|
||||
Vision pre-populates when confidence ≥ 0.7. Empty when below.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Review [X]│
|
||||
│ ────────────────────────────────── │
|
||||
│ Photos │
|
||||
│ [ ▢ ] [ ▢ ] [ ▢ ] [ ▢ ] [ ▢ ] │
|
||||
│ (processed PNG thumbnails) │
|
||||
│ ────────────────────────────────── │
|
||||
│ SKU: BW-0042 │
|
||||
│ Length: 96.0" Thickness: 1.5" │
|
||||
│ sqft: 0.64 bdft: 0.96 │
|
||||
│ Widths: 14.0 — 22.0 (avg 18.2) │
|
||||
│ ────────────────────────────────── │
|
||||
│ Species [ Black Walnut ▼ ] │
|
||||
│ Wood Cat [ Live edge ▼ ] │
|
||||
│ Edge Type [ Live Edge ▼ ] │
|
||||
│ Figure [ Cathedral ▼ ] │
|
||||
│ Grade [ Premium ▼ ] │
|
||||
│ Fig Tags [ Cathedral ▼ ] │
|
||||
│ Feat Tags [ None ▼ ] │
|
||||
│ ────────────────────────────────── │
|
||||
│ Thickness Band: [ 1"–1 1/2" ▼ ] │
|
||||
│ Moisture: [ Kiln-dried ▼ ] │
|
||||
│ ────────────────────────────────── │
|
||||
│ Price: [ $12.00 ] (rec $12.00) │
|
||||
│ ────────────────────────────────── │
|
||||
│ [ Review Title / Desc ] [ Publish ]│
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
X = exit review, returns to calibrated draft
|
||||
```
|
||||
|
||||
Per-field gating:
|
||||
- Each missing mandatory field shows an inline empty state as the user works.
|
||||
- Below-threshold Call 1 leaves taxonomy fields empty. The user sees the empty
|
||||
field with a nudge: "Select species" or "Select a figure type".
|
||||
- Below-threshold leaves taxonomy fields empty. The user must manually fill species, wood
|
||||
category, edge type, figure, grade, fig-* tags, and grade to reach ready.
|
||||
- Submit-time validation only fires after all fields are filled.
|
||||
|
||||
Pre-populated field appearance:
|
||||
- Filled by Call 1: field shows the value with a small "AI" badge. User can
|
||||
tap to change. Badge disappears on edit.
|
||||
- User-filled: no badge.
|
||||
|
||||
Gating details:
|
||||
- Mandatory: exactly one species, ≥1 wood category, 1 edge type, ≥1 figure,
|
||||
≥1 fig-* tag, ≥1 grade, thickness band, moisture, price, SKU, length,
|
||||
thickness, sqft/bdft/widths, ≥1 inventory PNG.
|
||||
- Optional: feat-* tags (zero is fine).
|
||||
- Publish button is disabled until all mandatory fields are filled.
|
||||
|
||||
---
|
||||
|
||||
## 7. Title / Description
|
||||
|
||||
Type or generate. Generate text is user-initiated.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Title & Description │
|
||||
│ ────────────────────────────────── │
|
||||
│ Title │
|
||||
│ [ Black Walnut 8ft × 18.2in Slab... │
|
||||
│ ────────────────────────────────── │
|
||||
│ Short Title │
|
||||
│ [ Black Walnut Slab — Cathedral ] │
|
||||
│ ────────────────────────────────── │
|
||||
│ Description │
|
||||
│ [ A one-of-a-one cathedral black... │
|
||||
│ ────────────────────────────────── │
|
||||
│ [ Generate Text ] [ Done ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Interaction:
|
||||
- Generate Text: triggers Call 2. Button disabled if content LLM is off or
|
||||
inference endpoint unreachable. LLM writes prose only. Templates inject
|
||||
deterministic numbers. User can always edit the result.
|
||||
- Done: returns to review. Title/description stored on the slab.
|
||||
|
||||
---
|
||||
|
||||
## 8. Publish
|
||||
|
||||
Status polling. Result shown inline.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Publishing... │
|
||||
│ │
|
||||
│ ──────── ● ──────── │
|
||||
│ │
|
||||
│ Creating store listing... │
|
||||
│ Please wait. │
|
||||
│ │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Success:
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Published! │
|
||||
│ │
|
||||
│ Listing created as draft. │
|
||||
│ SKU: BW-0042 │
|
||||
│ Store product ID: 1042 │
|
||||
│ │
|
||||
│ [ Open in Store ] [ Done ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Failed:
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Publish Failed │
|
||||
│ │
|
||||
│ The store rejected the listing. │
|
||||
│ Error shown inline on the field. │
|
||||
│ │
|
||||
│ [ Retry ] [ Back to Review ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Error and empty states
|
||||
|
||||
### 9.1 Mask failure
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Mask Quality │
|
||||
│ ────────────────────────────────── │
|
||||
│ Cannot isolate the slab edge. │
|
||||
│ Adjust the knobs or retake. │
|
||||
│ ────────────────────────────────── │
|
||||
│ [ Retake ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 9.2 Axis misalignment
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Axis Check │
|
||||
│ ────────────────────────────────── │
|
||||
│ Rotate the axis to match the │
|
||||
│ prevailing length of the slab. │
|
||||
│ ────────────────────────────────── │
|
||||
│ [ Rotate ↻ ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 9.3 Source too small after crop
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Photo Quality │
|
||||
│ ────────────────────────────────── │
|
||||
│ Photo will be too small after │
|
||||
│ cropping. Please retake with a │
|
||||
│ closer shot. │
|
||||
│ ────────────────────────────────── │
|
||||
│ [ Retake ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 9.4 SKU duplicate
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ SKU Check │
|
||||
│ ────────────────────────────────── │
|
||||
│ This SKU already exists in the │
|
||||
│ store (any status). │
|
||||
│ ────────────────────────────────── │
|
||||
│ [ Edit SKU ] [ Open Existing ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 9.5 Stale taxonomy value
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Field Check │
|
||||
│ ────────────────────────────────── │
|
||||
│ This value is no longer valid. │
|
||||
│ Pick from the current list. │
|
||||
│ ────────────────────────────────── │
|
||||
│ [ Refresh Store Lists ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 9.6 Store unreachable
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Connection │
|
||||
│ ────────────────────────────────── │
|
||||
│ Cannot reach the store. Check your │
|
||||
│ connection and settings. │
|
||||
│ ────────────────────────────────── │
|
||||
│ [ Retry ] [ Open Settings ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 9.7 Vision off or below threshold
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Review (vision off) │
|
||||
│ ────────────────────────────────── │
|
||||
│ Species [ Select ▼ ] ◉ Select species
|
||||
│ Wood Cat [ Select ▼ ] ◉ Select category
|
||||
│ Edge Type [ Select ▼ ] ◉ Select edge
|
||||
│ Figure [ Select ▼ ] ◉ Select figure
|
||||
│ ────────────────────────────────── │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
◉ = inline nudge (per-field)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Interaction patterns
|
||||
|
||||
### Per-field gating (review screen)
|
||||
- Each mandatory field that is empty shows an inline nudge as the user works.
|
||||
- The nudge is a small text hint to the right of the field.
|
||||
- Below-threshold Call 1 leaves fields empty with nudges visible.
|
||||
- Fill the field to dismiss the nudge.
|
||||
- Publish button stays disabled until all mandatory fields are filled.
|
||||
|
||||
### Pre-populated field state
|
||||
- Fields filled by Call 1 show the value with an "AI" badge.
|
||||
- User can tap the field to change it. The badge disappears on edit.
|
||||
- User-filled fields have no badge.
|
||||
|
||||
### Knob interaction (capture screen)
|
||||
- All four knobs are on the capture screen next to the overlay.
|
||||
- Moving a knob immediately re-runs background removal.
|
||||
- No apply/save step. No server round-trip for mask tuning.
|
||||
|
||||
### Axis rotation
|
||||
- Drag or tap to rotate the axis. Width samples and sqft update live.
|
||||
- Confirm locks the axis for measurement.
|
||||
|
||||
### Generate text
|
||||
- Button only appears if content LLM is enabled and inference is reachable.
|
||||
- Disabled if the text service is down.
|
||||
- Never runs automatically. User taps it.
|
||||
|
||||
### Publish flow
|
||||
- Tap Publish. Status moves to publishing. Poll for result.
|
||||
- Success: show result, offer to open in store.
|
||||
- Failed: show error detail, keep draft and photos, allow retry.
|
||||
- SLAB-UAT-* SKUs always create as Woo draft regardless of settings.
|
||||
|
||||
---
|
||||
|
||||
## Browser compatibility gate
|
||||
|
||||
Shown on load if browser lacks required APIs.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Browser Update │
|
||||
│ ────────────────────────────────── │
|
||||
│ This app requires a recent browser. │
|
||||
│ Please update Safari or Chrome, │
|
||||
│ then try again. │
|
||||
│ ────────────────────────────────── │
|
||||
│ [ Update Browser ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## UAT test cases (derived from wireframes)
|
||||
|
||||
1. **Settings once**: enter WP credentials, test connection, taxonomy syncs.
|
||||
2. **First-run guidance**: card shows and dismisses.
|
||||
3. **Capture**: take photo, mask overlays, adjust knob, overlay refreshes live, confirm.
|
||||
4. **Length axis**: bounding rect draws, rotate axis, confirm, widths update.
|
||||
5. **Type values**: enter SKU/length/thickness, computed values appear, done.
|
||||
6. **Review — vision on, ≥ 0.7**: taxonomy fields pre-filled with AI badge, editable.
|
||||
7. **Review — vision on, < 0.7**: taxonomy fields empty, per-field nudges visible, user fills manually.
|
||||
8. **Review — vision off**: all taxonomy fields empty, per-field nudges visible, user fills manually.
|
||||
9. **Publish — success**: draft created, product ID stored, images purged.
|
||||
10. **Publish — duplicate SKU**: error on SKU field, edit SKU or open existing.
|
||||
11. **Publish — stale taxonomy**: error on field, refresh store lists, pick current option.
|
||||
12. **Publish — SLAB-UAT-***: always creates as draft regardless of settings.
|
||||
13. **Generate text**: button visible when enabled, disabled when service down, LLM prose injected.
|
||||
14. **Retake paths**: mask failure → retake, source too small → retake.
|
||||
+31
-21
@@ -1,8 +1,8 @@
|
||||
# Phone flow
|
||||
|
||||
What the mill owner does on the phone, from first photo to a store listing. Math and constants live in `docs/TECH-SPEC-PIPELINE.md`. Field names and the ready set live in `docs/DATA-MODEL.md`. Store payload and create steps live in `docs/CONTENT-WOO.md`.
|
||||
What the mill owner does on the phone, from first photo to a store listing. Math and constants live in `docs/TECH-SPEC-PIPELINE.md`. Field names and the ready set live in `docs/DATA-MODEL.md`. Store payload and create steps live in `docs/CONTENT-WOO.md`. Wireframes and interaction patterns: `docs/UX-DESIGN.md`.
|
||||
|
||||
Values you type are kept as-is. Vision fills store fields only when it is at least 0.7 confident; everything else you fill in yourself.
|
||||
Values you type are kept as-is. Vision fills store fields per the confidence gating rules in `AGENTS.md` §6.
|
||||
|
||||
---
|
||||
|
||||
@@ -10,21 +10,21 @@ Values you type are kept as-is. Vision fills store fields only when it is at lea
|
||||
|
||||
### Settings once
|
||||
|
||||
The store URL shows read-only from the deploy (`WOO_BASE_URL`). It is not an input field. You always know which store this phone talks to.
|
||||
The store URL shows read-only from the deploy (`WOO_BASE_URL`). You always know which store this phone talks to.
|
||||
|
||||
Enter the WordPress username and application password for the low-privilege store user, under Users → Profile in WordPress. The password is write-only: you type it once, and it never comes back on load. To rotate, revoke the old one in WordPress and enter a new one here.
|
||||
Enter the WordPress username and application password for the low-privilege store user, under Users → Profile in WordPress. The password is write-only: you type it once. To rotate, revoke the old one in WordPress and enter a new one here.
|
||||
|
||||
On the same screen: species $/bdft rates, vision on/off with endpoint and key, draft vs publish for new listings (default draft), reset capture knobs to factory, and an optional refresh of the store lists. **Test connection** always pulls fresh species, attributes, and tags from the store when it succeeds.
|
||||
|
||||
### First run on the floor
|
||||
|
||||
One short card, then dismiss. Lay a green or black sheet under the slab. Shoot from above with the lens parallel to the face. Put a tape measure in the shot so you can **type** the length later. The app does not read the tape and has no ruler detector; your typed number is what it measures against.
|
||||
One short card, then dismiss. Lay a green or black sheet under the slab. Shoot from above with the lens parallel to the face. Put a tape measure in the shot so you can **type** the length later. Your typed number is what the app measures against.
|
||||
|
||||
### Capture
|
||||
|
||||
Take 1 to 5 inventory photos.
|
||||
|
||||
The source photo stays on screen, and the mask draws over that original: kept wood versus dropped sheet. Four knobs sit next to the overlay, not in Settings:
|
||||
The source photo stays on screen, and the mask draws over that original: kept wood versus dropped sheet. Four knobs sit next to the overlay:
|
||||
|
||||
1. Sheet — auto, green, or black
|
||||
2. Sensitivity
|
||||
@@ -33,7 +33,7 @@ The source photo stays on screen, and the mask draws over that original: kept wo
|
||||
|
||||
Move a knob and background removal re-runs on this photo; the overlay refreshes immediately. Nothing round-trips to the server for mask tuning. The knobs stick in local storage until you reset them to factory.
|
||||
|
||||
Your eye is the only check on the mask: there is no confidence score, no quality gate, and no image-quality classifier. If the cut sits on the wood edge, confirm it. If it clips grain or still holds sheet after you tune, retake the photo. The one-photo server U2Net path stays in the architecture for post-POC; it has no control in this POC.
|
||||
Confirm the mask edge by eye. If the cut sits on the wood edge, confirm it. If it clips grain or still holds sheet after you tune, retake the photo. The one-photo server U2Net path stays in the architecture for post-POC; it is deferred from POC.
|
||||
|
||||
### Length axis
|
||||
|
||||
@@ -43,7 +43,7 @@ The bounding rectangle and length axis draw over the confirmed mask, with width
|
||||
|
||||
Manual values win. The phone computes square feet, board feet (`bdft = sqft × thickness_in`, no `/12`), and width min / max / avg from the mask and your typed length.
|
||||
|
||||
It builds 3:4 transparent PNG inventory images at 80% fill on the extremes. After that crop, if the source does not have enough pixels for a shorter side of 1600 px, that photo is not publishable until you retake it. No fake upscale. The floor and the math are in `docs/TECH-SPEC-PIPELINE.md` (constants and TV-7); they are not painted on the camera screen.
|
||||
It builds 3:4 transparent PNG inventory images at 80% fill on the extremes. After that crop, if the source does not have enough pixels for a shorter side of 1600 px, that photo is not publishable until you retake it. The floor and the math are in `docs/TECH-SPEC-PIPELINE.md` (constants and TV-7).
|
||||
|
||||
### Draft upload (calibrated)
|
||||
|
||||
@@ -51,7 +51,7 @@ When mask, axis, length, thickness, and SKU are set and the numbers and PNGs are
|
||||
|
||||
### Review (store fields)
|
||||
|
||||
Everything the listing needs lands here. A required control that is still empty shows an inline empty state as you work, not only at submit.
|
||||
Everything the listing needs lands here. A required control that is still empty shows an inline empty state as you work.
|
||||
|
||||
**Always on the form from capture and defaults**
|
||||
|
||||
@@ -59,14 +59,14 @@ Everything the listing needs lands here. A required control that is still empty
|
||||
- SKU, length, thickness
|
||||
- Computed sqft, bdft, width min / max / avg
|
||||
- Thickness store band from your typed thickness, rounded **up** into the synced Woo thickness range
|
||||
- Moisture starts at **kiln-dried**. Vision does not set moisture. Change it if the slab is not KD.
|
||||
- Moisture starts at **kiln-dried**. Vision does not set moisture. Change it for green or air-dried slabs.
|
||||
- Price: species $/bdft × bdft prefills when a rate exists for that species. If there is no rate, the field starts empty and you type the price. Override anytime; your override sticks for this slab.
|
||||
|
||||
**Species and store taxonomy**
|
||||
|
||||
Pickers and any vision lists are exactly the last pull from the store. No hardcoded species list. A new Woo species becomes selectable only after a sync lands it in the cache.
|
||||
Pickers and any vision lists are exactly the last pull from the store. A new Woo species becomes selectable only after a sync lands it in the cache.
|
||||
|
||||
If vision is on and confidence is at least 0.7, it may pre-fill species, wood categories, edge type, figure, grade, and feature (`feat-*`) tags. Every pre-fill is editable; typed values win. If vision is off or confidence is under 0.7, those fields start empty and you fill them by hand. A low-confidence guess never shows as a default.
|
||||
Call 1 prefill behavior: see CONTENT-WOO §2.3. Every pre-fill is editable. Typed values win.
|
||||
|
||||
**Required before the slab is ready to list**
|
||||
|
||||
@@ -85,7 +85,7 @@ Feature (`feat-*`) tags are optional; zero is fine.
|
||||
|
||||
### Title, short title, description
|
||||
|
||||
Type them, or tap **Generate text**. Generate text never runs on its own and is off unless content generation is enabled in Settings. If the text service is down, the button is disabled; templates still work and publish is not blocked. The model writes prose only — character, color, grain, uses. Measured length, width, thickness, square feet, and board feet are facts it receives, never numbers it invents.
|
||||
Type them, or tap **Generate text**. Generate text is off unless content generation is enabled in Settings. Templates still work when the text service is down. The model writes prose only. Templates inject the measured values into the final text.
|
||||
|
||||
If title, short title, or description are still blank at publish, templates fill them from the measured facts (species, lengths, widths, thickness, bdft). You can edit any of it afterward.
|
||||
|
||||
@@ -107,30 +107,40 @@ Same capture and review as production, with a `SLAB-UAT-*` SKU. The listing is f
|
||||
|
||||
## Usual failures
|
||||
|
||||
**Mask clips wood or still holds sheet.** Turn the four knobs; confirm by eye. If it is still wrong, retake. A bad edge silently shifts square feet and widths; there is no later numeric check that catches it.
|
||||
**Mask clips wood or still holds sheet.** Turn the four knobs; confirm by eye. If it is still wrong, retake. A bad edge shifts square feet and widths without a later numeric check.
|
||||
|
||||
**Axis skewed or on the wrong length side.** Rotate the axis, or retake. Widths and sqft follow whatever axis you confirm.
|
||||
|
||||
**Source too small after the 3:4 / 80% crop.** The app warns and asks for a retake of that photo. No invented pixels; see `docs/TECH-SPEC-PIPELINE.md` TV-7.
|
||||
**Source too small after the 3:4 / 80% crop.** The app warns and asks for a retake of that photo. See `docs/TECH-SPEC-PIPELINE.md` TV-7.
|
||||
|
||||
**Required store field still empty.** Inline empty state on that control. Publish stays blocked until the full ready set in Main path is filled.
|
||||
|
||||
**SKU already exists in the store under any status** (draft, private, publish, and the rest). The message sits on the SKU field: it already exists in the store. Actions there: edit the SKU, or open the existing listing when a link is available. This version does not edit the other product in place. No raw status codes on screen.
|
||||
**SKU already exists in the store under any status** (draft, private, publish, and the rest). The message sits on the SKU field: it already exists in the store. Actions there: edit the SKU, or open the existing listing when a link is available. This version does not edit the other product in place. Raw status codes do not appear on screen.
|
||||
|
||||
**Category, attribute, tag, or price no longer valid after a list refresh.** The message sits on that field: the value is no longer valid; pick from the current list, and the current options come with it. Your draft stays on the phone.
|
||||
|
||||
**Rules copy on the phone went stale at submit.** Brief "Updating rules." The phone refetches the shared rules, checks again, and retries. That is not a duplicate-SKU conflict, and no raw status code shows.
|
||||
**Rules copy on the phone went stale at submit.** Brief "Updating rules." The phone refetches the shared rules, checks again, and retries.
|
||||
|
||||
**Store unreachable, auth failure, or other hard Woo failure.** Plain failure message, no stack traces. The slab can move to failed with detail; draft and photos stay so you can retry.
|
||||
**Store unreachable, auth failure, or other hard Woo failure.** Plain failure message. The slab can move to failed with detail. Draft and photos stay so you can retry.
|
||||
|
||||
**Vision off or under 0.7.** The taxonomy fields vision would have filled start empty; fill the required set by hand. Moisture still starts kiln-dried, and the thickness band still comes from your typed thickness. Inference never blocks publish and never publishes on its own.
|
||||
**Vision off or below threshold.** Fill the required set by hand. Moisture starts kiln-dried, and the thickness band comes from your typed thickness. Inference is assist-only.
|
||||
|
||||
**Generate text unavailable.** Button disabled. Type copy or let templates write at publish.
|
||||
|
||||
Leaving a field: empty optional is fine; typed junk is not. SKU is `A-Z`, `0-9`, and hyphen, length 3–24. Title, short title, and description cannot type past the store max length.
|
||||
Leaving a field: SKU is `A-Z`, `0-9`, and hyphen, length 3–24. Title, short title, and description cannot exceed the store max length.
|
||||
|
||||
## Browser compatibility
|
||||
|
||||
The app requires **iOS Safari 17** or **Android Chrome 110** (or newer). These versions provide the APIs the image pipeline depends on: OffscreenCanvas, MediaDevices, Web Workers, File System Access, and structuredClone.
|
||||
|
||||
When an older browser loads the app, the landing page shows:
|
||||
|
||||
> This app requires a recent browser. Please update Safari or Chrome, then try again.
|
||||
|
||||
The message includes a link to the browser's update page..
|
||||
|
||||
---
|
||||
|
||||
## Out of scope for this POC UI
|
||||
|
||||
Server U2Net "Try harder" on capture (kept in architecture for later; not a control here). A user slider for the 0.7 vision threshold. Offline / airplane capture. Any image-quality classifier or score. Strings painted on the live photo about lighting, steadiness, mask confidence, or a pixel requirement.
|
||||
Server U2Net "Try harder" on capture (deferred from POC). A user slider for the 0.7 vision threshold. Offline / airplane capture. Any image-quality classifier or score. Strings painted on the live photo about lighting, steadiness, mask confidence, or a pixel requirement.
|
||||
|
||||
Reference in New Issue
Block a user