Files
missions/_docs/00_problem/problem.md
T
Oleksandr Bezdieniezhnykh 78dea8ebab
ci/woodpecker/push/build-arm Pipeline was successful
chore: update configuration and Docker setup for JWT and test results
Enhanced the .gitignore to exclude test results and updated the Dockerfile to include a new entrypoint script for improved container initialization. Refactored JWT configuration to support additional parameters for automatic refresh intervals, ensuring better control over token management. Updated the ConfigurationResolver to enforce required environment variables without hardcoded fallbacks, enhancing security and flexibility.
2026-05-15 03:23:23 +03:00

8.1 KiB
Raw Blame History

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 B4B12.


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 using ECDSA-SHA256 and validated locally against admin's JWKS, which missions fetches once at startup (and refreshes on schedule) and caches; request-path validation is local and does not call 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. Once the JWKS has been cached, authn/authz does not depend on a live admin callback; tokens validate locally against the cached ECDSA public keys. admin must be reachable at the moment of the first JWKS fetch after a cold start (then again periodically on the manager's refresh schedule).

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 + JWKS publisher) This service fetches admin's public JWKS once at startup and on the ConfigurationManager refresh schedule; request-path validation does not call back. admin outage after the JWKS has been cached does NOT take this service down (until cache + tokens expire). admin outage at the time of the first JWKS fetch causes the first protected request to fail 500

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.

flowchart LR
  ui[[Operator UI]] -- "REST + JWT" --> mc[MissionsController / VehiclesController]
  mc --> svc[MissionService / VehicleService / WaypointService]
  svc --> ado[AppDataConnection<br/>linq2db ITable&lt;T&gt;]
  ado --> pg[(postgres-local)]
  autopilot[[autopilot]] -- "DB read missions/waypoints<br/>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 ECDSA-SHA256 against admin's cached JWKS; iss + aud validated; alg pinned)
  • 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 ECDSA-SHA256 signature verification against admin's published JWKS (cached locally), with iss == JWT_ISSUER + aud == JWT_AUDIENCE + exp (30s skew) all enforced and alg pinned to EcdsaSha256; 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<T> 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 issuanceadmin 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 storageannotations 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