mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-22 17:21:15 +00:00
[AZ-794] [AZ-795] [AZ-796] Strict input validation + z/x/y rename
AZ-794: rename inventory wire fields tileZoom/tileX/tileY -> z/x/y to match the slippy-map URL convention. Contract bumped to v2.0.0. AZ-795: shared validation infrastructure -- FluentValidation + ValidationEndpointFilter + GlobalValidatorConfig (camelCase paths). GlobalExceptionHandler now converts JsonException (UnmappedMember + JsonRequired) into RFC 7807 ValidationProblemDetails. JSON layer hardened with UnmappedMemberHandling.Disallow + camelCase naming policy. New error-shape.md contract. AZ-796: InventoryRequestValidator covers 9 rules (XOR tiles vs locationHashes, cap 1000, z 0..22, x/y in slippy bounds, hash length/charset). 16 unit tests + 16 integration tests + a manual curl probe script. Adjacent fixes uncovered by the new strict layer: - IdempotentPostTests RoutePoint payload corrected to lat/lon (the DTO has used JsonPropertyName for ages; previously silently ignored under PascalCase fallback). - TileInventoryTests slippy x/y reduced to fit z=18 bounds. - docker-compose.yml host port for Postgres moved 5432 -> 5433 to avoid sibling-project conflict; appsettings.Development + README + AGENTS + architecture + containerization docs aligned. New coderule (suite + repo): API consumer-facing OpenAPI descriptions must not contain task IDs, contract filenames, or version-bump history -- internal change tracking belongs in commits/contract docs/changelogs. Existing offending descriptions in Program.cs cleaned up. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace SatelliteProvider.Common.DTO;
|
||||
|
||||
// AZ-505: bulk-list / inventory request envelope. Either `Tiles` OR
|
||||
@@ -12,21 +14,33 @@ public sealed class TileInventoryRequest
|
||||
public IReadOnlyList<Guid>? LocationHashes { get; set; }
|
||||
}
|
||||
|
||||
// AZ-505: Slippy-map tile coordinate triple. Field naming matches the on-wire
|
||||
// snake_case used by the existing `GET /tiles/{z}/{x}/{y}` and the AZ-484/AZ-503
|
||||
// `tiles` table columns (`tile_zoom`, `tile_x`, `tile_y`).
|
||||
// AZ-505: Slippy-map tile coordinate triple. AZ-794 (cycle 7) renamed the
|
||||
// wire-format fields from `tileZoom/tileX/tileY` → `z/x/y` to align with the
|
||||
// OSM / slippy-map convention already used by `GET /tiles/{z}/{x}/{y}` and
|
||||
// to shave wire-size on inventory requests carrying thousands of entries.
|
||||
// The C# property names (`Z`, `X`, `Y`) intentionally mirror the wire names
|
||||
// 1:1 so consumers don't need to mentally translate at the deserialization
|
||||
// boundary. The DataAccess `TileEntity.TileZoom/TileX/TileY` columns are
|
||||
// unchanged — that's a database identity, not a wire format.
|
||||
public sealed class TileCoord
|
||||
{
|
||||
public int TileZoom { get; set; }
|
||||
public int TileX { get; set; }
|
||||
public int TileY { get; set; }
|
||||
[JsonRequired]
|
||||
public int Z { get; set; }
|
||||
|
||||
[JsonRequired]
|
||||
public int X { get; set; }
|
||||
|
||||
[JsonRequired]
|
||||
public int Y { get; set; }
|
||||
}
|
||||
|
||||
// AZ-505: Inventory response. Entries are returned in the SAME ORDER as the
|
||||
// matching request input (per AC-1). When Request.Tiles was populated, each
|
||||
// entry's `TileZoom`/`TileX`/`TileY` echoes the request entry; when
|
||||
// Request.LocationHashes was populated, the coord triple fields are 0 (the
|
||||
// caller already knows the hash and can map it back themselves).
|
||||
// entry's `Z`/`X`/`Y` echoes the request entry; when Request.LocationHashes
|
||||
// was populated, the coord triple fields are 0 (the caller already knows
|
||||
// the hash and can map it back themselves). AZ-794 (cycle 7) renamed the
|
||||
// coord triple to `z/x/y` to align wire format with the URL-path
|
||||
// convention.
|
||||
public sealed class TileInventoryResponse
|
||||
{
|
||||
public IReadOnlyList<TileInventoryEntry> Results { get; set; } = Array.Empty<TileInventoryEntry>();
|
||||
@@ -40,11 +54,14 @@ public sealed class TileInventoryResponse
|
||||
// `EstimatedBytes` is intentionally absent in v1.0.0 — adding the per-row
|
||||
// `stat()` cost is deferred until production profiling justifies it (see
|
||||
// AZ-505 Outcome bullet 1 + Excluded list).
|
||||
//
|
||||
// AZ-794 (cycle 7): coord triple renamed `tileZoom/tileX/tileY` → `z/x/y`
|
||||
// (contract bumped to v2.0.0).
|
||||
public sealed class TileInventoryEntry
|
||||
{
|
||||
public int TileZoom { get; set; }
|
||||
public int TileX { get; set; }
|
||||
public int TileY { get; set; }
|
||||
public int Z { get; set; }
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
public Guid LocationHash { get; set; }
|
||||
public bool Present { get; set; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user