Skip to content

feat: M1 demand ledger — RFQ capture, studio-types, /api/v1 surface - #2

Merged
lgalabru merged 2 commits into
mainfrom
feat/m1-demand-ledger
Aug 1, 2026
Merged

feat: M1 demand ledger — RFQ capture, studio-types, /api/v1 surface#2
lgalabru merged 2 commits into
mainfrom
feat/m1-demand-ledger

Conversation

@lgalabru

@lgalabru lgalabru commented Aug 1, 2026

Copy link
Copy Markdown
Member

M1 of PLAN.md: the demand ledger — capture pay.sh catalog misses as structured, buyer-attributed RFQs.

What

  • studio-types — wire/domain types (NewRfq, Rfq, Amount, FieldError) with field validation and schemars derives (pin schemars = "1", matching buzz). schemas/rfq.json is generated from the types (just schemas); a drift test fails CI if it goes stale, and the conformance suite keeps schema and validate() agreeing on example payloads.
  • studio-core::rfq::capture(new, id, now) — pure submission→record path; handlers only supply uuid + clock, so a CLI/MCP reuses the same logic.
  • API under /api/v1POST/GET /api/v1/rfqs, GET /api/v1/rfqs/{id}, plus discovery: GET /api/v1 (endpoint index) and GET /api/v1/schemas/{name}. Validation failures are 422 with { errors: [{ field, message }] }; unknown fields rejected, not dropped. /healthz stays unversioned.
  • studio-store::rfqs — STRICT rfqs table (migration 0002), restart-survival test.

Verification

  • just ci green: fmt, clippy -D warnings, 30 tests (incl. schema drift, discovery contract, store reopen).
  • Live curl demo: index → schema fetch → 404 with available list → capture 201 → invalid 422 with field errors.

Note: design docs (draft-00) keep unversioned /rfqs shorthand; doc pass rides the next ARCHITECTURE touch.

…oints

studio-core::NewRfq/Rfq with frictionless-capture validation (only an empty
query or a malformed buyer npub rejects; budget/product/monetization are
optional signal — never tax the order book). bech32 structural npub check;
signature verification stays a substrate concern for M3.

schemas/rfq.json is the interoperable wire contract; a conformance test
suite validates the same example payloads against both the JSON Schema and
NewRfq::validate so the two cannot drift.

studio-store::rfqs: insert/get/list_since over a STRICT rfqs table
(migration 0002), competition as a JSON column, budget as nullable
amount+mint pair with a Corrupt error if the pair is half-set. Restart
survival covered by a tempfile reopen test.

studio-api: POST /rfqs (201 / 422 with field errors, including unknown
fields), GET /rfqs/{id} (200/404), GET /rfqs?since=rfc3339 (422 on bad
timestamp). Shape errors are deserialized by hand so they surface as 422
field errors rather than axum's opaque rejection.

Projection caveat recorded in migration 0002: rfq rows are API-authored and
not yet rebuildable from substrates — raised at the M1 boundary.

Verified: just ci green (24 tests); live curl demo incl. process restart.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lgalabru
lgalabru force-pushed the feat/m1-demand-ledger branch from d8d9e35 to 9922ef5 Compare August 1, 2026 15:34
…emas

Introduce studio-types as the single source of the wire contract: NewRfq/
Rfq/Amount/FieldError move there with schemars JsonSchema derives (pin
schemars = "1", matching the buzz workspace). schemas/rfq.json is now
generated from the types (just schemas); a drift test fails CI when the
checked-in file is stale, and a registry test catches orphan schema files.
The behavioral conformance suite (schema and validate agree on examples)
moves with the types and stays.

Routes move under /api/v1, with GET /api/v1 (endpoint index) and
GET /api/v1/schemas/{name} (serves the generated schemas, 404 lists what
exists) for discoverability. /healthz stays unversioned.

Handler assembly centralizes in studio-core::rfq::capture(new, id, now) —
a pure fn, so a CLI/MCP surface reuses the exact submission->record path;
the HTTP handler only supplies uuid and clock. studio-store now depends on
studio-types directly; studio-core re-exports the types.

Design docs keep unversioned path shorthand (/rfqs) — archy folds doc
touch-ups on next ARCHITECTURE pass.

Verified: just ci green (30 tests incl. new drift + discovery contract
tests); live curl demo of /api/v1 index, schema fetch, 404, capture, 422.
@lgalabru lgalabru changed the title Feat/m1 demand ledger feat: M1 demand ledger — RFQ capture, studio-types, /api/v1 surface Aug 1, 2026
@lgalabru
lgalabru merged commit f43ccad into main Aug 1, 2026
1 check passed
@lgalabru
lgalabru deleted the feat/m1-demand-ledger branch August 1, 2026 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant