Expand description
Project-family capability models (03-01, PROJ-01/02) — the native
/data/api/v1/projects/* CRUD family: wire-faithful camelCase
models, verified path constants/builders, and the ONE per-segment
encoder.
HIGH-confidence endpoints (03-RESEARCH §Verified Endpoint Catalog:
the official 83-api collection + the working ignition-mcp client
agree on every path). Item SHAPES stay MEDIUM until live capture
(research Open Question 2) — hence the #[serde(flatten)] extra
passthrough on ProjectRecord (the 02-02 ModuleInfo pattern:
wire-truth corrections stay cheap).
Serialization discipline (Pitfall 5): every optional field on the
create/modify bodies is Option with skip_serializing_if —
absent means NOT SENT, never an empty-string reference
("parent": "" would point at a nonexistent project). Create
always sends name + enabled; the modify body carries NO name
(the PUT must not rename — rename has its own route) and its
enabled is itself optional so a single-field set never
clobbers the flag.
Path discipline (Pitfall 6): every {name} path segment rides
through [encode_segment] (percent-encoding, NON_ALPHANUMERIC set
— over-encoding is safe and mirrors mcp’s quote(name, safe=''));
a spaced-name recorded-request proof pins it. 03-03’s resource
paths encode per-segment through this same fn but keep their /
separators.
Structs§
- Export
Meta - The export download result — the ZIP was STREAMED to disk (never
buffered in a
Vec<u8>, Pitfall 2) and this is what the response metadata said about it. Not serialized into envelopes (the file is the artifact; the command output model lives in the actions layer). - Import
Outcome - The import result — OPAQUE-SUCCESS (the response body is
unverified MEDIUM; the mcp pattern parses JSON when it can and
falls back to
{"status":"success"}otherwise — restart’s literaltrueis the same family style). - Project
Copy - POST body — copy. Official body keys are
fromName/toName. - Project
Create - POST body — create.
name+enabledare ALWAYS sent; every optional rides only when provided (Pitfall 5 — an absent optional is OMITTED, never an empty string referencing a nonexistent resource). A bare create serializes to exactly{"name":…,"enabled":true}(wiremock recorded-body pin). - Project
Modify - PUT body — modify: the create fields MINUS
name(the PUT must not rename), withenableditself optional so a single-fieldsetnever clobbers it. Same skip-serializing discipline: aset --titlebody is exactly{"title":"T"}(unit-pinned). - Project
Record - One item of the list/find endpoints — typed core + passthrough
(
defaultDb/tagProvider/userSourceand every unmodeled key round-trip so client-seam--jsonstays complete as the gateway evolves). - Project
Rename Body - POST body — rename. The official body key is
name(the NEW name).
Constants§
- PROJECT_
EXPORT_ TIMEOUT - Per-request export timeout (Pitfall 3): 120 s, the logs-download
precedent —
RequestBuilder::timeout, never a second client and never a global change. - PROJECT_
IMPORT_ TIMEOUT - Per-request import timeout (Pitfall 3, the classic default-timeout death): imports are heavy and synchronous (no job IDs — verified), so the upload rides a 300 s budget.