Files
satellite-provider/_docs/03_implementation/batch_02_cycle8_report.md
T
Oleksandr Bezdieniezhnykh 34ee1e0b83 [AZ-808] [AZ-811] Strict validation on region POST + lat/lon GET
AZ-808: FluentValidation for POST /api/satellite/request
- RegionRequestValidator: id non-empty, lat/lon/sizeMeters/zoomLevel ranges
- RequestRegionRequest: [JsonRequired] on every property, no implicit defaults
- Wired via .WithValidation<RequestRegionRequest>() in MapPost chain
- Unit + integration tests + curl probe script
- New contract: contracts/api/region-request.md v1.0.0

AZ-811: FluentValidation + envelope filter for GET /api/satellite/tiles/latlon
- GetTileByLatLonQuery: nullable record (double?/int?) so the minimal-API
  binder never short-circuits with BadHttpRequestException before filters
- GetTileByLatLonQueryValidator: Cascade(Stop) + NotNull + InclusiveBetween
  per param; missing surfaces as `\`<name>\` is required.`
- RejectUnknownQueryParamsEndpointFilter: reusable IEndpointFilter that
  rejects any query key outside the allowed set with errors[<key>] map;
  catches legacy `?Latitude=` typos and hostile probes (`?debug=1&admin=1`)
- Handler: [AsParameters] GetTileByLatLonQuery + .Value deref post-validator
- Unit (validator + filter) + integration tests + curl probe script
- New contract: contracts/api/tile-latlon.md v1.0.0

Shared hygiene
- Promote AssertErrorsContainsMention from per-test-file private helpers to
  ProblemDetailsAssertions (closes batch-1 Low-severity DRY warning)
- Sync Swagger param descriptions, README, blackbox/security/perf scripts,
  uuidv5 doc with the new lat/lon/zoom query-param names

Docs
- system-flows.md F1/F2 reference the new contracts + validation layers
- modules/api_program.md adds Api/Validators + Api/DTOs sections
- _autodev_state.md: batch 2 of 4 complete; next batch = AZ-809

All smoke tests green (mode=smoke, exit 0). AZ-808 + AZ-811 transitioned
to In Testing on Jira.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 16:29:41 +03:00

8.0 KiB

Batch Report

Batch: 02 (cycle 8) Tasks: AZ-808 (Region POST strict validation) + AZ-811 (lat/lon GET strict validation) Date: 2026-05-22

Task Results

Task Status Files Modified Tests AC Coverage Issues
AZ-808_region_endpoint_validation Done 10 files (4 new) smoke pass (mode=smoke, exit 0); 10 integration tests added 8/8 ACs covered none
AZ-811_latlon_get_endpoint_validation Done 19 files (8 new) smoke pass; 8 integration tests + 4 filter unit tests + 9 validator unit tests added 9/9 ACs covered 1 Info (nullable DTO rationale, documented)

AC Test Coverage

AZ-808 (8/8 ACs)

AC Coverage
AC-1 RegionRequestValidator exists at SatelliteProvider.Api/Validators/RegionRequestValidator.cs with rules for id (non-empty), lat ([-90, 90]), lon ([-180, 180]), sizeMeters ([100, 10000]), zoomLevel ([0, 22]).
AC-2 Happy path: RegionRequestValidationTests.HappyPath_Returns200 returns HTTP 200. Smoke green.
AC-3 Wired via .WithValidation<RequestRegionRequest>() in Program.cs MapPost chain.
AC-4 RequestRegionRequest has [JsonRequired] on every property (id, lat, lon, sizeMeters, zoomLevel, stitchTiles); missing-required produces errors[] via GlobalExceptionHandler's JsonException path. Tested by MissingId_Returns400 and MissingStitchTiles_Returns400.
AC-5 Unit tests SatelliteProvider.Tests/Validators/RegionRequestValidatorTests.cs — 11 methods covering each rule with positive + negative cases.
AC-6 Integration tests SatelliteProvider.IntegrationTests/RegionRequestValidationTests.cs — 10 methods covering happy + 9 failure modes; all green in smoke.
AC-7 New contract _docs/02_document/contracts/api/region-request.md v1.0.0 published. References error-shape.md v1.0.0 for 400 body shape.
AC-8 Probe script scripts/probe_region_validation.sh covers happy + each failure mode via curl.

AZ-811 (9/9 ACs)

AC Coverage
AC-1 5 validations enforced: lat/lon/zoom range (validator), unknown-key (envelope filter), type-mismatch (model binder via GlobalExceptionHandler). All produce HTTP 400 + ValidationProblemDetails per error-shape.md v1.0.0.
AC-2 Happy path: GetTileByLatLonValidationTests.HappyPath_Returns200 returns HTTP 200 + DownloadTileResponse. Smoke green.
AC-3 GetTileByLatLonQueryValidator lives at SatelliteProvider.Api/Validators/; unit tests cover 9 methods (3 per RuleFor + 3 null cases).
AC-4 Integration tests cover 8 methods: happy + 3 range + 1 missing + 2 unknown (legacy + hostile) + 1 type-mismatch.
AC-5 New contract _docs/02_document/contracts/api/tile-latlon.md v1.0.0 published. References error-shape.md v1.0.0 + tile-inventory.md v2.0.0.
AC-6 _docs/02_document/modules/api_program.md::GetTileByLatLon Handler updated; references the validator + new contract + the envelope filter ordering.
AC-7 OpenAPI: .Accepts<> not needed for GET; .Produces<DownloadTileResponse>(200) + .ProducesProblem(400) declared on the endpoint chain. Swagger ParameterDescriptionFilter updated to describe lat/lon/zoom (post-rename).
AC-8 Probe script scripts/probe_latlon_validation.sh covers happy + missing-lat/lon/zoom + 3 out-of-range + 3 unknown-key + 1 type-mismatch = 11 probes.
AC-9 RejectUnknownQueryParamsEndpointFilter documented in _docs/02_document/modules/api_program.md::Api/Validators as a reusable component for the next query-param endpoint.

