docs(m3): place create decisions in the contracts
- DATA-MODEL.md: storage engine (stdlib sqlite3 + schema.sql, no ORM/migrations), pragmas, per-test isolation. - API.md: revision coupling, async job model, PUT check order, server-derived ready. - PROMPTS.md: no prompt files ship; the DB is the only prompt source.
This commit is contained in:
+10
-3
@@ -36,7 +36,12 @@ The outbound WooCommerce payload is owned by `docs/contracts/WOO-API.md`.
|
|||||||
- **Envelope:** every error is `{ "error": { "code": string, "message": string, "detail": object|null } }`.
|
- **Envelope:** every error is `{ "error": { "code": string, "message": string, "detail": object|null } }`.
|
||||||
- **Lists:** returned in full, no pagination.
|
- **Lists:** returned in full, no pagination.
|
||||||
- **Revisions:** create/update carry `client_rev`; the server echoes `server_rev`; a mismatch is
|
- **Revisions:** create/update carry `client_rev`; the server echoes `server_rev`; a mismatch is
|
||||||
`409 revision_conflict`.
|
`409 revision_conflict`. A background inference write bumps `server_rev`; the client adopts the
|
||||||
|
polled `server_rev` before its next write.
|
||||||
|
- **Async work:** inference and publish run through one in-process job queue with a single
|
||||||
|
consumer; a status transition is compare-and-set inside one write transaction, so a poll never
|
||||||
|
observes a half-applied transition. Tests run the queue inline so contract tests are
|
||||||
|
deterministic.
|
||||||
- **IDs and time:** slab ids are client-generated UUIDv4; timestamps are UTC ISO-8601.
|
- **IDs and time:** slab ids are client-generated UUIDv4; timestamps are UTC ISO-8601.
|
||||||
- **Photos:** `multipart/form-data` with `data` (JSON), `files[]` (original images), and `meta[]`
|
- **Photos:** `multipart/form-data` with `data` (JSON), `files[]` (original images), and `meta[]`
|
||||||
(`{ "seq": n }`). One photo is the calibration photo, chosen by the owner.
|
(`{ "seq": n }`). One photo is the calibration photo, chosen by the owner.
|
||||||
@@ -108,8 +113,10 @@ completion.
|
|||||||
|
|
||||||
### `PUT /api/v1/slabs/{id}`
|
### `PUT /api/v1/slabs/{id}`
|
||||||
Partial update of editable fields plus `client_rev`. Stores client-sent derived fields and does
|
Partial update of editable fields plus `client_rev`. Stores client-sent derived fields and does
|
||||||
not recompute them. `409 revision_conflict`, `409 duplicate_sku` (SKU field actions `edit_sku` /
|
not recompute them. Checks run in order: `409 revision_conflict`, then `409 duplicate_sku` (SKU
|
||||||
`open_existing`), `422 stale_field` (current options included).
|
field actions `edit_sku` / `open_existing`), then `422 stale_field` (current options included).
|
||||||
|
`status` becomes `ready` only when the full required set is present; it is server-derived and a
|
||||||
|
client never sets it.
|
||||||
|
|
||||||
### `DELETE /api/v1/slabs/{id}`
|
### `DELETE /api/v1/slabs/{id}`
|
||||||
Soft delete of unpublished drafts only (sets `deleted_at`); `204`. Deleted rows are excluded from
|
Soft delete of unpublished drafts only (sets `deleted_at`); `204`. Deleted rows are excluded from
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ Status: SPEC · 2026-09-18. Store: SQLite.
|
|||||||
- Photo bytes live in `slab_photos` BLOBs; the `/images` volume is not a second store. It holds a
|
- Photo bytes live in `slab_photos` BLOBs; the `/images` volume is not a second store. It holds a
|
||||||
health-probe file and short-lived staging for 1024 px Call-1 JPEGs and Woo media uploads, purged
|
health-probe file and short-lived staging for 1024 px Call-1 JPEGs and Woo media uploads, purged
|
||||||
after use.
|
after use.
|
||||||
|
- The store is SQLite through the stdlib `sqlite3` module and a checked-in `schema.sql`
|
||||||
|
(`CREATE TABLE IF NOT EXISTS`); there is no ORM and no migration framework. Pragmas are
|
||||||
|
`journal_mode=WAL`, `foreign_keys=ON`, `busy_timeout`, `synchronous=NORMAL`, with one
|
||||||
|
process-wide connection behind a lock. The database path and image directory are explicit so a
|
||||||
|
test runs against isolated storage.
|
||||||
|
|
||||||
## 2. `slabs`
|
## 2. `slabs`
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ Owns prompt storage, prompt inputs, and the two inference calls.
|
|||||||
## 1. Storage and revisions
|
## 1. Storage and revisions
|
||||||
|
|
||||||
- Prompts live in the database, not in text files, with all revisions retained. Tables are in
|
- Prompts live in the database, not in text files, with all revisions retained. Tables are in
|
||||||
`docs/contracts/DATA-MODEL.md` §7.
|
`docs/contracts/DATA-MODEL.md` §7. No prompt files ship with the application; the database is
|
||||||
|
the only prompt source.
|
||||||
- Each call reads the active revision fresh.
|
- Each call reads the active revision fresh.
|
||||||
- Editing a prompt creates a new revision; history is never overwritten.
|
- Editing a prompt creates a new revision; history is never overwritten.
|
||||||
- Every generation is logged with its inputs, the request/response when a model was used, and the
|
- Every generation is logged with its inputs, the request/response when a model was used, and the
|
||||||
|
|||||||
Reference in New Issue
Block a user