Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-2186Done

11.4.5 Declare the remaining `/api/v1` operations — projects, sprints, backlog, ready set, workspaces and `/me` — so the document covers the whole surface

Repo: motir-core. One PR. 11.4.4 proved the registry and the emitter on the work-item resource. This card finishes the surface: every remaining /api/v1 endpoint gets its operation declaration, so the emitted document describes the whole API rather than a sample of it.

The work is mechanical but not clerical — each declaration is a claim about what the route actually does, and each one has to be read off the route and its schema module rather than off memory or off the sibling above it.

Do NOT work from a list written here. A hard-coded inventory of endpoints goes stale the moment a route is added or renamed. Instead walk app/api/v1 for every route.ts and every HTTP method it exportsv1RouteFiles() in tests/helpers/v1RouteAudit.ts:38 already does exactly this walk, and declaredScopeByMethod() (line 166) already reads the scope each method declares — and declare an operation for each. Today that covers /me, workspaces, projects and the project resource, the project-scoped sprints / backlog / backlog work-items / ready collections, and the sprint resource with its start, complete and membership routes; tomorrow it covers whatever the walk returns.

For each operation, take from the route and its schema module: the path parameters, the query parameters it parses, the request body schema where it has one, which of the two page envelopes it returns (the ranked one carrying totalCount, or the plain cursor page — Amendment 3 Q2 decided this per endpoint, so read that section rather than inferring), the scope it declares, and the error statuses it can raise.

Two things worth reading before declaring rather than after: lib/api/v1/rankedCollections.ts (which collections are ranked and therefore counted) and lib/api/v1/pagination.ts's V1_COLLECTIONS (the collection vocabulary a cursor is scoped to).

Scope BOUNDARY

Ends at the operation declarations. It builds no machinery — the descriptor type, the registry and the emitter are 11.4.4's. It authors no schema, shared or per-resource. It builds no CI guard: proving the document and the routes cannot disagree is 11.4.6, which needs this card's completeness to be assertable at all. It changes no route's behaviour, path, parameters or response — where a route's real behaviour differs from what its declaration would naturally say, the declaration follows the route and the discrepancy is recorded as a finding, never corrected by editing the endpoint.

Acceptance criteria

  • Every route.ts under app/api/v1 — discovered by walking the tree, not from a list — has an operation declared for each HTTP method it exports, with the sole exception of the spec route itself, which is named explicitly as the exception.
  • A test drives that same walk and fails if any exported method has no operation, so a route added later without a declaration fails rather than silently going undocumented.
  • Each collection operation references the envelope its route genuinely returns, with the ranked-vs-plain choice traceable to Amendment 3 Q2 rather than guessed.
  • Each operation's declared scope equals the scope its route file declares, asserted by comparing against declaredScopeByMethod().
  • Each operation names the error statuses that route can actually raise, drawn from DOMAIN_ERROR_STATUS and the ADR §4 table — including 409 and 412 where the write endpoints use them.
  • The assembled document still validates as OpenAPI 3.1 with the full operation set present.
  • No file under app/api/v1/** changes behaviour; any route-vs-declaration discrepancy found is written up as a bug against the owning story, not fixed here.
  • New files join the per-file coverage thresholds in vitest.config.ts at the ≥90% floor.

Context refs

  • tests/helpers/v1RouteAudit.tsv1RouteFiles() (the route walk) and declaredScopeByMethod() (the per-method scope read).
  • lib/api/v1/projects/schema.ts · lib/api/v1/sprints/schema.ts · lib/api/v1/ready/schema.ts — the per-resource schemas 11.3 shipped, which these operations reference.
  • lib/api/v1/rankedCollections.ts · lib/api/v1/pagination.ts — which collections are ranked and counted, and the collection vocabulary.
  • lib/api/v1/sprints/membership.ts — the sprint-membership route's shape.
  • docs/decisions/public-api-conventions.md — §3 the operation→scope table, §4 the status table, Amendment 3 (cursors, totalCount, the by-id carve-out).
  • Blocker: 11.4.4. Parent story: 11.4.