mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 17:41:14 +00:00
b0fffa6d42
Phase A baseline outputs from /autodev (Steps 1-5): - Problem & solution docs (_docs/00_problem, _docs/01_solution) - Codebase documentation (_docs/02_document) incl. architecture, module-layout, glossary, system-flows, baseline compliance scan - Test specs (blackbox, performance, resilience, security, resource, traceability matrix) - Test task decomposition (_docs/02_tasks/todo): AZ-285..AZ-290 - Testability refactor (_docs/04_refactoring/01-testability-refactoring): - TC-01 Move DownloadedTileInfoV2 + new ExistingTileInfo to Common.DTO - TC-02 Replace dead ISatelliteDownloader API with real signatures - TC-03 GoogleMapsDownloaderV2 implements ISatelliteDownloader - TC-04 TileService depends on ISatelliteDownloader (mockable) - TC-05 DI + endpoints use ISatelliteDownloader - Test runner scripts (scripts/run-tests.sh, run-performance-tests.sh) - Autodev state pointer (_docs/_autodev_state.md) Prepares the codebase for AZ-285..AZ-290 unit/integration test work. Co-authored-by: Cursor <cursoragent@cursor.com>
218 lines
8.0 KiB
Markdown
218 lines
8.0 KiB
Markdown
# Satellite Provider — Data Model
|
|
|
|
## Entity-Relationship Diagram
|
|
|
|
```mermaid
|
|
erDiagram
|
|
TILES {
|
|
uuid id PK
|
|
int tile_zoom
|
|
float latitude
|
|
float longitude
|
|
float tile_size_meters
|
|
int tile_size_pixels
|
|
varchar image_type
|
|
varchar maps_version
|
|
int version
|
|
varchar file_path
|
|
int tile_x
|
|
int tile_y
|
|
timestamp created_at
|
|
timestamp updated_at
|
|
}
|
|
|
|
REGIONS {
|
|
uuid id PK
|
|
float latitude
|
|
float longitude
|
|
float size_meters
|
|
int zoom_level
|
|
varchar status
|
|
bool stitch_tiles
|
|
varchar csv_file_path
|
|
varchar summary_file_path
|
|
int tiles_downloaded
|
|
int tiles_reused
|
|
timestamp created_at
|
|
timestamp updated_at
|
|
}
|
|
|
|
ROUTES {
|
|
uuid id PK
|
|
varchar name
|
|
text description
|
|
float region_size_meters
|
|
int zoom_level
|
|
float total_distance_meters
|
|
int total_points
|
|
bool request_maps
|
|
bool maps_ready
|
|
bool create_tiles_zip
|
|
varchar tiles_zip_path
|
|
varchar csv_file_path
|
|
varchar summary_file_path
|
|
varchar stitched_image_path
|
|
timestamp created_at
|
|
timestamp updated_at
|
|
}
|
|
|
|
ROUTE_POINTS {
|
|
uuid id PK
|
|
uuid route_id FK
|
|
int sequence_number
|
|
float latitude
|
|
float longitude
|
|
varchar point_type
|
|
int segment_index
|
|
float distance_from_previous
|
|
timestamp created_at
|
|
}
|
|
|
|
ROUTE_REGIONS {
|
|
uuid route_id FK
|
|
uuid region_id FK
|
|
bool is_geofence
|
|
int geofence_polygon_index
|
|
timestamp created_at
|
|
}
|
|
|
|
ROUTES ||--o{ ROUTE_POINTS : "has many"
|
|
ROUTES ||--o{ ROUTE_REGIONS : "has many"
|
|
REGIONS ||--o{ ROUTE_REGIONS : "linked via"
|
|
```
|
|
|
|
## Tables
|
|
|
|
### tiles
|
|
|
|
Stores metadata for downloaded satellite imagery tiles. Each tile is a single image at a specific geographic coordinate and zoom level.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|-------------|-------------|
|
|
| id | UUID | PK | Unique tile identifier |
|
|
| tile_zoom | INT | NOT NULL | Google Maps zoom level (1-20) |
|
|
| latitude | DOUBLE PRECISION | NOT NULL | Center latitude |
|
|
| longitude | DOUBLE PRECISION | NOT NULL | Center longitude |
|
|
| tile_size_meters | DOUBLE PRECISION | NOT NULL | Ground coverage in meters |
|
|
| tile_size_pixels | INT | NOT NULL | Image dimension in pixels |
|
|
| image_type | VARCHAR(10) | NOT NULL | Image format (e.g., "jpg") |
|
|
| maps_version | VARCHAR(50) | | Google Maps version string |
|
|
| version | INT | NOT NULL, DEFAULT 2025 | Year-based versioning for cache invalidation |
|
|
| file_path | VARCHAR(500) | NOT NULL | Relative path to stored image |
|
|
| tile_x | INT | NOT NULL | Tile X coordinate (Slippy Map) |
|
|
| tile_y | INT | NOT NULL | Tile Y coordinate (Slippy Map) |
|
|
| created_at | TIMESTAMP | NOT NULL, DEFAULT NOW | |
|
|
| updated_at | TIMESTAMP | NOT NULL, DEFAULT NOW | |
|
|
|
|
**Indexes**:
|
|
- `idx_tiles_unique_location` UNIQUE (latitude, longitude, tile_zoom, tile_size_meters, version)
|
|
- `idx_tiles_coordinates` (tile_zoom, tile_x, tile_y, version)
|
|
- `idx_tiles_zoom` (tile_zoom)
|
|
|
|
### regions
|
|
|
|
Tracks region download requests and their processing status.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|-------------|-------------|
|
|
| id | UUID | PK | Region request identifier |
|
|
| latitude | DOUBLE PRECISION | NOT NULL | Center latitude |
|
|
| longitude | DOUBLE PRECISION | NOT NULL | Center longitude |
|
|
| size_meters | DOUBLE PRECISION | NOT NULL | Square region side length |
|
|
| zoom_level | INT | NOT NULL | Zoom level for tiles |
|
|
| status | VARCHAR(20) | NOT NULL | pending / processing / completed / failed |
|
|
| stitch_tiles | BOOLEAN | NOT NULL, DEFAULT false | Whether to produce stitched image |
|
|
| csv_file_path | VARCHAR(500) | | Path to tile manifest CSV |
|
|
| summary_file_path | VARCHAR(500) | | Path to summary text |
|
|
| tiles_downloaded | INT | DEFAULT 0 | Count of newly downloaded tiles |
|
|
| tiles_reused | INT | DEFAULT 0 | Count of cache-hit tiles |
|
|
| created_at | TIMESTAMP | NOT NULL, DEFAULT NOW | |
|
|
| updated_at | TIMESTAMP | NOT NULL, DEFAULT NOW | |
|
|
|
|
**Indexes**:
|
|
- `idx_regions_status` (status)
|
|
|
|
### routes
|
|
|
|
Defines route paths with configuration for map tile generation.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|-------------|-------------|
|
|
| id | UUID | PK | Route identifier |
|
|
| name | VARCHAR(200) | NOT NULL | Human-readable name |
|
|
| description | TEXT | | Optional description |
|
|
| region_size_meters | DOUBLE PRECISION | NOT NULL | Size of region per point |
|
|
| zoom_level | INT | NOT NULL | Zoom level for regions |
|
|
| total_distance_meters | DOUBLE PRECISION | NOT NULL | Total route length |
|
|
| total_points | INT | NOT NULL | Total point count (original + interpolated) |
|
|
| request_maps | BOOLEAN | NOT NULL, DEFAULT false | Whether to generate map tiles |
|
|
| maps_ready | BOOLEAN | NOT NULL, DEFAULT false | Whether map generation is complete |
|
|
| create_tiles_zip | BOOLEAN | NOT NULL, DEFAULT false | Whether to produce ZIP archive |
|
|
| tiles_zip_path | VARCHAR(500) | | Path to output ZIP |
|
|
| csv_file_path | VARCHAR(500) | | Route-level CSV |
|
|
| summary_file_path | VARCHAR(500) | | Route-level summary |
|
|
| stitched_image_path | VARCHAR(500) | | Route-level stitched image |
|
|
| created_at | TIMESTAMP | NOT NULL, DEFAULT NOW | |
|
|
| updated_at | TIMESTAMP | NOT NULL, DEFAULT NOW | |
|
|
|
|
### route_points
|
|
|
|
Stores all points along a route (both original waypoints and interpolated intermediate points).
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|-------------|-------------|
|
|
| id | UUID | PK | Point identifier |
|
|
| route_id | UUID | FK → routes.id, CASCADE | Parent route |
|
|
| sequence_number | INT | NOT NULL, UNIQUE(route_id, seq) | Order along route |
|
|
| latitude | DOUBLE PRECISION | NOT NULL | Point latitude |
|
|
| longitude | DOUBLE PRECISION | NOT NULL | Point longitude |
|
|
| point_type | VARCHAR(20) | NOT NULL | "original" or "intermediate" |
|
|
| segment_index | INT | NOT NULL | Which segment (between original points) |
|
|
| distance_from_previous | DOUBLE PRECISION | | Meters from previous point |
|
|
| created_at | TIMESTAMP | NOT NULL, DEFAULT NOW | |
|
|
|
|
**Indexes**:
|
|
- `idx_route_points_route` (route_id, sequence_number)
|
|
- `idx_route_points_coords` (latitude, longitude)
|
|
|
|
### route_regions
|
|
|
|
Junction table linking routes to their generated region requests, with geofence metadata.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|-------------|-------------|
|
|
| route_id | UUID | FK → routes.id, CASCADE, PK | |
|
|
| region_id | UUID | FK → regions.id, CASCADE, PK | |
|
|
| is_geofence | BOOLEAN | NOT NULL, DEFAULT false | Whether point is inside a geofence |
|
|
| geofence_polygon_index | INTEGER | | Which polygon (0-based) the point is in |
|
|
| created_at | TIMESTAMP | NOT NULL, DEFAULT NOW | |
|
|
|
|
**Indexes**:
|
|
- `idx_route_regions_route` (route_id)
|
|
- `idx_route_regions_region` (region_id)
|
|
|
|
## Migration Strategy
|
|
|
|
- **Tool**: DbUp (embedded SQL scripts)
|
|
- **Execution**: Automatic on application startup (`DatabaseMigrator.Migrate()`)
|
|
- **Naming**: `NNN_DescriptiveName.sql` (sequential numbering)
|
|
- **Storage**: Embedded resources in `SatelliteProvider.DataAccess` assembly
|
|
- **Tracking**: DbUp's internal `schemaversions` table records which scripts have run
|
|
- **Rollback**: Not supported — forward-only migrations
|
|
|
|
## Migration History
|
|
|
|
| # | Migration | Purpose |
|
|
|---|-----------|---------|
|
|
| 001 | CreateTilesTable | Base tiles table |
|
|
| 002 | CreateRegionsTable | Region request tracking |
|
|
| 003 | CreateIndexes | Performance indexes |
|
|
| 004 | AddVersionColumn | Year-based tile versioning + dedup |
|
|
| 005 | CreateRoutesTables | Routes, route_points, route_regions |
|
|
| 006 | AddStitchTilesToRegions | Stitch flag on regions |
|
|
| 007 | AddRouteMapFields | request_maps, maps_ready, file paths on routes |
|
|
| 008 | AddGeofenceFlagToRouteRegions | is_geofence flag |
|
|
| 009 | AddGeofencePolygonIndex | Polygon index tracking |
|
|
| 010 | AddTilesZipToRoutes | ZIP generation fields |
|
|
| 011 | AddTileCoordinates | Slippy map X/Y + rename zoom_level → tile_zoom |
|