Files
missions/_docs/02_document/FINAL_report.md
T
Oleksandr Bezdieniezhnykh 7025f4d075 refactor: enhance JWT authentication and CORS configuration
Updated JWT authentication to use configuration values instead of hardcoded secrets, improving security and flexibility. Enhanced CORS policy to conditionally allow origins based on configuration settings, with logging for permissive defaults. Updated README to reflect project renaming and clarify service context.
2026-05-14 19:48:25 +03:00

20 KiB
Raw Blame History

Azaion.Missions — Final Documentation Report

Status: complete (autodev /document Step 7, 2026-05-14). Mode: retrospective documentation of an existing codebase, post-Step 4 verification + Step 4.5 user-confirmed glossary & vision. Forward-looking caveat: every artefact in this set describes the post-rename, post-GPS-Denied-removal target. Today's source still uses pre-rename names; the doc-vs-code reconciliation table lives in 04_verification_log.md § 0 and the implementation deltas are tracked under Jira AZ-EPIC AZ-539 children B4B12 (see _docs/_process_leftovers/2026-05-14_rename-flights-to-missions.md).


Executive Summary

missions is the edge-tier .NET 10 REST service that owns the mission domain (vehicles, missions, waypoints) of an Azaion deployment. The autodev /document skill produced a complete bottom-up documentation set across 8 steps: discovery → 12 module docs → 6 component specs → module-layout (file ownership + 5-layer dependency table) → architecture / system-flows / data-model / deployment → verification (9 inline corrections, 2 drift items captured) → user-confirmed glossary & architecture vision → retrospective solution / problem / restrictions / acceptance-criteria / security-approach. This terminates Phase A Step 1 of the autodev existing-code flow; Step 2 (Architecture Baseline Scan) is the next auto-chained step.

Problem Statement

The system is the per-device authority for vehicle inventory (Plane / Copter / UGV / GuidedMissile), mission plans, and ordered waypoints — and is the single orchestrator of the cross-service cascade-delete that keeps media / annotations / detection / map_objects consistent when missions or waypoints are removed. It runs as one container per device alongside annotations, the detection pipeline, autopilot, gps-denied, and the React ui, sharing one local PostgreSQL with per-service table ownership enforced by convention. JWTs are validated locally with a shared HMAC secret — the service never calls back to the central admin issuer. Full statement in _docs/00_problem/problem.md.

Architecture Overview

Pattern: thin ASP.NET Core controller → service class → linq2db active-record over a per-HTTP-request scoped AppDataConnection. No repository abstraction; no in-process message queue / event bus; no background workers.

Technology stack: C# / .NET 10 (net10.0) on ASP.NET Core, linq2db 6.2.0 over PostgreSQL via Npgsql 10.0.2, JWT bearer (HS256, shared secret), Swashbuckle 10.1.5 (Swagger UI mounted unconditionally — ADR-005).

Deployment: docker compose per edge device (Jetson Orin / OrangePI / operator-PC); multi-arch ARM64 + AMD64 image built by Woodpecker; Watchtower handles container restarts; flight-gate prevents container restart mid-mission; vertical scale only (one instance per device).

8 ADRs (see architecture.md § 8): one Postgres per device (ADR-001), PascalCase wire shape carry-forward (ADR-002), manual cascade-delete (ADR-003), IF NOT EXISTS schema bootstrap (ADR-004), Swagger + dev fallbacks ungated (ADR-005), cascade-not-transaction-wrapped carry-forward (ADR-006), GPS-Denied moved out (ADR-007), one-csproj layering by convention (ADR-008).

Component Summary

# Component Purpose Dependencies (logical layer) Spec / Epic
01 01_vehicle_catalog Vehicle CRUD + is_default exclusivity (stricter than spec — B12 decision pending) Layer 3 → 04_persistence, 05_identity suite spec § 6.1; B6 / B12
02 02_mission_planning Mission + Waypoint CRUD + cross-service cascade-delete walk Layer 4 → 01_vehicle_catalog (existence check), 04_persistence, 05_identity, 06_http_conventions suite spec § 6.2; B6 / B7 / B8
04 04_persistence AppDataConnection (linq2db ITable<T>) + DatabaseMigrator (CREATE TABLE IF NOT EXISTS + B9 one-shot DROP) Layer 1 → linq2db + Npgsql only B7 / B9
05 05_identity JwtExtensions.AddJwtAuth — HS256 local validation + "FL" policy Layer 2 → ASP.NET Core only suite-level remediation (AZ-487/AZ-494 carry-forward)
06 06_http_conventions ErrorHandlingMiddleware + PaginatedResponse<T> + dead ErrorResponse DTO Layer 2 → ASP.NET Core only ADR-002 carry-forward
07 07_host Program.cs composition root: env adapter, JWT registration, scoped DI, run migrator, register middleware, MapGet("/health"), mount Swagger Layer 5 → every other component B5 (csproj rename) / B10 (image tag)

