# Problem — Azaion.Missions
> **Status**: derived-from-code (autodev `/document` Step 6, 2026-05-14).
> **Mode**: retrospective synthesis from the verified `_docs/02_document/` set + the canonical suite spec at `../../suite/_docs/02_missions.md`.
> **Forward-looking caveat**: same as `solution.md` § header — references to "the system" mean the post-rename, post-GPS-Denied-removal target. Today's source still uses pre-rename names; deltas tracked under Jira AZ-EPIC (AZ-539) children B4–B12.
---
## What is this system?
`missions` is the **edge-tier .NET 10 REST service** that owns the **mission domain** of an Azaion deployment: it is the local source of truth for the operator's vehicle inventory, mission plans, and ordered waypoints, and it is the orchestrator of the cross-service cascade-delete that keeps the rest of the device's edge stack consistent when missions or waypoints are removed.
It is one of ~6 backend services running side-by-side **on each customer device** (Jetson Orin / OrangePI / operator-PC). All edge services share **one local PostgreSQL** on the device; each migrates only the tables it owns. JWTs are minted by the central `admin` service and validated locally with a shared HMAC secret — `missions` never calls `admin` back.
## What problem does it solve?
When a human operator plans, runs, and tears down missions on the edge:
1. **Inventory** — the operator must register the vehicles they own (Plane / Copter / UGV / GuidedMissile) and pick a default for one-click mission setup.
2. **Mission planning** — the operator must define a named mission against a chosen vehicle and lay out an ordered set of waypoints (lat/lon or MGRS, with per-waypoint source / objective / height).
3. **Mission lifecycle** — when a mission or waypoint is deleted, every downstream artefact (media uploaded by `annotations`, AI annotations, AI detections, autopilot-emitted `map_objects`) MUST be cleaned up in FK-safe order so the local DB doesn't accumulate orphans.
4. **Cross-service cohesion** — sibling services (`autopilot`, `annotations`, detection pipeline, `gps-denied`, `ui`) must be able to read mission/waypoint data without round-trips to the central admin and without their own copies. The shared local DB is that contract.
5. **Local trust** — the operator's device may be intermittently offline from the central network. Authn/authz cannot depend on a live `admin` callback; tokens validate locally with a shared secret.
## Who are the users?
| Persona | Role | How they interact |
|---------|------|-------------------|
| **Operator** | Human running missions in the field | Through the React `ui` (REST + JWT). Sole human user of this service today |
| **`autopilot`** | Sibling edge service (consumes missions/waypoints, writes `map_objects`) | Reads `missions` / `waypoints` from the shared DB; writes `map_objects` to a table this service owns the schema for and cascade-deletes |
| **`annotations`** | Sibling edge service (owns `media` / `annotations` table schemas) | Indirect — `missions` cascade-deletes from `media` / `annotations` when missions/waypoints are removed |
| **Detection pipeline** | Sibling edge service (owns the `detection` table schema) | Indirect — same pattern as `annotations` |
| **`gps-denied`** *(post-B7)* | Sibling edge service (owns `orthophotos` + `gps_corrections`) | None at runtime — references `mission_id` / `waypoint_id` as plain GUIDs in its own tables; manages its own cleanup |
| **`admin`** | Central .NET service (token issuer) | One-way: issues JWTs that this service validates locally. `admin` outages do NOT take this service down (until tokens expire) |
There are **no application-level admin / superuser roles inside this service** — every protected endpoint is gated by the single `"FL"` permission. The role → permission matrix is suite-level (`../../suite/_docs/00_roles_permissions.md`).
## How does it work at a high level?
ASP.NET Core thin controller → service class → linq2db active-record over a per-HTTP-request scoped `AppDataConnection`. No repository abstraction; no in-process message queue or event bus; no background workers.
```mermaid
flowchart LR
ui[[Operator UI]] -- "REST + JWT" --> mc[MissionsController / VehiclesController]
mc --> svc[MissionService / VehicleService / WaypointService]
svc --> ado[AppDataConnection
linq2db ITable<T>]
ado --> pg[(postgres-local)]
autopilot[[autopilot]] -- "DB read missions/waypoints
DB write map_objects" --> pg
svc -. "cascade delete on mission/waypoint delete" .-> pg
```
Seven flows make up the runtime surface (`_docs/02_document/system-flows.md`):
- **F1** Vehicle CRUD
- **F2** Mission create / read / update
- **F3** Mission delete + **cross-service cascade** (the most critical flow; not transaction-wrapped today — ADR-006)
- **F4** Waypoint create / read / update / delete (delete is a scoped F3)
- **F5** JWT bearer validation (cross-cutting; local HS256 only)
- **F6** Service startup + idempotent schema migration
- **F7** Anonymous `GET /health` probe
## Cross-cutting contracts owned here
1. **JWT validation contract** — trust admin-issued tokens via shared HMAC secret (`JWT_SECRET`); reject everything else with `401`/`403`.
2. **Mission ownership graph & cascade-delete** — only place in the system that knows `mission → {map_objects, waypoints → media → annotations → detection}`.
3. **Suite-standard wire shapes** *(currently divergent — see `_docs/02_document/architecture.md` ADR-002)* — error envelope and `PaginatedResponse` are shared with `annotations`, `admin`, `satellite-provider`.
## Out of scope for this service
- **GPS-Denied** (orthophoto upload, live-GPS, GPS correction) — separate `gps-denied` service after B7.
- **Token issuance** — `admin` mints tokens; this service only validates.
- **Detection / AI** — owned by the detection pipeline; this service only cascade-deletes orphaned rows on mission/waypoint delete.
- **Media storage** — `annotations` owns `media` (text PK + waypoint FK); this service only cascade-deletes.
- **Multi-instance HA** — exactly one container per device; horizontal scale-out explicitly not supported.
## Cross-reference index
| Concern | Where |
|---------|-------|
| Spec (canonical, post-rename) | `../../suite/_docs/02_missions.md` |
| Top-level architecture (envelope, pagination, topology) | `../../suite/_docs/00_top_level_architecture.md` |
| Authoritative ER diagram | `../../suite/_docs/00_database_schema.md` |
| Roles & `FL` permission origin | `../../suite/_docs/00_roles_permissions.md` |
| GPS-Denied (separate service) | `../../suite/_docs/11_gps_denied.md` |
| Verified architecture (this repo) | `_docs/02_document/architecture.md` |
| Verified system flows (this repo) | `_docs/02_document/system-flows.md` |
| Glossary (confirmed-by-user) | `_docs/02_document/glossary.md` |
| Verification log (drift mapping) | `_docs/02_document/04_verification_log.md` |
| Solution (retrospective) | `_docs/01_solution/solution.md` |
| Restrictions (retrospective) | `_docs/00_problem/restrictions.md` |
| Acceptance criteria (retrospective) | `_docs/00_problem/acceptance_criteria.md` |
| Input data | `_docs/00_problem/input_data/data_parameters.md` |
| Security approach | `_docs/00_problem/security_approach.md` |
| Rename leftover (Jira index) | `_docs/_process_leftovers/2026-05-14_rename-flights-to-missions.md` |