[AZ-447] autodev Steps 1-4 baseline: docs, tests, refactor specs

Captures the full output of autodev existing-code Phase A through
Step 4 (Code Testability Revision) for the Azaion UI workspace:

- Step 1 Document: _docs/02_document/ (FINAL_report, architecture,
  glossary, components/, modules/, diagrams/, system-flows,
  module-layout) plus _docs/00_problem/ + _docs/01_solution/ +
  _docs/legacy/ + _docs/how_to_test + README.
- Step 2 Architecture Baseline: architecture_compliance_baseline.md.
- Step 3 Test Spec: _docs/02_document/tests/ (environment,
  test-data, blackbox/performance/resilience/security/
  resource-limit tests, traceability-matrix), enum_spec_snapshot,
  expected_results/results_report.md (98 rows), plus the
  run-tests.sh + run-performance-tests.sh runners.
- Step 4 Code Testability Revision: 01-testability-refactoring/
  run dir (list-of-changes C01-C07, deferred_to_refactor,
  analysis/research_findings + refactoring_roadmap) and the 7
  child task specs AZ-448..AZ-454 under _docs/02_tasks/todo/
  plus _dependencies_table.md.
- _docs/_autodev_state.md pins the cursor at Step 4 / refactor
  Phase 4 entry so /autodev resumes cleanly.

Epic AZ-447 (UI testability gates) tracks the 7 child tasks that
will land in subsequent commits.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-11 00:38:49 +03:00
parent da0a5aa187
commit 510df68bcf
84 changed files with 13065 additions and 0 deletions
@@ -0,0 +1,78 @@
# 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. |
## 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 inlined at every call site (testability finding from autodev Step 4).
## 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** → URL strings duplicated across features. Risk of typos surfacing as 404s only at runtime (Step 4).
## 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` |