4e97770373
Rewrite PRD, tech spec, data model, and OpenAPI around the 2026-08-27 decisions: client-side mask/measure/crop, U2Net on demand, Woo as product source of truth, draft-only local state. Architecture records topology C through the status machine. Drop the old CONTENT-WOO spec until the Call 2 prompt review finishes.
241 lines
12 KiB
Plaintext
241 lines
12 KiB
Plaintext
# Slab Capture & WooCommerce Publishing App — PRD
|
|
|
|
## Overview
|
|
Build a mobile-first, self-hosted web app that streamlines publishing one-of-a-one wood
|
|
slabs to a WooCommerce store. The app is a photo capture → calibration → inference →
|
|
publish pipeline.
|
|
|
|
**Primary constraints**
|
|
- No slab versioning in v1.
|
|
- No staff accounts or role complexity in v1.
|
|
- No bulk publishing; slab-by-slab submission only.
|
|
- No analytics in v1.
|
|
- No pricing tiers in v1 — flat price-per-bdft per species/wood-category.
|
|
- No app-level auth in v1 — app relies on HTTPS + trusted network.
|
|
- Single SKU per slab; duplicate SKU publish is blocked.
|
|
- Images are purged after successful publish (retained only while draft/retry).
|
|
- Deploy target: .201, Docker Compose + Caddy.
|
|
|
|
## Decisions log (2026-08-27, Ty)
|
|
1. No calibration photos — user manually enters SKU, length, thickness.
|
|
2. First photo is the measurement photo (must be top-down, lens parallel to broad side).
|
|
3. All photos go through background removal + 80% frame-fill crop.
|
|
4. Output: transparent PNGs, minimum 1600 px on the smaller dimension, aspect ratio preserved.
|
|
5. Green or black sheet — algorithm auto-detects background color from image borders.
|
|
6. WooCommerce categories synced from store: Species (1 required, leaf-only), Wood Category (1+ required, leaf-only).
|
|
7. WooCommerce attributes: Edge Type (1 required), Figure (1+ required), Grade (1+ required), Thickness (1 required, rounded up to nearest Woo attribute range).
|
|
8. WooCommerce tags: fig-* only (1+ required, e.g., fig-chat = Chatoyant).
|
|
9. Two-call inference: Call 1 (vision, wood expert) → Call 2 (text, content gen). Both configurable.
|
|
10. Call 1 runs automatically after calibration. User reviews/corrects before triggering Call 2.
|
|
11. Inference timeout >45s or non-200 → error with retry. User can fill fields manually.
|
|
12. Woo product status set to "published" by default (configurable in settings).
|
|
13. All inference prompts stored server-side, editable in settings with reset-to-default.
|
|
14. Brand voice + GEO context injected into Call 2 prompt.
|
|
15. WooCommerce credentials (username + App Password) stored client-side in settings.
|
|
16. Inference endpoint: configurable OpenAI-compatible API (user provides base URL, key, model).
|
|
17. Test connection verifies text completion + vision support.
|
|
18. Offline capture not required for MVP.
|
|
|
|
## Open items
|
|
- (none — all resolved 2026-08-27)
|
|
|
|
## Goals and success metrics
|
|
**Goals**
|
|
- Reduce per-slab prep time (target: 20-30 to 5-10 minutes).
|
|
- Produce consistent, high-quality product pages (title, description, taxonomy, images).
|
|
- Keep deterministic core logic testable and auditable.
|
|
- Mobile-first UX with fast feedback.
|
|
- Allow Ty to host and control inference via a configurable OpenAI endpoint.
|
|
|
|
**Success metrics**
|
|
- Average time from first photo to published product <= 10 minutes.
|
|
- Dimension extraction accuracy within +/- 0.25 in.
|
|
- Photo normalization produces consistent 80% frame fill for 95% of inventory photos.
|
|
- Inference results accepted or corrected by user in <= 2 edits for 90% of slabs.
|
|
|
|
## Non-goals
|
|
- Multi-tenant SaaS or ERP integrations in v1.
|
|
- Generic SKU inventory management.
|
|
- Complex user roles or staff permissions.
|
|
- Bulk import/publish workflows.
|
|
- Offline capture for MVP.
|
|
|
|
## Users and core use cases
|
|
|
|
**Primary user**
|
|
- Ty (Owner/Expert): captures, configures, reviews, and publishes slabs.
|
|
|
|
**Core use cases**
|
|
- Capture: Stage slab on green or black sheet with lights, take 1-5 photos.
|
|
- Enter metadata: SKU, length (in), thickness (in).
|
|
- Calibration: App processes first photo - BG removal, longest dimension detection,
|
|
area measurement (sqft), bdft calc, then processes all photos for BG removal + crop.
|
|
- Inference: Call 1 (vision) auto-runs, populating taxonomy/content. User reviews/corrects.
|
|
Call 2 (text) user-triggered for title/description/short description.
|
|
- Review & publish: Final review screen with full override capability; publish to WooCommerce.
|
|
- Configuration: Settings for inference endpoint, Woo credentials, pricing rules,
|
|
brand voice, GEO context, prompts.
|
|
|
|
## High level requirements summary
|
|
- Deterministic core: all measurement math, pricing, normalization, and WooCommerce sync
|
|
must be deterministic and unit-tested.
|
|
- Scoped inference: species/category/attribute detection and content generation only;
|
|
inference must be toggleable and use Ty's configured OpenAI endpoint.
|
|
- Mobile first: usable on modern iPhone and Android browsers.
|
|
- Single slab workflow: no batch publish in v1; each slab is captured, enriched,
|
|
reviewed, and published individually.
|
|
|
|
## Functional requirements (detailed)
|
|
|
|
### Capture and calibration
|
|
- **FR1:** Camera capture for 1-5 inventory photos. First photo must be top-down,
|
|
lens parallel to the slab's broad side.
|
|
- **FR2:** User manually enters SKU (3-24 chars, [A-Z0-9-]), length (in), thickness (in).
|
|
- **FR3:** App detects background color from image borders (green or black sheet).
|
|
- **FR4:** First photo: BG removal - find longest dimension - compute scale
|
|
(longest_px / user-length) - compute area (sqft) - bdft = sqft * thickness / 12.
|
|
- **FR5:** All photos: BG removal - crop to 80% frame fill - save as transparent PNG,
|
|
minimum 1600 px on smaller dimension, aspect ratio preserved.
|
|
- **FR6:** User can retake the first photo or abort and start fresh.
|
|
|
|
### Dimensions and calculations
|
|
- **FR7:** Compute length (user-entered), area (sqft), and bdft deterministically.
|
|
- **FR8:** Thickness is always manually entered and treated as authoritative.
|
|
- **FR9:** All dimension math must be deterministic, unit-tested, and reproducible.
|
|
|
|
### Taxonomy (WooCommerce sync)
|
|
- **FR10:** Sync categories, attributes, and tags from WooCommerce and cache locally.
|
|
- **FR11:** Species category: 1 required, leaf-only selection.
|
|
- **FR12:** Wood Category: 1+ required, leaf-only selection (parents shown for grouping only).
|
|
- **FR13:** Edge Type attribute: 1 required.
|
|
- **FR14:** Figure attribute: 1+ required.
|
|
- **FR15:** Grade attribute: 1+ required.
|
|
- **FR16:** Thickness attribute: 1 required, mapped by rounding up user-entered
|
|
thickness to nearest Woo attribute range.
|
|
- **FR17:** Tags: fig-* only, 1+ required.
|
|
- **FR18:** Auto-assign taxonomy based on inference results; allow manual override.
|
|
|
|
### Pricing engine
|
|
- **FR19:** UI to define bdft pricing rules by species and wood category.
|
|
- **FR20:** Deterministic bdft calculation and application of pricing rules to produce
|
|
a price recommendation.
|
|
- **FR21:** Price recommendation editable by user; final price stored as authoritative.
|
|
|
|
### Inference (two-call architecture)
|
|
- **FR22:** Call 1 (vision): auto-run after calibration. Input: all inventory photos
|
|
(downscaled to 1024px max, using original pre-crop photos), user metadata, synced
|
|
Woo taxonomy. Output: species, wood categories, edge type, figure, grade,
|
|
character/inclusions/voids/checks with severity, top 3 wood categories with
|
|
confidence. If no species match above threshold, omit and require manual selection.
|
|
- **FR23:** Call 2 (text): user-triggered after Call 1 curation. Input: deterministic
|
|
data + Call 1 results + brand voice + GEO context. Output: title, description,
|
|
short description.
|
|
- **FR24:** Inference prompts stored server-side, editable in settings, reset-to-default available.
|
|
- **FR25:** Progress indicator during inference calls (latency expected).
|
|
- **FR26:** Timeout >45s or non-200 - visible error with retry option.
|
|
- **FR27:** All inference results editable; no automatic publish of LLM output.
|
|
- **FR28:** Inference endpoint configured via settings: base URL, API key, model name.
|
|
Test connection verifies text + vision support.
|
|
|
|
### Photo normalization and output
|
|
- **FR29:** Background removal: chroma-key for green/black, fallback to U2Net matting.
|
|
- **FR30:** Crop to 80% frame fill, slab centered, aspect ratio preserved,
|
|
minimum 1600 px on smaller dimension.
|
|
- **FR31:** Output as transparent PNG (ideal for WooCommerce).
|
|
- **FR32:** Store both original and processed images. Purge after successful publish.
|
|
|
|
### WooCommerce sync and publish
|
|
- **FR33:** Authenticate to WooCommerce using consumer key + App Password.
|
|
- **FR34:** Publish is blocked if the slab SKU already exists (simple dedupe, no update path).
|
|
- **FR35:** Create WooCommerce product with SKU, title, description, short description,
|
|
price, categories, attributes, tags, and normalized PNG images.
|
|
- **FR36:** Default product status: "published" (configurable in settings).
|
|
- **FR37:** Log sync results and surface errors; store WooCommerce product ID on success.
|
|
|
|
### Drafts, review, and publish
|
|
- **FR38:** Maintain a draft slab state with full metadata and photos.
|
|
- **FR39:** Provide a single review screen showing all fields; every field is editable.
|
|
- **FR40:** Publish action performs deterministic server-side processing and WooCommerce
|
|
sync; update status to Published/Failed with error details.
|
|
|
|
### Configuration and hosting
|
|
- **FR41:** Settings UI for inference endpoint, Woo credentials, pricing rules,
|
|
brand voice, GEO context, prompts.
|
|
- **FR42:** App deploys via Docker Compose on .201 with Caddy for HTTPS.
|
|
- **FR43:** All secrets stored encrypted at rest; all client-server traffic over HTTPS.
|
|
|
|
## Non-functional requirements
|
|
- **Performance:** Client capture and local processing within 1-2s; server normalization
|
|
within 3-5s per slab; inference calls within 45s.
|
|
- **Reliability:** Deterministic logic fully unit-tested.
|
|
- **Security:** Encrypted secrets, HTTPS, minimal persistent credentials on client.
|
|
- **Maintainability:** Clear separation of deterministic code and inference code.
|
|
- **Usability:** One-hand operation, large touch targets, clear distinction between
|
|
internal processing and customer-facing output.
|
|
|
|
## Architecture and tech stack
|
|
|
|
**Client (mobile web / PWA)**
|
|
- SvelteKit (mobile-first)
|
|
- TailwindCSS for UI
|
|
- Camera API for capture and immediate preview
|
|
- No OCR, no OpenCV on client
|
|
|
|
**Server (self-hosted, containerized)**
|
|
- FastAPI (Python) for deterministic image pipeline, bdft math, pricing,
|
|
background removal, crop/normalize, WooCommerce REST integration,
|
|
inference wrappers, taxonomy sync
|
|
- SQLite for v1 (slab records, pricing rules, taxonomy cache, sync history)
|
|
|
|
**Inference**
|
|
- Configurable OpenAI-compatible endpoint (user supplies base URL, key, model).
|
|
Must support vision. Two calls: wood expert (vision) + content generation (text).
|
|
All inference calls logged.
|
|
|
|
**Deployment**
|
|
- Docker Compose with frontend and fastapi services on .201.
|
|
- Caddy for HTTPS and reverse proxy.
|
|
|
|
**Security**
|
|
- AES encryption for stored secrets.
|
|
- No app-level auth in v1.
|
|
- HTTPS enforced.
|
|
|
|
### Pricing rule schema
|
|
id: uuid
|
|
species: string
|
|
wood_category: string
|
|
price_per_bdft: float
|
|
created_at: timestamp
|
|
updated_at: timestamp
|
|
|
|
## Key flows and acceptance criteria
|
|
|
|
### Capture -> Calibrate -> Infer -> Publish flow
|
|
1. New slab: user stages slab and opens app.
|
|
2. Capture: take 1-5 inventory photos.
|
|
3. Enter metadata: SKU, length, thickness.
|
|
4. Calibration: server processes first photo (BG removal, area, bdft),
|
|
processes all photos (BG removal, crop, PNG).
|
|
5. Inference: Call 1 auto-runs (vision), populating taxonomy/content.
|
|
User reviews/corrects. Call 2 user-triggered (text), generating
|
|
title/description/short description.
|
|
6. Review: user edits/overrides any field.
|
|
7. Publish: user triggers publish; FastAPI syncs taxonomy, creates
|
|
WooCommerce product, purges images. Status updated and logged.
|
|
|
|
### Acceptance criteria
|
|
- End-to-end slab capture to published product works on modern iPhone and Android browsers.
|
|
- Area measurement accuracy within +/- 0.25 in^2.
|
|
- Photo normalization produces 80% frame fill, transparent PNG, 1600px min on smaller dim.
|
|
- WooCommerce product created with normalized images, correct taxonomy, and correct content.
|
|
- Deterministic functions covered by unit tests; inference calls logged.
|
|
|
|
## Operational and debugging notes
|
|
- Local dev: Docker Compose with frontend and fastapi. Mobile testing over LAN/Tailscale.
|
|
- Logging: centralized logs per service; inference request/response payloads stored for audit.
|
|
- Testing: unit tests for deterministic math and image processing; integration tests
|
|
for WooCommerce sync against a staging store.
|
|
- Secrets: store App Passwords and inference keys encrypted; rotate keys periodically.
|
|
- Monitoring: health endpoints and job queue visibility.
|