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

3.8 KiB

Flow F2 — Mission create / read / update

Post-rename. Today: [Route("flights")], Flight* files.

Description

Mission CRUD excluding delete (delete is the cross-service cascade in F3). Create / update validate that the referenced vehicle_id exists; list (GET /missions) is the only paginated endpoint in this service.

Preconditions

  • Service is running, schema in place (F6).
  • Caller holds JWT with permissions=FL (F5).
  • For create / update with VehicleId: the referenced vehicle exists (F1).

Sequence Diagram (POST /missions)

sequenceDiagram
    autonumber
    participant UI as Operator UI
    participant Identity as 05_identity
    participant Errs as 06_http_conventions
    participant Ctrl as MissionsController
    participant MS as MissionService
    participant DB as 04_persistence (postgres-local)

    UI->>Identity: POST /missions + JWT + { Name, VehicleId }
    Identity-->>Ctrl: authorized (policy "FL")
    Ctrl->>MS: CreateMission(req)
    MS->>DB: SELECT 1 FROM vehicles WHERE id = @VehicleId
    alt Vehicle missing
        DB-->>MS: 0 rows
        MS-->>Errs: throw ArgumentException("VehicleId not found")
        note right of MS: Spec says 404; code returns 400. Carry-forward.
        Errs-->>UI: 400 Bad Request (PascalCase error envelope)
    else Vehicle exists
        DB-->>MS: 1 row
        MS->>DB: INSERT INTO missions (id, name, vehicle_id, created_date) VALUES (...)
        DB-->>MS: row inserted
        MS-->>Ctrl: Mission entity
        Ctrl-->>UI: 201 Created + Mission (Vehicle / Waypoints serialize as null / [] — no eager load)
    end

Flowchart (GET /missions paginated)

flowchart TD
    Start([GET /missions?Name=&FromDate=&ToDate=&Page=&PageSize=]) --> Auth{JWT + FL valid?}
    Auth -->|no| Reject([401 / 403])
    Auth -->|yes| Build[Build LINQ predicate from optional filters]
    Build --> Count[COUNT * over filtered set]
    Count --> Page[SELECT ... ORDER BY created_date DESC LIMIT pageSize OFFSET]
    Page --> Wrap[Wrap in PaginatedResponse Items, TotalCount, Page, PageSize]
    Wrap --> Done([200 OK + envelope, PascalCase])

Data Flow

Step From To Data Format
1 UI MissionsController CreateMissionRequest / UpdateMissionRequest / GetMissionsQuery JSON / query string (PascalCase)
2 MissionService vehicles table existence check SELECT 1 SQL
3 MissionService missions table INSERT / UPDATE / SELECT SQL
4 MissionService UI Mission entity / PaginatedResponse<Mission> JSON (PascalCase)

Error Scenarios

Error Where Detection Recovery
VehicleId missing on create / update MissionService.CreateMission / UpdateMission existence check returns false ArgumentException400 (spec wants 404 — minor divergence, B-set carry-forward)
TOCTOU: vehicle deleted between existence check and insert MissionService.CreateMission FK constraint violation Npgsql PostgresException → middleware → 500. UX gap (should be 400); rare in practice
Mission not found MissionService.GetMission / UpdateMission entity lookup null KeyNotFoundException404
Page / PageSize out of range None enforced n/a LinqToDB Skip(negative) / Take(0) returns empty set; no error returned to client

Performance Expectations

Metric Target Notes
End-to-end latency (single mission) <15ms typical Two round-trips on create (existence check + insert); one on read
Paginated list latency <30ms typical for ≤1000 rows No index on created_date — full scan + sort. Add ix_missions_created_date if list latency becomes an issue
Throughput Operator-paced Not load-tested