AGENTS.md@web/src/api · git:20260819.fefe3c9 · 2026-08-19 · sha256 13312ced3f2f8988
AGENTS.md@web/src/api git:20260819.fefe3c9A
Immutable. This exact content is served forever at /api/v1/blob/13312ced3f2f8988.
# web/src/api — AGENTS.md API-specific guidance under the parent [`web/src` guide](../AGENTS.md). Read it first. For streaming chat contracts also read [`docs/architecture/chat-rendering-pipeline.md`](../../../docs/architecture/chat-rendering-pipeline.md); for tenant/auth behavior read [`docs/architecture/multi-tenant-platform.md`](../../../docs/architecture/multi-tenant-platform.md). Scenario-test conventions live in [`docs/architecture/testing-chat-scenarios.md`](../../../docs/architecture/testing-chat-scenarios.md), with executable scenarios under [`web/src/test/scenarios`](../test/scenarios/) and fixtures under [`web/src/test/fixtures/scenarios`](../test/fixtures/scenarios/). ## Ownership and typed REST wrappers - Keep browser transport in this directory. Components should call exported wrappers rather than constructing `/api/*` requests themselves. - Define request, response, and callback types beside the wrapper. Return domain values (`Promise<Foo>`, `Promise<void>`, `Blob`, or an `AbortController` for a stream), not untyped JSON or `any`. - Encode path segments with `encodeURIComponent`, build query strings with `URLSearchParams`, and set `Content-Type: application/json` only for JSON bodies. - Match names, optionality, casing, status codes, and endpoint paths to the Go handler DTOs. Do not “fix” a backend mismatch with a permissive frontend type. Inspect the relevant handler in `pkg/api/` and update Go, wrapper, consumers, and tests together when a contract changes. ## Auth and team context - Use `teamFetch` from `teamContext.ts` for authenticated/team-scoped API calls. It owns `X-Astonish-Team`, `X-Requested-With`, single-flight 401 refresh/retry, auth-expiry notification, and rejected-team handling. - Do not duplicate token refresh, read auth storage directly, or use bare `fetch` to bypass team context. Use `explicitTeam` only when the operation intentionally targets a team other than the globally active team. - Preserve headers supplied by callers. Team/auth behavior belongs in `teamContext.ts`; endpoint wrappers own only endpoint-specific headers and payloads. ## Response ownership and errors - The wrapper that receives a `Response` owns consuming its body exactly once. Parse success as the declared type; for non-OK responses, consume useful server text/JSON where appropriate and throw an `Error` with endpoint context. - Callers own UI presentation, retries beyond the centralized auth retry, and cancellation lifecycle. Do not swallow failures or return empty values unless the existing API explicitly defines best-effort/fallback behavior. - Clone a response only when middleware must inspect it while preserving the original for its caller (as in team rejection handling). - Keep text, JSON, and binary paths distinct. Artifact media must use `response.blob()`; never decode video or other binary data as text. ## SSE transport - Studio streams use `fetch` + `ReadableStream`, not `EventSource`, because the primary stream is a POST. Buffer decoded chunks across reads, split complete SSE records only at blank-line delimiters, parse `event:` and `data:` fields, then JSON-decode the payload before dispatch. - Preserve backend event names verbatim. Malformed payloads must not corrupt the remaining buffer; transport/HTTP failures go to `onError`, normal EOF to `onDone`. - `connectChat` and `connectChatStream` must parse and expose the same contract. Any parser correction applies to both paths and needs chunk-boundary, malformed-data, abort, HTTP-error, and EOF coverage. - Return an `AbortController`; consumers must abort on unmount, session switch, or superseding connection. Treat `AbortError` as intentional completion, release/cancel readers when refactoring, and never leave a background read loop updating stale React state. ## Verification From `web/`: ```bash npm test -- src/api/__tests__/studioChat.test.ts npm test -- src/api/__tests__/teamContext.test.ts npm test -- src/api/__tests__/<changed-wrapper>.test.ts npm run typecheck ``` Add focused Vitest coverage for URL/body/header construction, typed success parsing, non-OK responses, auth/team behavior, and stream framing/cleanup. Run the full `npm test` when changing shared transport.