# Module: `src/types/index.ts`

> **Source**: `src/types/index.ts` (161 lines)
> **Topo batch**: B1 (leaf — no internal imports)

## Purpose

Shared TypeScript contract surface for the SPA: pure type aliases, interfaces, and numeric enums describing the DTOs that travel between the React UI and the suite backends (`admin/`, `annotations/`, `flights/`, `loader/`, etc.).

## Public interface

Generic shape:

| Symbol | Kind | Notes |
|---|---|---|
| `PaginatedResponse<T>` | `interface` | `{ items, totalCount, page, pageSize }`. Returned by paged list endpoints (e.g., `GET /api/flights?pageSize=...`). |

Domain entities (mirroring backend DTOs):

| Symbol | Kind | Backing concept |
|---|---|---|
| `Media` | `interface` | A media file (image / video) attached to a flight. Fields: `id, name, path, mediaType, mediaStatus, duration, annotationCount, waypointId, userId`. |
| `Detection` | `interface` | A bounding box. Fields: `id, classNum, label, confidence, affiliation, combatReadiness, centerX, centerY, width, height` (normalized 0–1 coords, see `_docs/legacy/wpf-era.md` §10). |
| `AnnotationListItem` | `interface` | A frame's annotation set. `time` is `string \| null` (ISO duration), `splitTile` carries tile zoom info for split-image detections. Embeds `Detection[]`. |
| `DetectionClass` | `interface` | Admin-managed detection class metadata (`id, name, shortName, color, maxSizeM, photoMode`). Drives the Detection Classes panel + GSD validation. |
| `Flight`, `Aircraft`, `Waypoint` | `interface` | Flight feature entities. `Aircraft.type` is union `'Plane' \| 'Copter'`. |
| `SystemSettings`, `DirectorySettings`, `CameraSettings`, `UserSettings` | `interface` | Settings domain. `UserSettings` carries the global `selectedFlightId` plus per-page panel widths persisted server-side via the annotations API (see `src/components/FlightContext.tsx`). |
| `DatasetItem` | `interface` | Row in the Dataset Explorer grid (`annotationId, imageName, thumbnailPath, status, createdDate, createdEmail, flightName, source, isSeed, isSplit`). |
| `ClassDistributionItem` | `interface` | Aggregate row for the Class Distribution chart. |
| `User` | `interface` | Admin user list row. |
| `AuthUser` | `interface` | Authenticated session user (`id, email, name, role, permissions[]`); used by `AuthContext`. |

Numeric enums (must match backend wire values bit-for-bit):

| Enum | Members | Used by |
|---|---|---|
| `MediaType` | `None=0, Image=1, Video=2` | media list, video player branching |
| `MediaStatus` | `New=0, AiProcessing=1, AiProcessed=2, ManualCreated=3` | media list state |
| `AnnotationSource` | `AI=0, Manual=1` | annotation provenance |
| `AnnotationStatus` | `Created=0, Edited=1, Validated=2` | dataset filter buttons |
| `Affiliation` | `Unknown=0, Friendly=1, Hostile=2` | bounding-box icon (see `_docs/legacy/wpf-era.md` §10) |
| `CombatReadiness` | `NotReady=0, Ready=1` | bounding-box readiness dot |

## Internal logic

None. Declarations file only.

## Dependencies

- **Internal**: none (true leaf).
- **External**: none.

## Consumers (intra-repo)

`src/auth/AuthContext.tsx`, `src/components/FlightContext.tsx`, `src/components/Header.tsx`, `src/components/DetectionClasses.tsx`, `src/api/*` (none directly — API calls are typed at call sites), every page under `src/features/*` except `src/features/login/LoginPage.tsx`. Roughly 15 importing files.

## Data models

The whole module **is** the data-model surface for the SPA. Two implicit constraints:

1. **Numeric enum values are wire-coupled** — changing them silently breaks every backend that returns the same number. Treated as a public contract; downstream changes must coordinate with the corresponding `.NET` / Cython service.
2. **`*.id` is `string`** for every entity (suite uses GUIDs), but `Detection.classNum` and the four enums are `number`. Mixed-key shapes are intentional.

## Configuration

None.

## External integrations

None directly. The types are the *contract* surface for HTTP responses from `/api/admin/*`, `/api/annotations/*`, `/api/flights/*`. Ground truth for shapes lives in the respective backend submodule (`suite/admin/`, `suite/annotations/`, `suite/flights/`).

## Security

`AuthUser.permissions: string[]` is the only security-relevant field — checked by `AuthContext.hasPermission(perm)`. The permission strings are not enumerated here; they are defined by the `admin/` service.

## Tests

None.

## Notes / open questions

- `Media.duration` is `string | null` rather than `number | null` — this matches a `TimeSpan`-style ISO duration the backend returns. Document the format precisely once the consumer (`VideoPlayer`) is reached in B7.
- `UserSettings` mixes "selected flight" with "per-page panel widths" — possibly a candidate for splitting along ownership lines, but the API endpoint (`/api/annotations/settings/user`) treats them as one document. Out of scope for `/document`.
