Files
missions/_docs/00_problem/input_data/data_parameters.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

12 KiB

Input Data Parameters — Azaion.Missions

Status: derived-from-code (autodev /document Step 6, 2026-05-14). Schemas below match the actual Database/Entities/*.cs LinqToDB mappings and DTOs/*.cs request shapes (post-B6 names). Today's source still uses pre-rename names; the doc-vs-code mapping is in _docs/02_document/04_verification_log.md § 0.


1. Configuration input (env vars)

Variable Type Required Default (dev fallback) Source order Format / constraints Used by
DATABASE_URL string yes (production) Host=localhost;Database=azaion;Username=postgres;Password=changeme IConfigurationEnvironment.GetEnvironmentVariable → fallback Either postgresql://user:pass@host:port/db (converted via local helper ConvertPostgresUrl) OR a raw Npgsql connection string Program.cs (DI registration of AppDataConnection)
JWT_SECRET string yes (production) development-secret-key-min-32-chars!! same as above UTF-8 string, ≥32 chars (SymmetricSecurityKey accepts shorter but JwtBearer HS256 requires ≥32 bytes) Program.cs AddJwtAuth
AZAION_REVISION string no (build-time) Dockerfile ARG baked from CI_COMMIT_SHA git SHA Dockerfile only; surfaced via docker inspect
ASPNETCORE_URLS string no http://+:8080 ASP.NET Core convention URL list ASP.NET Core host

Important: ADR-005 carry-forward — neither Swagger UI mounting nor the dev fallbacks for JWT_SECRET / DATABASE_URL are gated on IsDevelopment(). A production deploy without the env vars set will silently boot with the well-known dev secret; tracked at suite level (CMMC L2 row 3, AZ-487 / AZ-494).

2. HTTP request DTOs (post-B6 shapes)

2.1 Vehicle (/vehicles)

public class CreateVehicleRequest {
    public VehicleType Type { get; set; }            // enum int: Plane=0, Copter=1, UGV=2, GuidedMissile=3
    public string      Model { get; set; } = "";
    public string      Name { get; set; } = "";
    public FuelType    FuelType { get; set; }        // enum int: Electric=0, Gasoline=1, Diesel=2
    public decimal     BatteryCapacity { get; set; }
    public decimal     EngineConsumption { get; set; }
    public decimal     EngineConsumptionIdle { get; set; }
    public bool        IsDefault { get; set; }
}

public class UpdateVehicleRequest {                  // all properties nullable -- partial update
    public VehicleType? Type;
    public string?      Model;
    public string?      Name;
    public FuelType?    FuelType;
    public decimal?     BatteryCapacity;
    public decimal?     EngineConsumption;
    public decimal?     EngineConsumptionIdle;
    public bool?        IsDefault;
}

public class GetVehiclesQuery {
    public string? Name { get; set; }                // case-sensitive contains
    public bool?   IsDefault { get; set; }           // exact match
}

public class SetDefaultRequest {
    public bool IsDefault { get; set; }
}

Validation: NONE today. No [Required], no [Range], no min-length. Empty Name, negative BatteryCapacity, out-of-range enum int values are accepted. Carry-forward improvement.

2.2 Mission (/missions)

public class CreateMissionRequest {
    public Guid     VehicleId { get; set; }
    public string   Name { get; set; } = "";
    public DateTime? CreatedDate { get; set; }       // defaults to UtcNow if null
}

public class UpdateMissionRequest {                  // partial update
    public string? Name { get; set; }
    public Guid?   VehicleId { get; set; }
}

public class GetMissionsQuery {
    public string?   Name { get; set; }
    public DateTime? FromDate { get; set; }
    public DateTime? ToDate { get; set; }
    public int       Page { get; set; } = 1;
    public int       PageSize { get; set; } = 20;
}

Validation: existence check on VehicleId (returns 400 today via ArgumentException; spec wants 404 — carry-forward divergence). No bounds on Page / PageSize (negative or huge values accepted by binding).

2.3 Waypoint (/missions/{id}/waypoints)

public class GeoPoint {                              // shared value object; all fields nullable
    public decimal? Lat { get; set; }
    public decimal? Lon { get; set; }
    public string?  Mgrs { get; set; }               // Military Grid Reference System
}

public class CreateWaypointRequest {
    public GeoPoint?         GeoPoint { get; set; }  // nullable: all-null is accepted today (no invariant)
    public WaypointSource    WaypointSource { get; set; }    // enum int
    public WaypointObjective WaypointObjective { get; set; } // enum int
    public int               OrderNum { get; set; }
    public decimal           Height { get; set; }
}

public class UpdateWaypointRequest {                 // identical SHAPE to Create -- non-nullable enums/numerics
    public GeoPoint?         GeoPoint { get; set; }
    public WaypointSource    WaypointSource { get; set; }
    public WaypointObjective WaypointObjective { get; set; }
    public int               OrderNum { get; set; }
    public decimal           Height { get; set; }
}

Validation: NONE. No min-length, no enum range check, no Lat/Lon bounds, no MGRS format validation. GeoPoint may be all-null. UpdateWaypoint is structurally NOT partial — every field gets overwritten on PUT (inconsistent with vehicle's partial-update pattern).

Spec divergence (Geopoint): spec stores Waypoints.GPS as a single string GPS field with Lat <-> MGRS auto-conversion (../../suite/_docs/02_missions.md, ../../suite/_docs/00_database_schema.md). Code stores 3 separate columns with NO conversion. Carry-forward.

3. Persisted data — owned tables (post-B7+B9)

3.1 vehicles (owned)

Column Type Nullable Notes
id UUID NO primary key
type INTEGER NO VehicleType enum int (Plane / Copter / UGV / GuidedMissile)
model TEXT NO
name TEXT NO
fuel_type INTEGER NO FuelType enum int
battery_capacity NUMERIC NO
engine_consumption NUMERIC NO
engine_consumption_idle NUMERIC NO
is_default BOOLEAN NO "exactly one default" enforced by VehicleService (stricter than spec — B12 decision)

3.2 missions (owned)

Column Type Nullable Notes
id UUID NO primary key
created_date TIMESTAMPTZ NO server-assigned UtcNow if not supplied
name TEXT NO
vehicle_id UUID NO logical FK to vehicles.id; existence-checked in service, no DB-level FK constraint declared in migrator

Index: ix_missions_vehicle_id on vehicle_id.

3.3 waypoints (owned)

Column Type Nullable Notes
id UUID NO primary key
mission_id UUID NO logical FK to missions.id
lat NUMERIC YES spec divergence — see § 2.3
lon NUMERIC YES spec divergence
mgrs TEXT YES spec divergence
waypoint_source INTEGER NO WaypointSource enum int
waypoint_objective INTEGER NO WaypointObjective enum int
order_num INTEGER NO listing order
height NUMERIC NO metres

Index: ix_waypoints_mission_id on mission_id.

3.4 map_objects (owned schema; written by autopilot)

Column Type Nullable Notes
id UUID NO primary key
mission_id UUID NO logical FK to missions.id
h3_index TEXT NO Uber H3 hex grid cell
mgrs TEXT NO
lat NUMERIC YES
lon NUMERIC YES
class_num INTEGER NO detection class id
label TEXT NO
size_width_m NUMERIC NO
size_length_m NUMERIC NO
confidence NUMERIC NO 0..1
object_status INTEGER NO ObjectStatus enum int
first_seen_at TIMESTAMPTZ NO
last_seen_at TIMESTAMPTZ NO

Index: ix_map_objects_mission_id on mission_id.

autopilot is the writer (per ../../suite/_docs/06_autopilot_design.md); this service owns the schema and cascade-deletes only.

4. Persisted data — borrowed read-only stubs

Table Schema owner This service uses for
media annotations (per ../../suite/_docs/01_annotations.md) id resolution + cascade-delete walk on mission/waypoint delete
annotations annotations id resolution + cascade-delete walk
detection (singular by upstream owner) Detection pipeline cascade-delete walk

Stub schemas (just enough to query / delete by id):

[Table("media")]       public class Media       { [PrimaryKey, Column("id")] public string Id = ""; [Column("waypoint_id")] public Guid? WaypointId; }
[Table("annotations")] public class Annotation  { [PrimaryKey, Column("id")] public string Id = ""; [Column("media_id")]    public string MediaId = ""; }
[Table("detection")]   public class Detection   { [PrimaryKey, Column("id")] public Guid   Id;     [Column("annotation_id")] public string AnnotationId = ""; }

Migrations for these tables are owned by the respective sibling services. If they have not migrated on a given device, this service's cascade-delete walk fails on relation does not exist (abnormal deployment).

5. Removed in B7 (post-B7+B9 schema)

These tables and entities are out of this repo; cleanup happens once on legacy devices via the B9 DROP TABLE IF EXISTS block in DatabaseMigrator:

Table Pre-B7 owner Post-B7 owner
orthophotos this repo (Orthophoto entity, 03_gps_denied component) gps-denied service (separate repo)
gps_corrections this repo (GpsCorrection entity, 03_gps_denied component) gps-denied service

gps-denied references mission_id / waypoint_id as plain GUIDs in its OWN tables — no runtime coupling, no FK declaration, no cascade by this service.

6. Enum values

Enum Values Persisted as Defined in
VehicleType Plane=0, Copter=1, UGV=2, GuidedMissile=3 INTEGER Enums/VehicleType.cs (post-B6)
FuelType Electric=0, Gasoline=1, Diesel=2 INTEGER Enums/FuelType.cs
WaypointSource Operator=0, Mission=1, ... INTEGER Enums/WaypointSource.cs
WaypointObjective Surveillance=0, Strike=1, ... INTEGER Enums/WaypointObjective.cs
ObjectStatus Active=0, Lost=1, ... INTEGER Enums/ObjectStatus.cs (used only by MapObject)

Per _docs/02_document/modules/enums.md, integer values are NOT range-validated on input — model binding accepts any int.

7. Inbound data shapes (HTTP)

Endpoint Method Body / Query Returns
/vehicles GET ?name=&isDefault= List<Vehicle> (PascalCase JSON; not paginated)
/vehicles/{id} GET Vehicle
/vehicles POST CreateVehicleRequest Vehicle (created)
/vehicles/{id} PUT UpdateVehicleRequest (partial) Vehicle (updated)
/vehicles/{id}/setDefault POST SetDefaultRequest Vehicle
/vehicles/{id} DELETE 204 / 409 if referenced
/missions GET ?name=&fromDate=&toDate=&page=&pageSize= PaginatedResponse<Mission>
/missions/{id} GET Mission
/missions POST CreateMissionRequest Mission (created)
/missions/{id} PUT UpdateMissionRequest (partial) Mission (updated)
/missions/{id} DELETE 204 / 404; runs F3 cascade
/missions/{id}/waypoints GET List<Waypoint> (unpaginated, ordered by OrderNum)
/missions/{id}/waypoints POST CreateWaypointRequest Waypoint (created)
/missions/{id}/waypoints/{wpId} PUT UpdateWaypointRequest (full overwrite) Waypoint
/missions/{id}/waypoints/{wpId} DELETE 204; runs F4 scoped cascade
/health GET — anonymous 200 { "status": "healthy" }

All routes except /health require JWT bearer with permissions=FL claim.