# 01 — API Transport

## 1. High-Level Overview

**Purpose**: Thin wrappers over the browser's `fetch` and `EventSource` that every feature uses to talk to the suite backend. Sole owners of cookie / bearer / refresh-token plumbing on the wire.

**Architectural Pattern**: HTTP/SSE facade. No service-specific clients — every feature passes string URLs directly.

**Upstream dependencies**: `00_foundation` (types).

**Downstream consumers**: `02_auth`, `03_shared-ui` (FlightContext, DetectionClasses), `05_flights`, `06_annotations`, `07_dataset`, `08_admin`, `09_settings`.

## 2. Internal Interfaces

### `src/api/client.ts`

| Export | Signature | Notes |
|--------|-----------|-------|
| `api.get<T>(url, opts?): Promise<T>` | thin `fetch` wrapper | Adds `credentials: 'include'`, parses JSON, throws on non-2xx |
| `api.post<T>(url, body?, opts?): Promise<T>` | same | |
| `api.put<T>(url, body?, opts?): Promise<T>` | same | |
| `api.del<T>(url, opts?): Promise<T>` | same | |
| `ApiError` | error class | Thrown with `{ status, body }` on non-2xx |

### `src/api/sse.ts`

| Export | Signature | Notes |
|--------|-----------|-------|
| `subscribe<T>(url, onMessage, onError?): { close }` | factory | Creates `EventSource` with the **bearer token in the query string** (browser `EventSource` can't set headers). Returns a `close()` handle. |

### `src/api/endpoints.ts` (since AZ-486 / F7)

| Export | Signature | Notes |
|--------|-----------|-------|
| `endpoints` | `Readonly<{ admin, annotations, flights, detect }>` of typed builder functions | Single source of truth for every `/api/<service>/...` URL the UI talks to. Each leaf is a function — `() => string` for constant paths, `(id, ...) => string` for parameterised ones. Wire-contract pinned by `src/api/endpoints.test.ts` (36 assertions). |

### `src/api/index.ts` (Public API barrel, since AZ-485 / F4)

Re-exports the component's public surface: `api`, `createSSE`, `setToken`, `getToken`, `getApiBase`, `setNavigateToLogin`, `endpoints`. Consumers OUTSIDE this component MUST import from the barrel; direct imports of `src/api/{client,sse,endpoints}` from other components are blocked by `STC-ARCH-01`.

## 3. External API Specification

This component does not *expose* an API; it consumes the suite's. The set of consumed endpoints (collected from feature module docs):

| Service | Path prefix (after nginx strip) | Used by |
|---------|---------------------------------|---------|
| `admin/` auth | `/api/admin/auth/{login,refresh,logout,me,...}` | `02_auth`, `08_admin` |
| `flights/` | `/api/flights/...` | `03_shared-ui` (FlightContext), `05_flights` |
| `annotations/` | `/api/annotations/...` | `06_annotations`, `07_dataset`, `08_admin` (read) |
| `detect/` | `/api/detect/...` | `06_annotations` |
| `loader/`, `resource/`, `gps-denied-*`, `autopilot/` | `/api/{loader,resource,gps-denied-desktop,gps-denied-onboard,autopilot}/...` | various features |

**No service-specific client modules exist**. URL strings are produced by typed builders in `src/api/endpoints.ts` (added by AZ-486 / F7, commit `8a461a2`) — the previous "URL strings inlined at every call site" testability finding (F7) is **CLOSED**. The `STC-ARCH-02` static gate (`scripts/check-arch-imports.mjs --mode=api-literals`, wired into `scripts/run-tests.sh`) forbids re-introducing `/api/<service>/...` literals under `src/`.

## 5. Implementation Details

| Concern | Behavior |
|---------|----------|
| Auth bootstrap | `client.ts` does NOT auto-attach `credentials: 'include'` on the very first call from `AuthContext` startup — finding B3 (`src__auth__AuthContext.md`). Cookie-based session bootstrap therefore fails on first refresh. **PRIORITY for Step 4.** |
| Refresh-token rotation | Server rotates access tokens via `X-Refresh-Token` header. `client.ts` handles refresh on 401 for fetch; `sse.ts` does **NOT** — `EventSource` holds the bearer captured at create time and dies after rotation (finding in `src__api__sse.md`). |
| Timeouts | None — no `AbortController` wired up. Long requests (e.g., dataset bulk export) can hang indefinitely. Step 4. |
| Error reporting | `ApiError` thrown to caller. Most features `catch` and call `alert()` or `console.error` silently — uneven across features. |

**State Management**: Module-level only — `sse.ts` keeps no registry; each subscription is independent.

**Key Dependencies**: native `fetch`, native `EventSource`. No third-party HTTP library.

## 7. Caveats & Edge Cases

- **No timeout / cancellation**. (Step 4.)
- **Bearer in SSE query string**. Accepted trade-off; document in `security_approach.md` (Step 6).
- **No reconnect-on-token-rotate** for SSE consumers — every feature that uses SSE will silently stop receiving events after the first refresh (Step 8 hardening).
- ~~No service-specific clients~~ → **CLOSED by AZ-486 / F7**: URL strings centralised in `src/api/endpoints.ts`; STC-ARCH-02 enforces it. Typos now surface at build time (TS strict on the builder names) or in `endpoints.test.ts`, never at runtime.

## 8. Dependency Graph

**Must be implemented after**: `00_foundation`.

**Can be implemented in parallel with**: `00_foundation` (it has no internal deps beyond types).

**Blocks**: `02_auth`, every feature page, `03_shared-ui` (FlightContext, DetectionClasses).

## Module Inventory

| Path | Module Doc |
|------|------------|
| `src/api/client.ts` | `_docs/02_document/modules/src__api__client.md` |
| `src/api/sse.ts` | `_docs/02_document/modules/src__api__sse.md` |
| `src/api/endpoints.ts` | `_docs/02_document/modules/src__api__endpoints.md` |
| `src/api/index.ts` (barrel) | (no separate doc — re-exports surface listed in §2 above) |