Implementation order (based on dependency graph in module-layout.md):

  1. Layer 1: 04_persistence — depends only on linq2db + Npgsql.
  2. Layer 2: 05_identity, 06_http_conventions — depend on ASP.NET Core only.
  3. Layer 3: 01_vehicle_catalog.
  4. Layer 4: 02_mission_planning (reads vehicles for existence checks; uses PaginatedResponse<T>).
  5. Layer 5: 07_host (composition root).

No circular dependencies between components.

System Flows

Flow Description Key components Criticality
F1 Vehicle CRUD 01_vehicle_catalog04_persistence High
F2 Mission create / read / update with vehicle_id existence check 02_mission_planning04_persistence, with 01_vehicle_catalog lookup High
F3 Mission delete with cross-service cascade (touches map_objects, media, annotations, detection, waypoints, missions) 02_mission_planning04_persistence + cross-service tables Critical (data integrity; not transaction-wrapped today — ADR-006)
F4 Waypoint CRUD (delete is a scoped F3 cascade) 02_mission_planning (WaypointService) → 04_persistence High
F5 JWT bearer validation (cross-cutting; local HS256 only) 05_identity (pipeline middleware) Critical (every authenticated route)
F6 Service startup + idempotent schema migration (B9 one-shot DROP TABLE IF EXISTS for fielded legacy devices) 07_host04_persistence High
F7 Anonymous GET /health probe (process-liveness only; no DB ping) 07_host Medium

Full sequences and per-flow Mermaid diagrams in system-flows.md and diagrams/flows/flow_*.md.

Risk Summary

The codebase has no automated tests today, so "risks" here are observed-from-code carry-forward concerns (architecture.md § Carry-forward + 00_discovery.md § Spec ↔ Code Divergences), classified by impact. Mitigation column points at the responsible Jira child or the suite-level ticket.

Level Count Items
Critical 1 Cascade-delete is NOT transaction-wrapped (ADR-006) — partial failure leaves orphan rows. One-line fix, recommended to land with B6
High 3 (a) JWT_SECRET / DATABASE_URL dev fallbacks not gated on IsDevelopment() (ADR-005, suite-tracked); (b) JWT iss/aud validation disabled (CMMC L2 row 3, AZ-487/AZ-494 suite-tracked); (c) Wire-shape divergence — entity/DTO bodies PascalCase, error envelope missing errors field (ADR-002 carry-forward)
Medium 4 (a) "Exactly one default vehicle" stricter than spec + race-prone (B12 / AZ-551 — decision-only ticket); (b) vehicle_id-not-found returns 400 instead of spec's 404 (carry-forward); (c) Swagger UI mounted unconditionally (ADR-005); (d) CORS open in all environments (carry-forward)
Low 4 (a) ErrorResponse DTO is dead on the wire and has wrong shape; (b) Geopoint stored as 3 flat columns instead of spec's auto-converting string GPS; (c) FL permission code retains legacy "Flight" wording post-rename (suite-level fleet-wide change); (d) FuelType enum may not fit single-use GuidedMissile

Mitigation status: every Critical/High item is either covered by an open Jira ticket (B6, B12, AZ-487/AZ-494) or explicitly logged as a suite-level carry-forward in 04_verification_log.md. No Critical/High item is unaccounted for.

Test Coverage

No automated tests exist today. Verification of every documented behaviour is by code inspection only. The autodev existing-code flow's Phase A Steps 3 → 7 is the planned path to convert _docs/00_problem/acceptance_criteria.md (10 AC groups, ~60 individual criteria) into runnable test cases.

Component Integration Performance Security Acceptance AC coverage today
01_vehicle_catalog 0 0 0 0 AC-1 (9 criteria) — inspection only
02_mission_planning 0 0 0 0 AC-2 (8) + AC-3 (7) + AC-4 (7) — inspection only
04_persistence 0 0 0 0 AC-6 (10) — inspection only
05_identity 0 0 0 0 AC-5 (9) + AC-9 (4) — inspection only
06_http_conventions 0 0 0 0 AC-8 (7) — inspection only
07_host 0 0 0 0 AC-6 (10) + AC-7 (4) + AC-10 (6) — inspection only

Overall AC coverage by automated tests: 0 / ~60 (0%) — the gap that Phase A Steps 37 will close.

Rename Epic Roadmap (Jira AZ-EPIC AZ-539)

The full doc-vs-code rename + GPS-Denied removal is tracked as one Jira Epic + 12 child tickets. B1B3 (the documentation half) landed in this turn; B4B12 (the code half) are still To Do.

