Revert "docs(m3): record create build plan and decisions"
This reverts commit 20f08bbc25.
This commit is contained in:
@@ -1,84 +0,0 @@
|
|||||||
# M3 Create — build plan (working record)
|
|
||||||
|
|
||||||
Status: WORKING RECORD · 2026-09-19 · **not normative**.
|
|
||||||
|
|
||||||
`docs/REQUIREMENTS.md` is the only normative text; `docs/MILESTONES.md` holds the M3 ID subset;
|
|
||||||
behavior is in `docs/capabilities/CREATE.md` and `docs/contracts/`. This file records decisions
|
|
||||||
made on 2026-09-19 so a new session does not re-litigate or drift from them. It **cites**
|
|
||||||
requirement IDs; it defines none.
|
|
||||||
|
|
||||||
## 1. Scope
|
|
||||||
|
|
||||||
Implement Milestone 3 only, per the M3 ID subset in `docs/MILESTONES.md` and
|
|
||||||
`docs/capabilities/CREATE.md`. Do not implement outside that subset unless the owner expands scope
|
|
||||||
in chat.
|
|
||||||
|
|
||||||
## 2. Settled contract rulings (owner, 2026-09-19)
|
|
||||||
|
|
||||||
| # | Question | Ruling | Now lives in |
|
|
||||||
|---|---|---|---|
|
|
||||||
| R1 | Soft delete representation | Add `deleted_at TEXT NULL`; deleted rows excluded from all GET responses; status enum unchanged | `docs/contracts/DATA-MODEL.md` §1–2, `docs/contracts/API.md` §4 |
|
|
||||||
| R2 | Publish completion vs the poll endpoint | The terminal poll returns `woo_product_id`; the local working slab row is then discarded; the device draft is cleared client-side; the app **never deletes from WooCommerce** | `docs/REQUIREMENTS.md` PUBLISH-25, `docs/contracts/API.md` §4 + §7, `docs/contracts/DATA-MODEL.md` §1 |
|
|
||||||
| R3 | Prompt storage | SQLite is the point of record (`prompts` + `prompt_revisions`). File-based prompts are **superseded**; no prompt files ship and the `backend/app/prompts:ro` compose mount was removed | `docs/contracts/PROMPTS.md` (unchanged), `deploy/docker-compose.yml`, `docs/DEPLOYMENT.md` |
|
|
||||||
| R4 | `/images` volume | Photo bytes are SQLite BLOBs (source of truth). `/images` holds only a health-probe file and short-lived staging (1024 px Call-1 JPEGs, Woo media uploads), purged after use. Health goes non-200 when the DB or `/images` is unwritable; `woo_reachable:false` stays 200 | `docs/contracts/DATA-MODEL.md` §1, APP-45 |
|
|
||||||
|
|
||||||
## 3. Implementation decisions
|
|
||||||
|
|
||||||
**Stack.** FastAPI + stdlib `sqlite3` + `schema.sql` (`CREATE TABLE IF NOT EXISTS`). No SQLAlchemy,
|
|
||||||
no Alembic. Pragmas `journal_mode=WAL`, `foreign_keys=ON`, `busy_timeout`, `synchronous=NORMAL`;
|
|
||||||
one process-wide connection behind a lock. The app factory takes `db_path` and `image_dir` so tests
|
|
||||||
get per-test isolation. Revisit an ORM/migrations only after real UAT data exists.
|
|
||||||
|
|
||||||
**Async (202 + poll).** One in-process job queue with a single consumer — **not** FastAPI
|
|
||||||
`BackgroundTasks` (Starlette background tasks make TestClient 202 tests accidentally synchronous).
|
|
||||||
Status transitions CAS inside `BEGIN IMMEDIATE`. Tests run the queue in an inline mode so contract
|
|
||||||
tests stay deterministic.
|
|
||||||
|
|
||||||
**Photos.** `slab_photos.original_blob` / `processed_blob` are the source of truth; `/images` per R4.
|
|
||||||
|
|
||||||
**Prompts.** DB-only with revisions per R3.
|
|
||||||
|
|
||||||
**Publish.** Per R2 and `docs/contracts/API.md` §7 + `docs/contracts/CONTENT-WOO.md`. On success:
|
|
||||||
set `woo_product_id`, purge photos, delete the working row after the terminal poll is served, clear
|
|
||||||
the device draft. `SLAB-UAT-*` always creates a draft. `max_upload_size` is checked before media
|
|
||||||
upload (`docs/contracts/WOO-API.md` §10).
|
|
||||||
|
|
||||||
**Other.**
|
|
||||||
- `ready` is server-derived from the REVIEW-5 set.
|
|
||||||
- SKU is entered at the Measure step (UX §2.5); do not widen the Capture union.
|
|
||||||
- The server stores client-sent derived numbers and never recomputes them as source of truth (APP-40).
|
|
||||||
- PUT order: 404 → 409 `revision_conflict` → 409 `duplicate_sku` → 422 `stale_field` → apply → `server_rev++`.
|
|
||||||
- Call 1 fills empty fields only; background inference writes bump `server_rev` and the client adopts the polled rev.
|
|
||||||
- Frontend additions stay outside the Capture union: `frontend/src/api/*`, `frontend/src/create/*`.
|
|
||||||
|
|
||||||
## 4. Slice order
|
|
||||||
|
|
||||||
| Slice | Delivers | M3 IDs |
|
|
||||||
|---|---|---|
|
|
||||||
| S0 | factory, config/startup guards, health/meta, JSON logs, Dockerfile | APP-30, APP-45, APP-55, APP-65, SETTINGS-10, SETTINGS-25, OPS-25 |
|
|
||||||
| S1 | AES-GCM crypto + Settings (masked, write-only secrets) | SETTINGS-5/15/20/25/30/35/75/85/90, QUALITY-125 |
|
|
||||||
| S2 | slabs CRUD, optimistic concurrency, soft delete | APP-5/15/20/35/40, REVIEW-45 |
|
|
||||||
| S3 | photos (multipart → BLOBs, original/processed, 410 after purge) | CAPTURE-95/105/130, PUBLISH-40 |
|
|
||||||
| S4 | Woo client (app-password Basic) + taxonomy sync + test-woo | METADATA-5/10/15/20/30, SETTINGS-40/50/51/55/60/80, QUALITY-35 |
|
|
||||||
| S5 | pricing, deterministic templates, server-derived ready | REVIEW-5/10/15/20/25/30/35/40/50, METADATA-70/80/85/90, QUALITY-90/95 |
|
|
||||||
| S6 | publish (sequence, UAT draft, duplicate/stale/partial-failure) | PUBLISH-5/10/15/20/25/30/31/35/36/37/38/40/45/50/55/60 |
|
|
||||||
| S7 | inference last (Call 1/Call 2, prompt revisions, templates fallback) | METADATA-35/40/45/50/55/60/65/66/75/95/100/105/110/115, SETTINGS-45/70 |
|
|
||||||
| Cross | frontend API client + Review / Settings / Publish screens | (UI for the slices above) |
|
|
||||||
| Exit | inference-off suite, Woo-mock integration, Compose UI E2E, real UAT draft | QUALITY-20/35/50/105/110/120 |
|
|
||||||
|
|
||||||
TDD every slice: the failing test precedes its implementation; never parallelize RED and GREEN of
|
|
||||||
the same scenario.
|
|
||||||
|
|
||||||
## 5. Guardrails
|
|
||||||
|
|
||||||
- Subagents run on a single local GPU: **one at a time, never in parallel**.
|
|
||||||
- Agents never declare a gate green; Ty owns gate exit (QUALITY-25, QUALITY-30).
|
|
||||||
- Run `python tools/check_requirements.py` after any docs change; it must pass.
|
|
||||||
- Ports `10880`–`10889` are this project's; never bind `:10880`. Dev-test runs on `:10881`, bound `0.0.0.0`.
|
|
||||||
- Create must work with inference off (zero inference calls) — QUALITY-20.
|
|
||||||
- No raw status codes, stack traces, or internal codes reach the owner — QUALITY-120.
|
|
||||||
|
|
||||||
## 6. Not yet validated
|
|
||||||
|
|
||||||
- Long-horizon multi-step agentic loops (more than one or two tool round-trips).
|
|
||||||
- M3 implementation has not started; this file is the pre-build record.
|
|
||||||
Reference in New Issue
Block a user