Files
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

4.4 KiB
Raw Permalink Blame History

Module: Azaion.Missions.Controllers.MissionsController

File: Controllers/MissionsController.cs

NOTE (forward-looking): post-rename + post-route-change. Today's source is Controllers/FlightsController.cs mounted at [Route("flights")] with nested waypoint routes under /flights/{id}/waypoints/.... Renames + route changes tracked under Jira AZ-EPIC children B6 + B8.

Purpose

REST surface for the missions resource AND its nested waypoints sub-resource. Wraps MissionService for the parent and WaypointService for the nested routes.

Public Interface

Missions

HTTP Route Action Body / Query Returns
POST /missions Create CreateMissionRequest 201 + Location: /missions/{id}, body: Mission
PUT /missions/{id:guid} Update UpdateMissionRequest 200, body: Mission
GET /missions/{id:guid} Get -- 200, body: Mission
GET /missions GetAll GetMissionsQuery (Name?, FromDate?, ToDate?, Page=1, PageSize=20) 200, body: PaginatedResponse<Mission>
DELETE /missions/{id:guid} Delete -- 204

Waypoints (nested under a mission)

HTTP Route Action Body Returns
POST /missions/{id:guid}/waypoints CreateWaypoint CreateWaypointRequest 201 + Location: /missions/{id}/waypoints/{wpId}, body: Waypoint
PUT /missions/{id:guid}/waypoints/{waypointId:guid} UpdateWaypoint UpdateWaypointRequest 200, body: Waypoint
DELETE /missions/{id:guid}/waypoints/{waypointId:guid} DeleteWaypoint -- 204
GET /missions/{id:guid}/waypoints GetWaypoints -- 200, body: List<Waypoint> (no pagination)

Class-level decorators: [ApiController], [Route("missions")], [Authorize(Policy = "FL")].

Internal Logic

Same pattern as VehiclesController: each action awaits the appropriate service method and wraps in Created / Ok / NoContent.

Dependencies

  • MissionService, WaypointService (constructor-injected; primary constructor)
  • Azaion.Missions.DTOs

Consumers

  • HTTP clients.
  • Cross-service callers in the suite: autopilot reads GET /missions/{id} + GET /missions/{id}/waypoints to drive UAV behavior; ui paginates /missions. Both will need to be updated to the new prefix as part of B11 (consumer updates).

Data Models

Returns Mission (which has Vehicle? + List<Waypoint> association properties) and Waypoint (with Mission? association property) directly. Whether associations are populated on the wire depends on LinqToDB query behavior -- by default, FirstOrDefaultAsync(predicate) does NOT eager-load associations, so mission.Vehicle and mission.Waypoints will serialize as null/empty in JSON. Verify in Step 4 against actual API responses if available.

Configuration / External Integrations

None directly.

Security

  • All routes behind [Authorize(Policy = "FL")].
  • Composite-key handling in waypoint operations means a stolen waypoint id alone is not enough -- the attacker must also know the parent mission id.

Tests

None present.

Notes / Smells

  1. Inconsistent listing pagination -- GET /missions paginates, GET /missions/{id}/waypoints and GET /vehicles do not. Verification flag.
  2. Nested resource modeling -- waypoints are exposed only as a sub-resource of a mission, never as /waypoints/{id}. Consistent with the data model (mission_id is NOT NULL).
  3. Update of a mission allows changing vehicle_id but the controller doesn't reflect any business constraint (e.g., immutable after start). All such constraints would need to live in the service.
  4. No bulk endpoints -- no batch create / batch delete for waypoints despite the natural use case ("upload a route plan").
  5. Entity body PascalCase wire shape -- the whole API has no JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase, so Mission, Waypoint, and PaginatedResponse<Mission> responses serialize PascalCase property names. Spec says camelCase (per ../../suite/_docs/00_top_level_architecture.md). Note: the global error envelope produced by ErrorHandlingMiddleware is already camelCase (anonymous object literal) -- this divergence applies only to entity / DTO bodies (see middleware.md Notes #1#2 for the distinction). Carry to verification log.