Code Review Verdict: PASS_WITH_NOTES

See _docs/03_implementation/reviews/batch_02_cycle8_review.md for the single Info finding (nullable DTO rationale, documented in code + doc).

Auto-Fix Attempts: 1 (mid-batch)

  • AZ-811 initially used non-nullable types on GetTileByLatLonQuery. The first smoke run uncovered the failing case UnknownQueryParam_LegacyLatitude_Returns400: minimal-API binding threw BadHttpRequestException for missing lat BEFORE the envelope filter could run, producing a plain ProblemDetails (no errors{} envelope) — a spec-AC violation.
  • Root-cause investigation via diagnostic instrumentation (Console.Error.WriteLine in the filter + Console.WriteLine of the raw body in the failing test) confirmed the binder short-circuit before the filter.
  • Fix: nullable types on the DTO + NotNull + CascadeMode.Stop in the validator + .Value dereference in the handler. Rationale documented in GetTileByLatLonQuery.cs and api_program.md::Api/DTOs.
  • Smoke re-run after fix: all green (no skipped tests, no flakes).

Stuck Agents: None

Files Modified

AZ-808

Path Kind
SatelliteProvider.Common/DTO/RequestRegionRequest.cs [JsonRequired] on every property + removed implicit defaults
SatelliteProvider.Api/Validators/RegionRequestValidator.cs NEW
SatelliteProvider.Api/Program.cs .WithValidation<RequestRegionRequest>() + removed inline size check
SatelliteProvider.Tests/Validators/RegionRequestValidatorTests.cs NEW
SatelliteProvider.IntegrationTests/RegionRequestValidationTests.cs NEW
SatelliteProvider.IntegrationTests/Program.cs Wired into smoke + full suites
scripts/probe_region_validation.sh NEW
_docs/02_document/contracts/api/region-request.md NEW v1.0.0
_docs/02_document/modules/api_program.md RequestRegion handler description
_docs/02_document/system-flows.md F2 description

AZ-811

Path Kind
SatelliteProvider.Api/DTOs/GetTileByLatLonQuery.cs NEW (nullable record)
SatelliteProvider.Api/Validators/GetTileByLatLonQueryValidator.cs NEW
SatelliteProvider.Api/Validators/RejectUnknownQueryParamsEndpointFilter.cs NEW (reusable)
SatelliteProvider.Api/Program.cs Endpoint filter + .WithValidation + handler signature + .Value deref
SatelliteProvider.Api/Swagger/ParameterDescriptionFilter.cs lat/lon/zoom descriptions
SatelliteProvider.Tests/Validators/GetTileByLatLonQueryValidatorTests.cs NEW (9 methods)
SatelliteProvider.Tests/Validators/RejectUnknownQueryParamsEndpointFilterTests.cs NEW (4 methods)
SatelliteProvider.IntegrationTests/GetTileByLatLonValidationTests.cs NEW (8 methods)
SatelliteProvider.IntegrationTests/TileTests.cs URL ?lat=&lon=&zoom=
SatelliteProvider.IntegrationTests/JwtIntegrationTests.cs ProtectedTilesPath const
SatelliteProvider.IntegrationTests/SecurityTests.cs SQLi probe URL
SatelliteProvider.IntegrationTests/Program.cs Wired into smoke + full suites
scripts/probe_latlon_validation.sh NEW
scripts/run-performance-tests.sh PT-01 URL update
README.md Endpoint example
_docs/02_document/contracts/api/tile-latlon.md NEW v1.0.0
_docs/02_document/modules/api_program.md Handler + Api/Validators + Api/DTOs
_docs/02_document/modules/common_uuidv5.md Example URL
_docs/02_document/system-flows.md F1 description
_docs/02_document/tests/blackbox-tests.md BT-01/N01/N02/18 triggers
_docs/02_document/tests/security-tests.md SEC-01/05 triggers

Shared

Path Kind
SatelliteProvider.IntegrationTests/ProblemDetailsAssertions.cs Promoted AssertErrorsContainsMention to shared helper (closes batch-1 DRY warning)
SatelliteProvider.IntegrationTests/TileInventoryValidationTests.cs Use shared helper
SatelliteProvider.IntegrationTests/RegionFieldRenameTests.cs Use shared helper

Tracker

  • AZ-808: To Do → In Progress (batch 2 start) → In Testing (post-smoke).
  • AZ-811: To Do → In Progress (batch 2 start) → In Testing (post-smoke).

Next Batch

Batch 3: AZ-809 — route-creation validator (3 DTOs, cross-field constraint: regionSizeMeters covers geofence overlap). Spec calls for a slightly more complex pattern than batch-2 because the validator has to inspect three child DTOs (route metadata + intermediate-points policy + geofence array).