# 08 — Admin ## 1. High-Level Overview **Purpose**: Operator-only configuration page. User management, detection-class management, AI Settings, GPS Settings, aircraft default. **Architectural Pattern**: Single-page feature, large monolithic component (~215 lines pre-consolidation per state.json). **Upstream dependencies**: `00_foundation`, `01_api-transport`, `03_shared-ui` (ConfirmDialog). **Downstream consumers**: `10_app-shell` (routed at `/admin`, **currently with no role-based guard** — see #1 caveat below). ## 2. Internal Interfaces | Export | Notes | |--------|-------| | `AdminPage()` | Top-level route component. Sub-sections: Users, Detection Classes, AI Settings, GPS Settings, Aircraft default. Detection Classes table supports the full CRUD surface — add, **edit** (AZ-512 inline form on row click of the ✎ button; PATCH `/api/admin/classes/{id}` with full body per Risk-2 mitigation; Enter saves, Escape cancels; inline validation for empty name and non-positive maxSizeM; closes Architecture Vision P12), delete. | ## 3. External API Specification | Method | Path | Purpose | |--------|------|---------| | GET / POST / PUT / DELETE | `/api/admin/users` | User CRUD | | GET | `/api/annotations/classes` | Read class list (note: read uses `annotations/`, write uses `admin/`) | | POST / PATCH / DELETE | `/api/admin/classes` | Class CRUD. PATCH `/api/admin/classes/{id}` powers the inline edit affordance (AZ-512) and accepts a full or partial body of `{ name?, shortName?, color?, maxSizeM? }`. **Cross-workspace note**: as of AZ-512 ship, the live `admin/` service still owes the write routes (POST + PATCH + DELETE) per **AZ-513** on `admin/`; UI ships against MSW stubs until that lands. | | GET / PUT | `/api/admin/settings/ai` | AI service config | | GET / PUT | `/api/admin/settings/gps` | GPS device config | | GET / PUT | `/api/admin/settings/aircraft-default` | Aircraft default | ## 5. Implementation Details **State Management**: Page-local React state per sub-form. No global form library. **Findings (B4, copied from state.json):** 1. **PRIORITY (security): no role-based route guard on `/admin`** — anyone authenticated can access. Server-enforced 403 protects the data, but UI does not gate. Surface in Step 6 problem-extraction. Cross-link with `10_app-shell`. 2. **AI Settings & GPS Settings forms render with `defaultValue` only — NO state, NO submit handler, the Save button does nothing.** PRIORITY surface in Step 6. 3. **Hardcoded GPS device default `'192.168.1.100'` / port `'5535'`** shipped in production bundle. Step 4. 4. **`handleDeleteClass` has NO `ConfirmDialog`** despite being destructive. Step 4 vs `ui_design/README.md`. 5. **Service split mismatch**: detection-class read uses `/api/annotations/classes` (annotations service) but write uses `/api/admin/classes` (admin service). Verify with suite ADRs in Step 3a. 6. **`handleToggleDefault` duplicated** between AdminPage and SettingsPage; aircraft default is global config but page exists in both `/admin` and `/settings` — surface intent in Step 6. 7. **Many hardcoded English strings.** Step 4 i18n. **Key Dependencies**: `03_shared-ui/ConfirmDialog` (used for some destructive actions; missing on `handleDeleteClass`). ## 7. Caveats & Edge Cases - The **broken Save button** is the most user-visible bug. - The **annotations/admin service split** for class CRUD looks like a copy-paste residue but may be deliberate; verify in Step 3a. - **No optimistic concurrency / version check** for any settings — last writer wins. ## 8. Dependency Graph **Must be implemented after**: `00_foundation`, `01_api-transport`, `03_shared-ui`. **Can be implemented in parallel with**: every other feature page. **Blocks**: `10_app-shell`. ## Module Inventory | Path | Module Doc | |------|------------| | `src/features/admin/AdminPage.tsx` | `_docs/02_document/modules/src__features__admin__AdminPage.md` |