# Components — High-Level Wiring (`missions` service) The shape below mirrors the spec features in `../../../suite/_docs/02_missions.md` rather than the source-tree directories. GPS-Denied is **not** a component of this service -- per Jira AZ-EPIC child B7 it lives in a separate `gps-denied` service and is documented in `../../../suite/_docs/11_gps_denied.md`. ```mermaid flowchart TB subgraph Suite[Azaion suite] Admin["admin (issues JWTs)"] Annotations["annotations\n(owns media + annotations)"] Detection["detection pipeline\n(owns detection)"] Autopilot["autopilot\n(reads missions, writes map_objects)"] UI["ui (browser)"] GpsDenied["gps-denied (separate service)\n(owns orthophotos + gps_corrections)"] end subgraph Missions[missions service — this codebase] Host[07_host\n• Program.cs\n• /health, Swagger] Auth[05_identity\n• JwtExtensions] Conv[06_http_conventions\n• ErrorMiddleware\n• PaginatedResponse] Persist[04_persistence\n• AppDataConnection\n• DatabaseMigrator\n• 7 entities] Catalog[01_vehicle_catalog\n• VehiclesController\n• VehicleService\n• Plane / Copter / UGV / GuidedMissile] Planning[02_mission_planning\n• MissionsController\n• Mission + Waypoint services\n• cross-service cascade] end UI -->|HTTP + JWT| Host Admin -->|mints JWT (HMAC shared secret)| Auth Host --> Conv Host --> Auth Host --> Persist Auth --> Catalog Auth --> Planning Conv --> Catalog Conv --> Planning Persist --> Catalog Persist --> Planning Catalog -->|vehicle existence check| Planning Planning -.delete cascade.-> Annotations Planning -.delete cascade.-> Detection Planning -.delete cascade.-> Autopilot Autopilot -->|reads missions + waypoints| Planning GpsDenied -.references mission_id / waypoint_id\n(no runtime call into this service).-> Planning ``` ## Component map (file <-> component) > **NOTE (forward-looking)**: file paths reflect the post-rename state. Today's source still uses `Aircraft*`/`Flight*`/`AircraftType` filenames + 9 entities. Renames tracked under Jira AZ-EPIC children B5 / B6 / B7 / B8. | Component | Files (post-rename) | |-----------|---------------------| | 01_vehicle_catalog | `Controllers/VehiclesController.cs`, `Services/VehicleService.cs`, 4 vehicle DTOs (`CreateVehicleRequest`, `UpdateVehicleRequest`, `GetVehiclesQuery`, `SetDefaultRequest`), `Enums/VehicleType.cs`, `Enums/FuelType.cs` | | 02_mission_planning | `Controllers/MissionsController.cs`, `Services/MissionService.cs`, `Services/WaypointService.cs`, 6 mission/waypoint DTOs, `Enums/WaypointSource.cs`, `Enums/WaypointObjective.cs`, `DTOs/GeoPoint.cs` | | 04_persistence | `Database/AppDataConnection.cs`, `Database/DatabaseMigrator.cs`, all 7 entities in `Database/Entities/` (`Vehicle`, `Mission`, `Waypoint`, `MapObject`, `Media`, `Annotation`, `Detection`), `Enums/ObjectStatus.cs` | | 05_identity | `Auth/JwtExtensions.cs` | | 06_http_conventions | `Middleware/ErrorHandlingMiddleware.cs`, `DTOs/ErrorResponse.cs`, `DTOs/PaginatedResponse.cs` | | 07_host | `Program.cs`, `GlobalUsings.cs` | ## Layering summary - **Foundation (parallelisable)**: 04_persistence, 05_identity, 06_http_conventions - **Feature components**: 01_vehicle_catalog (depends on 04+05+06), 02_mission_planning (depends on 04+05+06+01) - **Composition root**: 07_host (last; wires everything) ## Cross-service relationships (live runtime) | Boundary | Direction | Mechanism | |----------|-----------|-----------| | `admin` -> `missions` | inbound | JWT minted with shared HMAC secret; validated by 05_identity | | `missions` -> `annotations`, `detection` (DB) | outbound write | Cross-table cascade-delete on the shared local PostgreSQL during mission/waypoint delete | | `missions` -> `autopilot` (DB) | outbound delete | `map_objects` cleanup on mission delete (autopilot is the writer) | | `autopilot` -> `missions` (DB) | inbound read of mission state | autopilot reads `missions` + `waypoints` to drive the vehicle | | `ui` -> `missions` (HTTP) | inbound | All controllers (vehicle CRUD, mission planning) | | `gps-denied` <- `missions` (no runtime coupling) | -- | The new `gps-denied` service owns its own DB tables (`orthophotos`, `gps_corrections`); they reference `mission_id` / `waypoint_id` as plain GUIDs. There is no inbound HTTP call from `gps-denied` to `missions` and no outbound call from `missions` to `gps-denied` -- decoupled by design. |