Phase B cycle 1 was a structural refactor only: F4 (barrel imports + STC-ARCH-01) and F7 (endpoint builders + STC-ARCH-02). This commit brings docs in line with source after the cycle, no code changes. Module docs (12 consumers): swap every /api/<service>/... literal in code snippets and integration tables for the matching endpoints.* builder; note the barrel import migration in Dependencies. New module doc: src__api__endpoints.md (public surface, F4 barrel re-export note, STC-ARCH-02 enforcement, contract-test reference). Architecture compliance baseline: mark F4 + F7 CLOSED with commit hashes (23746ec,8a461a2). 01_api-transport component description: add endpoints.ts + barrel to Internal Interfaces, close the F7 caveat, extend Module Inventory. ripple_log_cycle1.md: Task Step 0.5 reverse-dep analysis records the import-graph closure (no extra docs needed beyond the direct set). Carry-over reports landed alongside the docs: - test_run_report_phase_b_cycle1.md (Step 11 outcome) - implementation_report_refactor_phase_b_cycle1.md (cycle summary) State file: trimmed to the autodev <30-line target; Steps 14 + 15 recorded as SKIPPED with rationale (no security or perf surface changed in this cycle); pointer moved to Step 16 (Deploy). Co-authored-by: Cursor <cursoragent@cursor.com>
5.6 KiB
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 insrc/api/endpoints.ts; STC-ARCH-02 enforces it. Typos now surface at build time (TS strict on the builder names) or inendpoints.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) |