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-2068Done

11.3.11 End-to-end conformance — drive the whole planning cadence as an EXTERNAL HTTP client with a real PAT

11.3's E2E, in the form the story actually has: the client is curl, so the acceptance is a conformance suite that drives the endpoints from outside — a real minted PAT in an Authorization header, real routes, real Postgres, no in-process shortcuts and no service imports to set up state the API itself can create.

This is the story's verification_recipe, automated. The vitest gate (11.3.10) proves the parts; this proves the JOURNEY — and it is the only test that can, because every seam it crosses is one no single route's unit test owns.

No acceptance video — no user-observable surface, so the story accepts on its tests alone, exactly as 11.1 and 11.2 did.

The walk

The journey step, end to end, as one ordered scenario:

list projects → read one → list its sprints → create a sprint → move a batch of backlog items into it → read the sprint's members → read the backlog and find them gone → start the sprint → read the baseline → ask what is ready → complete the sprint → find the unfinished work back in the backlog.

Every step is an HTTP call whose ONLY input is what a previous response returned — a projectKey from the project list, a sprintId from the create, MOTIR-<n> keys from the backlog. That constraint is the point: it proves the API is navigable by a client that started with nothing but a token, which is the actual claim this story makes. A step that needs a value no response carries is a finding, not a fixture to hard-code.

What only this level can catch

  • The Location header on create is followable — issue the create, then GET the URL it returned verbatim.
  • A cursor survives a round trip through a real client — page a collection to exhaustion using only nextCursor, and confirm the union equals the collection with no skips or duplicates.
  • The rate-limit headers are present on every response, success and refusal alike, and a full paged scan of a realistic collection does not trip the 60/min budget (11.1's shipped seam test, re-run over this story's collections).
  • Refusals are refusals, over HTTP: a read-only token gets 403 on every sprint write and both membership moves; a sprints:write token whose owner is not a sprint admin gets 403 too, with a distinguishable code; a token from another workspace gets 404 on every path taking a projectKey or sprintId.
  • Nothing leaks an internal cuid for a work item anywhere in the journey's responses.

Acceptance criteria

  • The whole walk above runs as one ordered scenario against real routes + real Postgres with a real minted PAT, using only values returned by previous responses.
  • The suite drives the API as an EXTERNAL client — it does not import a service, a repository or Prisma to arrange or assert state that the API itself exposes. (Minting the token and creating the tenant fixture are the permitted exceptions, exactly as the shipped conformance suites do it.)
  • Both refusal sweeps are asserted per endpoint, not once: read-only → 403 on every write; a non-admin sprints:write owner → 403; another workspace's resource → 404 on every keyed path.
  • A paged scan driven purely by nextCursor returns each row exactly once, over a collection larger than one page.
  • The Location header returned by sprint create resolves to the created sprint.
  • Every response carries x-request-id and the X-RateLimit-* headers; the journey completes inside the per-token budget.
  • Failures name the STEP that failed, not just an assertion — a conformance suite that fails as "expected 200, got 404" on line 300 costs more than it saves.
  • ONE PR against motir-core.

Context refs

  • tests/api/v1/conformance.test.ts — 11.1's shipped external-client harness: PAT minting, the real-route driver, and the fixture conventions to reuse.
  • tests/api/v1/work-item-conformance.test.ts11.2.12's journey suite, the direct precedent for this card's shape.
  • lib/apiTokens/ — how a scoped token is minted for a test, including a read-only grant.
  • docs/decisions/public-api-conventions.md §3 (the scope table), §4 (the status table), §6 (the 60/min budget + headers).
  • Blockers: every code subtask of this story — 11.3.2, 11.3.3, 11.3.4, 11.3.5, 11.3.6, 11.3.7, 11.3.8, 11.3.9. Parent story: 11.3.