Order Plan ID Jira Type SP Status Component / artefact
Epic AZ-539 Epic To Do umbrella
1 B1 AZ-540 Task 3 Done (this turn) local docs (this repo's _docs/)
2 B2 AZ-541 Task 3 Done (this turn) suite docs (../../suite/_docs/)
3 B3 AZ-542 Task 3 Done (this turn) local + suite state bookkeeping
4 B4 AZ-543 Task 3 To Do repo rename (Gitea + suite .gitmodules + git mv)
5 B5 AZ-544 Story 3 To Do csproj + namespace Azaion.FlightsAzaion.Missions
6 B6 AZ-545 Story 5 To Do domain rename Aircraft → Vehicle, Flight → Mission, AircraftType → VehicleType { Plane, Copter, UGV, GuidedMissile }
7 B7 AZ-546 Story 3 To Do drop GPS-Denied entities, "GPS" policy, cascade branches, migrator entries
8 B8 AZ-547 Story 3 To Do HTTP routes /aircrafts → /vehicles, /flights → /missions
9 B9 AZ-548 Story 5 To Do DB migration: ALTER TABLE rename + DROP TABLE IF EXISTS for legacy GPS-Denied
10 B10 AZ-549 Task 2 To Do Dockerfile entrypoint + Woodpecker image tag + suite compose service block
11 B11 AZ-550 Story 5 To Do consumer cutover (autopilot + ui + suite e2e)
12 B12 AZ-551 Task 2 To Do decision-only: lift "exactly one default" into spec + transaction-wrap, OR drop from code

Total estimated effort (remaining): 35 SP across 9 To-Do tickets. Implementation order has hard dependencies (B5 → B6 → B7 → B8 → B9 → B10 → B11; B4 ride-along; B12 independent decision).

Key Decisions Made (during documentation)

# Decision Rationale Alternatives rejected
1 Document the post-rename target rather than today's pre-rename source Aligns with the user's intended end state and the Jira Epic; avoids documenting code that's about to be deleted (B7) (a) Document today's code as-is — rejected: would require a near-total rewrite the moment B5B7 land. (b) Document both — rejected: doubles maintenance burden until B5B7 ship
2 Each forward-looking doc carries an explicit "post-rename" note pointing at the responsible Jira child Future readers can reconcile what they see in code against the doc without re-running discovery Implicit forward-looking — rejected: too easy to mistake a doc for current state
3 Treat the verification step as rename-aware The doc-vs-code rename mapping is captured once in 04_verification_log.md § 0; mismatches not covered by the mapping are the only flagged drift Treat every rename as a verification failure — rejected: would flag every entity name and produce noise
4 Component count went 7 → 6 (dropped 03_gps_denied) and 01_aircraft_catalog01_vehicle_catalog Matches the post-rename suite spec; logged in state.json.decomposition_revised Keep 7 with 03_gps_denied as deprecated — rejected: would conflict with B7's removal scope
5 architecture.md § "Architecture Vision" + glossary.md were both confirmed by the user (Step 4.5) Downstream skills (refactor, decompose, new-task) treat these as authoritative Skip the glossary — rejected: existing-code projects benefit most from explicit terminology reconciliation
6 Solution / problem / restrictions / acceptance / security all describe today's behaviour with carry-forward divergences explicitly called out Tests against the docs will catch unintended behaviour changes; spec-conformance fixes are intentional Rewrite the docs to match the suite spec — rejected: would misrepresent the running code

Open Questions (for Phase A Step 2 onward)

# Question Impact Where it surfaces next
1 Will B12 / AZ-551 lift "exactly one default vehicle" into spec (with transaction-wrap) or drop the rule from code? AC-1.2 / AC-1.3 / AC-1.4 will change shape; the F1 test scenarios in Step 3 will pin whichever resolution the user picks B12 / AZ-551 ticket
2 Should B6 also land the cascade transaction-wrap (ADR-006 carry-forward, one-line fix)? Closes the only Critical risk; B6 is a rename pass and the transaction wrap can ride along cheaply B6 / AZ-545 review
3 When does the suite-wide camelCase wire-shape migration happen (ADR-002 carry-forward)? Affects every Mission / Vehicle / PaginatedResponse consumer (UI + autopilot); not in this Epic Suite-level ticket (not yet filed)
4 Does gps-denied need to be deployed BEFORE B9's DROP TABLE IF EXISTS runs on fielded devices? Out-of-band ordering matters: AC-10.5; F6 error scenario B9 / B10 acceptance review
5 Will B11 cover any other consumers besides UI + autopilot? Determines B11 scope B11 / AZ-550 review

These do not block Step 2 (Architecture Baseline Scan); they are inputs to subsequent test-spec / refactor / new-task work.

Artifact Index

Documentation (this repo, _docs/)

File Description
_docs/00_problem/problem.md High-level problem statement (post-rename target)
_docs/00_problem/restrictions.md Hardware / software / environment / operational restrictions (4 categories, 41 items)
_docs/00_problem/acceptance_criteria.md 10 AC groups (~60 criteria), every criterion grounded in code
_docs/00_problem/input_data/data_parameters.md Env vars, HTTP DTOs, table schemas (4 owned + 3 borrowed), enum values, endpoint matrix
_docs/00_problem/security_approach.md Authn / authz / data protection / input validation / CORS / 8 production-deploy footguns / threat-model summary
_docs/01_solution/solution.md Retrospective solution: per-component table + cross-cutting choices + implementation order + testing strategy
_docs/02_document/00_discovery.md Suite context, repository layout, tech stack, entry points, configuration, dependency graph (5 layers), spec ↔ code divergences (15 items)
_docs/02_document/04_verification_log.md Step 4 verification: rename-aware mode, counts, per-symbol sweep, drift mapping table
_docs/02_document/architecture.md Architecture (Vision + 8 sections + 8 ADRs); confirmed by user at Step 4.5
_docs/02_document/system-flows.md F1F7 narrative + cross-cutting concerns + per-flow error tables
_docs/02_document/data_model.md Entity / table / cross-service ownership map
_docs/02_document/glossary.md Glossary; confirmed by user at Step 4.5
_docs/02_document/module-layout.md File ownership + 5-layer dependency table; status derived-from-code
_docs/02_document/components/01_vehicle_catalog/description.md Component spec (post-rename)
_docs/02_document/components/02_mission_planning/description.md Component spec
_docs/02_document/components/04_persistence/description.md Component spec
_docs/02_document/components/05_identity/description.md Component spec
_docs/02_document/components/06_http_conventions/description.md Component spec
_docs/02_document/components/07_host/description.md Component spec
_docs/02_document/modules/{auth,controller_missions,controller_vehicles,database,dtos,entities,enums,middleware,program,service_mission,service_vehicle,service_waypoint}.md 12 module docs
_docs/02_document/diagrams/components.md Mermaid component relationship diagram
_docs/02_document/diagrams/flows/flow_{vehicle_crud,mission_lifecycle,mission_cascade_delete,waypoint_lifecycle,jwt_validation,startup_migration,health_probe}.md Per-flow Mermaid sequence diagrams
_docs/02_document/deployment/{containerization,ci_cd_pipeline,environment_strategy,observability}.md Deployment notes

State / process artefacts

File Description
_docs/_autodev_state.md Autodev orchestrator state (this skill: Phase A Step 1, complete on Step 7 write)
_docs/02_document/state.json Document skill internal state
_docs/_process_leftovers/2026-05-14_rename-flights-to-missions.md Rename leftover index — kept until B4B12 ship
_docs/tasks/done/AZ-540_missions_rename_b1_local_docs.md B1 task spec (Done)
_docs/tasks/done/AZ-542_missions_rename_b3_state_bookkeeping.md B3 task spec (Done)
_docs/tasks/todo/AZ-544_missions_rename_b5_csproj_namespace.md B5 task spec
_docs/tasks/todo/AZ-545_missions_rename_b6_domain_rename.md B6 task spec
_docs/tasks/todo/AZ-546_missions_rename_b7_drop_gps_denied.md B7 task spec
_docs/tasks/todo/AZ-547_missions_rename_b8_http_routes.md B8 task spec
_docs/tasks/todo/AZ-548_missions_rename_b9_db_migration.md B9 task spec
_docs/tasks/todo/AZ-551_missions_rename_b12_default_vehicle_rule.md B12 task spec

Suite-level cross-references (read-only from this repo)

File Description
../../suite/_docs/02_missions.md Primary spec (post-rename)
../../suite/_docs/00_top_level_architecture.md Topology, error envelope, pagination
../../suite/_docs/00_database_schema.md Authoritative ER diagram
../../suite/_docs/00_roles_permissions.md FL permission origin
../../suite/_docs/11_gps_denied.md Separate gps-denied service (post-B7)
../../suite/_docs/05_security/cmmc_l2_scorecard.md CMMC L2 row 3 finding (AZ-487/AZ-494)
../../suite/_docs/_repo-config.yaml Repo registry (post-rename name: missions)

Next Step in the Autodev Existing-Code Flow

Phase A Step 2 — Architecture Baseline Scan: invoke code-review/SKILL.md in baseline mode (Phase 1 + Phase 7) against the full codebase, save the output to _docs/02_document/architecture_compliance_baseline.md. The scan compares the running code against the just-confirmed architecture.md + module-layout.md and flags pre-existing High/Critical structural issues. After the baseline is clean, the autodev auto-chains to Step 3 (Test Spec) — which produces _docs/02_document/tests/traceability-matrix.md and per-flow scenario files for F1F7, the seed set for the test suite implementation in Steps 57.