mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 19:51:14 +00:00
[AZ-794] [AZ-795] [AZ-796] Cycle 7 Steps 12-15 sync (test-spec / docs / security / perf)
Step 12 (Test-Spec Sync): adds BT-27 for the AZ-796 9-rule validation surface and 12 cycle-7 AC rows + Coverage Summary update to traceability-matrix.md. Step 13 (Update Docs): module-layout + module docs for the new SatelliteProvider.Api/Validators namespace + GlobalExceptionHandler + updated TileInventory DTO; tests_unit + tests_integration document the new InventoryRequestValidatorTests (16 unit tests covering all 9 rules) + TileInventoryValidationTests (16 integration tests) + ProblemDetailsAssertions support; glossary entries for Validation Problem Details / FluentValidation / Unmapped Member Handling; system-flows F8 (Tile Inventory Bulk Lookup) expanded with deserializer + validator gates and a 13-row Validation Surface table; data_parameters § Tile Inventory documents the v2 input schema + constraints; ripple_log_cycle7 captures the doc-side ripple decisions. Step 14 (Security Audit): 5-phase audit ran; verdict PASS_WITH_WARNINGS (3 Low findings — D-AZ795-1 FluentValidation 12.0.0 -> 12.1.1 recommended bump, F-AZ795-1 JsonException.Message leak in 400 detail, F-AZ795-2 BadHttpRequestException.Message leak). No Critical / High; auth runs before validation (confirmed in Program.cs); two NuGet additions (FluentValidation 12.0.0 + .DependencyInjectionExtensions 12.0.0) both CVE-clean. Per-phase reports plus consolidated security_report_cycle7.md. Step 15 (Performance Test): docker compose stack used for perf run, scripts/run-performance-tests.sh exited 0 with 8/8 scenarios PASS (second consecutive clean exit-0); added PT-09 cycle-7 smoke probe (v2 z/x/y schema, 2500-tile all-miss batch) measuring min=27ms median=44ms p95=73ms max=86ms (13.7x under AZ-505 AC-4 1000ms budget). PT-07/08 improvements traced to the cycle-6 TLS handshake-overhead identification, not application-side change. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -110,21 +110,23 @@ Authoritative reject-reason codes for the UAV upload quality gate. Adding a new
|
||||
- `ImageTooUniform = "IMAGE_TOO_UNIFORM"` — Rule 5 (luminance variance below `MinLuminanceVariance`).
|
||||
- `StorageFailure = "STORAGE_FAILURE"` — reserved for the orphan-row-recovery path when the on-disk write succeeds but the DB UPSERT fails; surfaced per-item without failing the envelope (AZ-488 Reliability NFR).
|
||||
|
||||
### TileCoord (added AZ-505)
|
||||
### TileCoord (added AZ-505, renamed AZ-794 cycle 7)
|
||||
Single tile coordinate triple used by the inventory endpoint Form A request shape and as the per-entry input echo on the response.
|
||||
- `TileZoom` (int) — slippy zoom level.
|
||||
- `TileX`, `TileY` (int) — slippy x/y at that zoom.
|
||||
- Defined in `SatelliteProvider.Common/DTO/TileInventory.cs`. Matches `tile-inventory.md` v1.0.0 Shape.
|
||||
- `Z` (int) `[JsonRequired]` — slippy zoom level. Wire name `"z"`.
|
||||
- `X` (int) `[JsonRequired]` — slippy x at that zoom. Wire name `"x"`.
|
||||
- `Y` (int) `[JsonRequired]` — slippy y at that zoom. Wire name `"y"`.
|
||||
- Defined in `SatelliteProvider.Common/DTO/TileInventory.cs`. Matches `tile-inventory.md` v2.0.0 Shape (the rename from `tileZoom/tileX/tileY` shipped in AZ-794; the `[JsonRequired]` markers + the global `UnmappedMemberHandling.Disallow` mean missing axes and the legacy field names both surface as HTTP 400 with `ValidationProblemDetails` per `error-shape.md` v1.0.0).
|
||||
|
||||
### TileInventoryRequest (added AZ-505)
|
||||
API request body for `POST /api/satellite/tiles/inventory`. Carries one of two XOR-exclusive batch shapes.
|
||||
- `Tiles` (`IReadOnlyList<TileCoord>?`) — Form A: coords-by-value. The server computes `location_hash = Uuidv5(TileNamespace, "{z}/{x}/{y}")` per entry.
|
||||
- `LocationHashes` (`IReadOnlyList<Guid>?`) — Form B: hashes-by-reference. Used when the caller already has UUIDv5 location hashes (typical for the onboard cross-repo path).
|
||||
- Exactly one of `Tiles` / `LocationHashes` must be populated and non-empty; both-populated or neither → HTTP 400 (`tile-inventory.md` Inv-1).
|
||||
- Exactly one of `Tiles` / `LocationHashes` must be populated and non-empty; both-populated or neither → HTTP 400 (`tile-inventory.md` v2.0.0 Inv-1, enforced by `InventoryRequestValidator` via `ValidationEndpointFilter<TileInventoryRequest>` in cycle 7).
|
||||
- Total entries (in either field) ≤ `TileInventoryLimits.MaxEntriesPerRequest` (5000); over-cap → HTTP 400 (Inv-7).
|
||||
|
||||
### TileInventoryEntry (added AZ-505)
|
||||
### TileInventoryEntry (added AZ-505, coord fields renamed AZ-794 cycle 7)
|
||||
Per-entry result inside `TileInventoryResponse`. One entry per request entry, in the SAME order as the request (`tile-inventory.md` Inv-2).
|
||||
- `Z`, `X`, `Y` (int) — echoed coord triple matching the request entry; wire names `"z"`, `"x"`, `"y"` (renamed from `"tileZoom"`/`"tileX"`/`"tileY"` by AZ-794). Always populated; when Form B was used, these are 0 (the caller already knows the hash).
|
||||
- `LocationHash` (Guid) — always populated; UUIDv5 of `"{z}/{x}/{y}"` from `Uuidv5.LocationHashForTile` (Form A) or echoed from request (Form B).
|
||||
- `Present` (bool) — `true` iff a row exists in `tiles` with this `location_hash` (Inv-4).
|
||||
- `Id` (Guid?) — `tiles.id` of the most-recent row across sources/flights (`captured_at DESC, updated_at DESC, id DESC`, Inv-5); null when `Present=false` (Inv-6).
|
||||
@@ -135,7 +137,7 @@ API response body for `POST /api/satellite/tiles/inventory`.
|
||||
- `Results` (`IReadOnlyList<TileInventoryEntry>`) — one entry per request entry; `Results.Count` always equals the request entry count (Inv-2).
|
||||
|
||||
### TileInventoryLimits (added AZ-505, static constants)
|
||||
- `MaxEntriesPerRequest = 5000` — request-body cap enforced by the inventory handler (Inv-7).
|
||||
- `MaxEntriesPerRequest = 5000` — request-body cap enforced by `InventoryRequestValidator` (per-array cap; `tile-inventory.md` v2.0.0 Inv-7).
|
||||
|
||||
## Internal Logic
|
||||
- `GeoPoint` uses a precision tolerance of `0.00005` degrees (~5.5 meters) for equality comparison.
|
||||
|
||||
Reference in New Issue
Block a user