namespace SatelliteProvider.Common.DTO; // AZ-505: bulk-list / inventory request envelope. Either `Tiles` OR // `LocationHashes` is populated — never both, never neither. The handler // converts every `(z, x, y)` coord into a `location_hash` via UUIDv5 and // queries `tiles_leaflet_path` once. Response order matches request order. // // Max entries per request: see TileInventoryLimits.MaxEntriesPerRequest. public sealed class TileInventoryRequest { public IReadOnlyList? Tiles { get; set; } public IReadOnlyList? 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`). public sealed class TileCoord { public int TileZoom { get; set; } public int TileX { get; set; } public int TileY { 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). public sealed class TileInventoryResponse { public IReadOnlyList Results { get; set; } = Array.Empty(); } // AZ-505: One entry per request input. `Present` indicates whether a row // exists in the `tiles` table for the resolved `LocationHash`. When // `Present == false` only `LocationHash` (and the echoed coord triple, if the // request used coords) is populated — the rest are null. // // `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). public sealed class TileInventoryEntry { public int TileZoom { get; set; } public int TileX { get; set; } public int TileY { get; set; } public Guid LocationHash { get; set; } public bool Present { get; set; } public Guid? Id { get; set; } public DateTime? CapturedAt { get; set; } public string? Source { get; set; } public Guid? FlightId { get; set; } public double? ResolutionMPerPx { get; set; } } // AZ-505: per-task constants exposed for the request validator + tests. // Living under DTO so both the API handler and test assertions can reference // the same value without re-deriving it. public static class TileInventoryLimits { // 2x headroom over the AC-4 perf gate of 2500 tiles. Anything larger is // rejected with HTTP 400 by the API handler. public const int MaxEntriesPerRequest = 5000; }