mirror of
https://github.com/azaion/missions.git
synced 2026-06-22 08:11:07 +00:00
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.
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
# 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`)
|
||||
|
||||
```mermaid
|
||||
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)
|
||||
|
||||
```mermaid
|
||||
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 | `ArgumentException` → `400` (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` | `KeyNotFoundException` → `404` |
|
||||
| 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 |
|
||||
Reference in New Issue
Block a user