mirror of
https://github.com/azaion/missions.git
synced 2026-06-21 14:01:07 +00:00
7025f4d075
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.
7.3 KiB
7.3 KiB
Module: Azaion.Missions.DTOs
Files (15) -- grouped by concern:
| Group | Files |
|---|---|
| Shared value objects | GeoPoint.cs |
| Shared response wrappers | PaginatedResponse.cs, ErrorResponse.cs |
| Vehicle requests/queries | CreateVehicleRequest.cs, UpdateVehicleRequest.cs, GetVehiclesQuery.cs, SetDefaultRequest.cs |
| Mission requests/queries | CreateMissionRequest.cs, UpdateMissionRequest.cs, GetMissionsQuery.cs |
| Waypoint requests | CreateWaypointRequest.cs, UpdateWaypointRequest.cs |
NOTE (forward-looking): post-rename file names. Today's source has
CreateAircraftRequest.cs/CreateFlightRequest.cs/ etc. Renames tracked under Jira AZ-EPIC child B6.
Purpose
HTTP request/response/query payloads for the controller layer. Plain POCOs with public mutable properties -- no validation attributes, no record types.
Public Interface
Shared
public class GeoPoint {
public decimal? Lat { get; set; }
public decimal? Lon { get; set; }
public string? Mgrs { get; set; } // Military Grid Reference System
}
public class PaginatedResponse<T> {
public List<T> Items { get; set; } = [];
public int TotalCount { get; set; }
public int Page { get; set; }
public int PageSize { get; set; }
}
public class ErrorResponse {
public int StatusCode { get; set; }
public string Message { get; set; } = string.Empty;
public List<string>? Errors { get; set; }
}
Vehicle
public class CreateVehicleRequest {
public VehicleType Type { get; set; } // Plane | Copter | UGV | GuidedMissile
public string Model { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public FuelType FuelType { get; set; }
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 semantics, applied per non-null field
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; }
public bool? IsDefault { get; set; }
}
public class SetDefaultRequest {
public bool IsDefault { get; set; }
}
Mission
public class CreateMissionRequest {
public Guid VehicleId { get; set; }
public string Name { get; set; } = string.Empty;
public DateTime? CreatedDate { get; set; } // Defaults to UtcNow if null
}
public class UpdateMissionRequest {
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;
}
Waypoint
public class CreateWaypointRequest {
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; }
}
public class UpdateWaypointRequest { // identical shape to Create
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; }
}
Internal Logic
Pure data containers. No methods, no constructors beyond the implicit default.
Dependencies
Azaion.Missions.Enums-- for typed enum properties
Consumers
Services.VehicleService,Services.MissionService,Services.WaypointService-- request DTOs as method parameters;PaginatedResponse<Mission>returned fromMissionService.GetMissions.Controllers.VehiclesController,Controllers.MissionsController--[FromBody]/[FromQuery]binding.
Data Models
Mirror the corresponding entity columns minus identity/timestamps (those are server-assigned).
Configuration / External Integrations / Security
None directly -- all binding is provided by ASP.NET Core model binding with no custom validators or [Required] / [Range] attributes.
Tests
None present.
Notes / Smells
- No validation: nothing prevents
CreateVehicleRequest.Name = "", negativeBatteryCapacity,OrderNum < 0, or out-of-range enum values (binding on int will accept any int and persist it). Carry to AC / restrictions in Step 6. UpdateWaypointRequestis structurally identical toCreateWaypointRequestbut uses non-nullable enum/numeric fields, meaning everyPUToverwrites all fields -- no partial-update semantics for waypoints (unlike vehicle, which uses?everywhere). Inconsistency between resources.PaginatedResponse<T>is only used forMissionlisting;GetVehiclesreturns a plainList<Vehicle>(no pagination, no total count), even thoughGetVehiclesQueryexists. Inconsistent listing contract -- matches spec (vehicles are a small dataset).ErrorResponseis defined but not used byErrorHandlingMiddleware(which writes an anonymous object literal). Dead code candidate.GeoPointallows all-null (Lat, Lon, Mgrs all optional). No invariant ensures at least one location representation is populated.- Spec divergence (Geopoint):
../../suite/_docs/02_missions.mdand../../suite/_docs/00_database_schema.mddefineWaypoints.GPSas a singlestring GPSfield with auto-conversion (Lat <-> MGRS). Code stores three separate columns (lat NUMERIC,lon NUMERIC,mgrs TEXT) and exposes them as three flat properties without conversion logic. Carry to verification log. - Spec divergence (ErrorResponse): spec
errorsisobject?keyed by field name (per-field validation arrays). Code definesList<string>? Errorsand the type is unused on the wire (middleware emits an anonymous object instead). Carry to verification log. - Spec divergence (PaginatedResponse case-style): suite-wide standard is camelCase (
items,totalCount,page,pageSize).PaginatedResponse<T>declares PascalCase properties and System.Text.Json's defaults preserve them, so on-the-wire output is{"Items":..., "TotalCount":..., ...}. NoJsonNamingPolicy.CamelCaseis configured. - Spec partial conformance (ErrorResponse / error envelope): the static
ErrorResponseDTO is unused on the wire --Middleware.ErrorHandlingMiddlewarewrites an anonymous object literal instead. That anonymous object happens to use lowercase property names (statusCode,message), whichSystem.Text.Jsonpreserves, so the live error envelope IS camelCase (matching spec on case) but still missing the spec'serrors: object?field. WereErrorResponseever used directly it would emit PascalCase (StatusCode,Message,Errors) and additionally have the wrongErrorsshape (List<string>?vs spec'sobject?). Two carry-forward concerns: add theerrorsfield to the live envelope, and either remove the deadErrorResponseDTO or fix it to match spec.