mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 14:11:16 +00:00
61612044fb
Wrap up cycle 5 verification + documentation: - Steps 10/11 wrap-up reports (implementation_completeness + implementation_report) for the AZ-503-foundation + AZ-504 batch. - Step 12 test-spec sync: AZ-503-foundation/AZ-504 ACs appended; AZ-505 deferred ACs recorded. - Step 13 update-docs: architecture, data-model, glossary, module- layout, uav-tile-upload contract (v1.1.0), DataAccess + Services + Tests module docs synced; new common_uuidv5.md module doc. - Step 14 security audit: PASS_WITH_WARNINGS; 0 new Critical/High; 2 new Low informational (F1 flightId provenance, F2 pgcrypto deploy gap). - Step 15 performance test: PASS_WITH_INFRA_WARNINGS; PT-08 passed twice (AZ-504 fix verified); PT-01/02 failed due to recurring local Docker/colima DNS cold-start (not an app regression). Cycle-3 perf-harness leftover stays OPEN with replay #5 documented. - Autodev state moved to Step 16 (Deploy). Co-authored-by: Cursor <cursoragent@cursor.com>
74 lines
4.4 KiB
Markdown
74 lines
4.4 KiB
Markdown
# Module: DataAccess/Models
|
|
|
|
## Purpose
|
|
Database entity classes that map directly to PostgreSQL tables via Dapper. Property names use PascalCase; column mapping is done with SQL aliases in repository queries.
|
|
|
|
## Public Interface
|
|
|
|
### TileEntity
|
|
Maps to `tiles` table.
|
|
- `Id` (Guid) — AZ-503: deterministic UUIDv5 of `{tile_zoom}/{tile_x}/{tile_y}/{source}/{flight_id or '00000000-0000-0000-0000-000000000000'}` under namespace `Uuidv5.TileNamespace`. Stable across re-ingests; preserved on UPSERT conflict.
|
|
- `TileZoom` (int), `TileX` (int), `TileY` (int)
|
|
- `Latitude`, `Longitude` (double), `TileSizeMeters` (double), `TileSizePixels` (int)
|
|
- `ImageType` (string), `MapsVersion` (string?), `Version` (int) — `MapsVersion`/`Version` are vestigial post-AZ-484 (kept nullable for backward compatibility; no longer part of the unique key)
|
|
- `Source` (string) — AZ-484 producer wire value, defaults to `TileSourceConverter.GoogleMapsWireValue` (`"google_maps"`). Stored as plain string (not the `TileSource` enum) due to Dapper issue #259 — see `_docs/LESSONS.md` L-001. Convert via `SatelliteProvider.Common.Enums.TileSourceConverter.{ToWireValue,FromWireValue}`.
|
|
- `CapturedAt` (DateTime, UTC) — AZ-484 imagery acquisition timestamp; drives the most-recent-across-sources selection.
|
|
- `FilePath` (string), `CreatedAt`, `UpdatedAt` (DateTime)
|
|
- `FlightId` (Guid?) — AZ-503: optional flight identifier. `null` for Google Maps tiles; populated from `UavTileMetadata.FlightId` on UAV uploads. Part of the AZ-503 UPSERT conflict key via `COALESCE(flight_id, '00000000-0000-0000-0000-000000000000'::uuid)`, so two flights uploading the same `(z, x, y)` cell produce two separate rows.
|
|
- `LocationHash` (Guid) — AZ-503 `NOT NULL`: deterministic UUIDv5 of `{tile_zoom}/{tile_x}/{tile_y}` under `Uuidv5.TileNamespace`. Identical across flights and sources for the same cell. Backfilled in migration 014 via a `pg_temp.uuidv5` PL/pgSQL function; subsequent inserts compute it in the application layer (`TileService` + `UavTileUploadHandler`). Reserved for AZ-505's Leaflet covering index (`POST /tiles/inventory`) — not yet on a unique constraint.
|
|
- `ContentSha256` (byte[]?) — AZ-503: SHA-256 digest of the JPEG body. Application code enforces `NOT NULL` for new writes via `TileService.BuildTileEntity` (Google Maps) and `UavTileUploadHandler.PersistAsync` (UAV). The DB column is `bytea NULL` because legacy pre-migration rows could not be backfilled reliably from disk (file paths are volatile). See `batch_02_cycle5_report.md` "Low maintainability finding" for the rationale.
|
|
- `LegacyId` (Guid?) — AZ-503: pre-migration `id` value, populated by migration 014 from every existing row's `id`. Preserves random-`Guid` provenance for one cycle (per AZ-503 Risk 1 mitigation) so external references to the old id can still be diagnosed before deletion.
|
|
|
|
### RegionEntity
|
|
Maps to `regions` table.
|
|
- `Id` (Guid), `Latitude`, `Longitude` (double), `SizeMeters` (double)
|
|
- `ZoomLevel` (int), `Status` (string: "queued"/"processing"/"completed"/"failed")
|
|
- `CsvFilePath`, `SummaryFilePath` (string?)
|
|
- `TilesDownloaded`, `TilesReused` (int), `StitchTiles` (bool)
|
|
- `CreatedAt`, `UpdatedAt` (DateTime)
|
|
|
|
### RouteEntity
|
|
Maps to `routes` table.
|
|
- `Id` (Guid), `Name` (string), `Description` (string?)
|
|
- `RegionSizeMeters` (double), `ZoomLevel` (int)
|
|
- `TotalDistanceMeters` (double), `TotalPoints` (int)
|
|
- `RequestMaps`, `MapsReady`, `CreateTilesZip` (bool)
|
|
- `CsvFilePath`, `SummaryFilePath`, `StitchedImagePath`, `TilesZipPath` (string?)
|
|
- `CreatedAt`, `UpdatedAt` (DateTime)
|
|
|
|
### RoutePointEntity
|
|
Maps to `route_points` table.
|
|
- `Id` (Guid), `RouteId` (Guid), `SequenceNumber` (int)
|
|
- `Latitude`, `Longitude` (double), `PointType` (string)
|
|
- `SegmentIndex` (int), `DistanceFromPrevious` (double?)
|
|
- `CreatedAt` (DateTime)
|
|
|
|
## Internal Logic
|
|
Plain POCOs with no logic.
|
|
|
|
## Dependencies
|
|
None.
|
|
|
|
## Consumers
|
|
- All repository implementations (TileRepository, RegionRepository, RouteRepository)
|
|
- `TileService` — creates `TileEntity` instances for persistence
|
|
- `RegionService` — creates/updates `RegionEntity`
|
|
- `RouteService` — creates `RouteEntity` and `RoutePointEntity`
|
|
- `RouteProcessingService` — reads entities from repositories
|
|
- `GoogleMapsDownloaderV2.GetTilesWithMetadataAsync` — accepts `IEnumerable<TileEntity>` to check existing tiles
|
|
|
|
## Data Models
|
|
These ARE the data model.
|
|
|
|
## Configuration
|
|
None.
|
|
|
|
## External Integrations
|
|
None.
|
|
|
|
## Security
|
|
None.
|
|
|
|
## Tests
|
|
No dedicated tests.
|