mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 15:11:14 +00:00
1802d32107
Replaces the 501 stub at POST /api/satellite/upload with a multipart
batch endpoint that ingests UAV-captured tiles, runs each item through
a 5-rule quality gate, and persists accepted tiles via the AZ-484
multi-source storage path with source='uav'.
Quality gate (in fixed order, first failure wins): JPEG format
(content-type + magic), size band 5 KiB-5 MiB, exact 256x256
dimensions, captured-at age (no future >30 s skew, no older than
7 days), luminance variance on 32x32 downsample. Closed reject-reason
enumeration in v1.0.0 contract.
Authorization: custom PermissionsRequirement / PermissionsAuthorization
Handler that reads the JWT `permissions` claim (tolerates both
repeated-string and JSON-array shapes). Endpoint protected by
RequiresGpsPermission policy; 401 without token, 403 without GPS perm.
Persistence: file-first to ./tiles/uav/{z}/{x}/{y}.jpg, then
ITileRepository.InsertAsync UPSERT (per-source UPSERT contract from
AZ-484). Per-item failures reported in response without aborting the
batch. Kestrel MaxRequestBodySize and FormOptions limits set to
MaxBatchSize x MaxBytes (default 100 x 5 MiB = 500 MiB).
New frozen contract: _docs/02_document/contracts/api/uav-tile-upload.md
v1.0.0. PT-08 NFR added to performance-tests.md as Deferred (harness
work tracked in PT-07 leftover, per AZ-488 § Risk 4).
Tests: 11 quality-gate unit tests, 5 handler unit tests, 3 file-path
unit tests, 12 permission-handler unit tests, 7 integration tests
(AC-1..AC-6, AC-8). All 253 unit tests + smoke integration suite
green.
Co-authored-by: Cursor <cursoragent@cursor.com>
6.0 KiB
6.0 KiB
Glossary
Domain Terms
| Term | Definition | Source |
|---|---|---|
| Tile | A single satellite imagery square (typically 256×256 px) at a specific zoom level and coordinate | modules/services_tile_service.md |
| Region | A square geographic area defined by center point and size in meters; the unit of work for batch tile downloads | modules/services_region_service.md |
| Route | An ordered sequence of geographic waypoints with interpolated intermediate points | modules/services_route_service.md |
| Route Point | A single lat/lon coordinate on a route; either "original" (user-provided waypoint) or "intermediate" (system-generated) | modules/dataaccess_models.md |
| Geofence | A rectangular geographic boundary (NW + SE corners) used to filter which route points receive map tile coverage | components/05_route_management/description.md |
| Zoom Level | Google Maps tile resolution level (1–20); higher = more detail, smaller ground coverage per tile | modules/common_configs.md |
| Stitch | Compositing multiple tiles into a single larger image with optional markers/borders | modules/services_region_service.md |
| Layer 1 | Historic name for satellite imagery from external providers (provider-agnostic; first implementation: Google Maps). Generalised in AZ-484 to one of N values of Tile Source; the term is retained for continuity with earlier docs and tickets. |
user clarification, AZ-484 |
| Layer 2 | Historic name for UAV-captured nadir camera imagery (orthogonal tiles uploaded post-flight). Generalised in AZ-484 to the uav Tile Source value; the term is retained for continuity with earlier docs and tickets. |
user clarification, AZ-484 |
| Tile Source | The producer of a tile row, persisted in tiles.source as a contract-defined string (google_maps, uav, …). Each cell may have at most one row per source; reads return the most-recent across sources. Adding a new source requires a new TileSource enum member and a tile-storage contract version bump. |
_docs/02_document/contracts/data-access/tile-storage.md (v1.0.0) |
| Captured At | Producer-defined UTC timestamp ("the moment this tile imagery represents") persisted in tiles.captured_at. For Google Maps it is DateTime.UtcNow at download time (provider does not expose original imagery date); for UAV it is the capture timestamp supplied by the upload client. Drives the most-recent-across-sources read selection rule. |
_docs/02_document/contracts/data-access/tile-storage.md (v1.0.0) |
| UAV Tile Upload | POST /api/satellite/upload batch endpoint (AZ-488) that ingests UAV-captured tiles. Multipart envelope with a JSON metadata field and an aligned files collection; per-item results returned in a single HTTP 200 response. |
_docs/02_document/contracts/api/uav-tile-upload.md (v1.0.0) |
| Quality Gate | The 5-rule validator (UavTileQualityGate) applied to every UAV tile before persistence: Format, Size band, Dimensions, Captured-at age, Blank/uniform. The first failing rule produces a reject reason from the closed UavTileRejectReasons enumeration. |
_docs/02_document/contracts/api/uav-tile-upload.md (v1.0.0) |
| INVALID_FORMAT | UAV reject reason — content-type is not image/jpeg OR the file's first three bytes are not the JPEG magic FF D8 FF OR the bytes fail to decode as JPEG. |
_docs/02_document/contracts/api/uav-tile-upload.md (v1.0.0) |
| SIZE_OUT_OF_BAND | UAV reject reason — image byte length outside [UavQualityConfig.MinBytes, MaxBytes] (defaults 5 KiB … 5 MiB). |
_docs/02_document/contracts/api/uav-tile-upload.md (v1.0.0) |
| WRONG_DIMENSIONS | UAV reject reason — image width or height does not equal MapConfig.TileSizePixels. |
_docs/02_document/contracts/api/uav-tile-upload.md (v1.0.0) |
| CAPTURED_AT_FUTURE | UAV reject reason — capturedAt is more than CapturedAtFutureSkewSeconds ahead of the server clock. |
_docs/02_document/contracts/api/uav-tile-upload.md (v1.0.0) |
| CAPTURED_AT_TOO_OLD | UAV reject reason — capturedAt is older than UavQualityConfig.MaxAgeDays. |
_docs/02_document/contracts/api/uav-tile-upload.md (v1.0.0) |
| IMAGE_TOO_UNIFORM | UAV reject reason — pixel-luminance variance on the downsampled image is below MinLuminanceVariance. |
_docs/02_document/contracts/api/uav-tile-upload.md (v1.0.0) |
| Nadir Camera | Downward-facing camera on a UAV capturing ground imagery during flight | user clarification |
| GPS-Denied Service | The consuming system: a UAV navigation service operating without GPS, using satellite/UAV imagery for positioning | user clarification |
| Slippy Map Coordinates | Tile X/Y indices in the Web Mercator projection grid (standard for web map tile servers) | data_model.md |
| Version | Integer year (e.g., 2025) used to invalidate tile cache when Google Maps imagery is updated | data_model.md |
Technical Terms
| Term | Definition | Source |
|---|---|---|
| Region Request Queue | In-process bounded Channel<Guid> that decouples HTTP request submission from background processing |
modules/services_region_request_queue.md |
| Session Token | Provider-specific authentication token (e.g., Google Maps) embedded in tile download URLs; each provider may use different auth mechanisms | modules/services_google_maps_downloader.md |
| ISatelliteDownloader | Interface abstracting satellite imagery providers; first implementation: Google Maps (GoogleMapsDownloaderV2) | modules/common_interfaces.md |
| DbUp | .NET library for forward-only SQL schema migrations via numbered embedded scripts | modules/dataaccess_database_migrator.md |
| Tile Deduplication | Mechanism using DB unique index + ConcurrentDictionary to prevent re-downloading identical tiles | modules/services_google_maps_downloader.md |
Abbreviations
| Abbrev | Meaning |
|---|---|
| MGRS | Military Grid Reference System (endpoint planned, currently stub) |
| UAV | Unmanned Aerial Vehicle |
| NFR | Non-Functional Requirement |
| DI | Dependency Injection |
| DTO | Data Transfer Object |
| CSV | Comma-Separated Values (tile manifest output format) |