using Microsoft.AspNetCore.Mvc; namespace SatelliteProvider.Api.DTOs; // AZ-811: query-string record for GET /api/satellite/tiles/latlon. // Bound via `[AsParameters]` so each property maps to one query parameter. // `[FromQuery(Name = "...")]` pins the wire name explicitly — case-sensitive // match against `?lat=&lon=&zoom=`, matching the OSM convention shared with // the rest of the satellite-provider API (`{z, x, y}` for inventory, // `{lat, lon}` for region and route DTOs). // // **Why nullable types**: minimal-API parameter binding throws // BadHttpRequestException for missing-required non-nullable query params // BEFORE endpoint filters run. That short-circuit produces a plain // ProblemDetails via GlobalExceptionHandler — no `errors{}` envelope, no // per-field key. Per AZ-811 ACs 1 & 4 every missing/unknown param must // surface as `errors.` in ValidationProblemDetails. Nullable // types let binding always succeed, so: // 1. RejectUnknownQueryParamsEndpointFilter handles unknown keys // (e.g. legacy `?Latitude=`, hostile `?debug=1`). // 2. GetTileByLatLonQueryValidator handles `null` (missing) plus range. // Validator guarantees non-null by the time the handler dereferences. public sealed record GetTileByLatLonQuery( [property: FromQuery(Name = "lat")] double? Lat, [property: FromQuery(Name = "lon")] double? Lon, [property: FromQuery(Name = "zoom")] int? Zoom);