[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:
Oleksandr Bezdieniezhnykh
2026-05-22 11:24:27 +03:00
parent 865dfdb3b9
commit bc04ba7f99
17 changed files with 779 additions and 32 deletions
+2 -1
View File
@@ -5,7 +5,7 @@
**Language**: csharp
**Layout Convention**: custom (per-component .csproj per logical component)
**Root**: ./
**Last Updated**: 2026-05-12 (cycle 6 — AZ-505 tile inventory + Leaflet covering index + HTTP/2: new `POST /api/satellite/tiles/inventory` endpoint, new `ITileRepository.GetTilesByLocationHashesAsync`, rewired `GetByTileCoordinatesAsync` to filter on `location_hash`, migration `015_AddTilesLeafletPathIndex.sql`, Kestrel `Http1AndHttp2`, new `TileInventory*` DTOs in Common; cycle 5 — AZ-503 tile-identity foundation added: `SatelliteProvider.Common/Utils/Uuidv5.cs`, migration `014_AddTileIdentityColumns.sql`, 4 new `TileEntity` columns, integer-only flight-aware UPSERT, IntegrationTests → Common ProjectReference)
**Last Updated**: 2026-05-22 (cycle 7 — AZ-794 + AZ-795 + AZ-796 strict inventory validation + z/x/y rename: `TileCoord` wire fields renamed `tileZoom/tileX/tileY``z/x/y` with `[JsonRequired]`; new `SatelliteProvider.Api/Validators/{InventoryRequestValidator,ValidationEndpointFilter,GlobalValidatorConfig,ValidationEndpointFilterExtensions}.cs`; new `SatelliteProvider.Api/GlobalExceptionHandler.cs` for `JsonException``ValidationProblemDetails`; FluentValidation 12.0.0 + `JsonSerializerOptions.UnmappedMemberHandling.Disallow` wired into `Program.cs`; new contract `_docs/02_document/contracts/api/error-shape.md` v1.0.0; `tile-inventory.md` bumped to v2.0.0; new `SatelliteProvider.IntegrationTests/ProblemDetailsAssertions.cs` + `TileInventoryValidationTests.cs`; new `SatelliteProvider.Tests/TestSupport/ValidatorTestModuleInitializer.cs` + `Validators/InventoryRequestValidatorTests.cs`; new `scripts/probe_inventory_validation.sh`; cycle 6 — AZ-505 tile inventory + Leaflet covering index + HTTP/2: new `POST /api/satellite/tiles/inventory` endpoint, new `ITileRepository.GetTilesByLocationHashesAsync`, rewired `GetByTileCoordinatesAsync` to filter on `location_hash`, migration `015_AddTilesLeafletPathIndex.sql`, Kestrel `Http1AndHttp2`, new `TileInventory*` DTOs in Common; cycle 5 — AZ-503 tile-identity foundation added: `SatelliteProvider.Common/Utils/Uuidv5.cs`, migration `014_AddTileIdentityColumns.sql`, 4 new `TileEntity` columns, integer-only flight-aware UPSERT, IntegrationTests → Common ProjectReference)
## Layout Rules
@@ -129,6 +129,7 @@ The cycle-1 (AZ-487) and cycle-2 (AZ-488) code reviews each surfaced an F1 (Low
- `SatelliteProvider.Api/Validators/ValidationEndpointFilter.cs` + `ValidationEndpointFilterExtensions.cs` (added by AZ-795; generic `IEndpointFilter<T>` that runs the registered `IValidator<T>` and returns `Results.ValidationProblem` on failure; opt-in via `RouteHandlerBuilder.WithValidation<T>()`)
- `SatelliteProvider.Api/Validators/InventoryRequestValidator.cs` + `TileCoordValidator` (added by AZ-796; FluentValidation rules for `POST /api/satellite/tiles/inventory` — XOR `tiles`/`locationHashes`, per-array cap, slippy-map range checks)
- `SatelliteProvider.Api/Validators/GlobalValidatorConfig.cs` (added by AZ-795/AZ-796; idempotent `ApplyOnce()` configures `ValidatorOptions.Global.PropertyNameResolver` so `errors`-map keys are camelCase per `error-shape.md` Inv-4; called from `Program.cs` and from the test assembly's `ModuleInitializer`)
- `SatelliteProvider.Api/GlobalExceptionHandler.cs` (added by AZ-795; `IExceptionHandler` registered via `AddExceptionHandler<GlobalExceptionHandler>()`. Intercepts `BadHttpRequestException(JsonException)` from System.Text.Json's strict-parsing path — unknown-member rejection, missing required field via `[JsonRequired]`, JSON type mismatch — and emits `ValidationProblemDetails` with the same `errors[]` map shape that FluentValidation produces. 5xx errors pass through with sanitised body + `correlationId` per AZ-353.)
- **Internal**: (none)
- **Owns**: `SatelliteProvider.Api/**`
- **PackageReferences (added by AZ-487, bumped by AZ-496, then by AZ-500; AZ-795 added FluentValidation)**: `Microsoft.AspNetCore.Authentication.JwtBearer` 10.0.7 (pinned to the same minor patch as `Microsoft.AspNetCore.OpenApi` 10.0.7; AZ-496 bumped both packages from 8.0.21 → 8.0.25 in cycle 3 to close cycle-1 D1 + cycle-2 D3 supply-chain findings, then AZ-500 bumped both 8.0.25 → 10.0.7 in cycle 4 as part of the .NET 8 → .NET 10 migration; AZ-500 also bumped `Swashbuckle.AspNetCore` 6.6.2 → 10.1.7 here to land Microsoft.OpenApi 2.x compat required by ASP.NET Core 10). `FluentValidation` + `FluentValidation.DependencyInjectionExtensions` 12.0.0 added by AZ-795 to back the strict-input-validation epic.