# Satellite Provider — Solution ## Product Solution Description Satellite Provider is a backend service that acquires, stores, and composites satellite imagery for a GPS-denied UAV navigation system. It operates as a tile cache and map-generation engine, bridging Google Maps satellite imagery (Layer 1) with UAV-captured nadir camera tiles (Layer 2, planned). ```mermaid graph LR Client[GPS-Denied Service] -->|HTTP| API[WebApi] API --> RS[RouteService] API --> RgS[RegionService] API --> TS[TileService] RS --> RgS RgS --> TS TS --> GM[Google Maps] TS --> FS[File System] RS --> DB[(PostgreSQL)] RgS --> DB TS --> DB ``` ## Architecture The system implements a layered monolith with asynchronous background processing. ### Per-Component Solution | Component | Solution | Tools | Advantages | Limitations | Requirements Met | Security | Cost | Fit | |-----------|----------|-------|-----------|-------------|-----------------|----------|------|-----| | Common | Shared contracts + geo-math library | C# records, static utility class | Type-safe contracts, reusable Haversine/Mercator math | Static utility class limits testability of geo functions | Cross-component type sharing, coordinate calculations | N/A | Zero runtime cost | High | | DataAccess | Dapper + DbUp repositories | Dapper, Npgsql, DbUp, PostgreSQL 16 | Raw SQL performance, simple migration model | No change tracking, manual mapping | Tile metadata persistence, region/route state tracking | Parameterized queries (SQL injection safe) | Minimal overhead | High | | TileDownloader | Provider-agnostic concurrent downloader with dedup cache via `ISatelliteDownloader` (first implementation: Google Maps) | HttpClient, SemaphoreSlim, ConcurrentDictionary | Prevents duplicate downloads, controlled concurrency, provider-swappable | Single-instance only, no distributed dedup | Tile acquisition from satellite imagery providers, disk caching | Provider-specific auth (e.g., session token) | Per-tile provider API cost | High | | RegionProcessing | Queue-based async processor with tile stitching | System.Threading.Channels, ImageSharp | Decoupled request/processing, bounded memory | Queue lost on restart, no retry persistence | Batch tile download for regions, composite image output | N/A | CPU-bound stitching | High | | RouteManagement | Point interpolation + geofenced region generation | Haversine math, point-in-rectangle test | Automated route coverage, geofence filtering | Rectangular geofences only (not arbitrary polygons) | Route-to-region expansion, selective tile coverage | N/A | Linear in point count | Medium-High | ## Testing Strategy ### Integration Tests - **Framework**: Custom console application (`SatelliteProvider.IntegrationTests`) - **Execution**: Docker Compose with dependent services (API + PostgreSQL) - **Coverage areas**: - Single tile download (lat/lon + zoom → file stored) - Region request lifecycle (pending → processing → completed) - Route creation with point interpolation - Complex routes with geofences and stitching - Extended routes with map request processing ### Unit Tests - **Framework**: xUnit + Moq (`SatelliteProvider.Tests`) - **Current state**: Minimal (placeholder test exists) - **Gap**: No unit test coverage for business logic (services, geo calculations) ### Non-Functional Tests - No dedicated performance/load tests - Integration tests implicitly verify end-to-end latency - File size assertions (stitched image > 1KB) serve as basic output validation ## References | Artifact | Path | Purpose | |----------|------|---------| | Dockerfile | `SatelliteProvider.Api/Dockerfile` | Multi-stage .NET 8.0 container build | | Docker Compose | `docker-compose.yml` | Service orchestration (API + PostgreSQL) | | Docker Compose Tests | `docker-compose.tests.yml` | Integration test execution environment | | CI - Unit Tests | `.woodpecker/01-test.yml` | Automated test gate on push/PR | | CI - Build & Push | `.woodpecker/02-build-push.yml` | Container image build and registry push | | App Config | `SatelliteProvider.Api/appsettings.json` | Default configuration values | | Dev Config | `SatelliteProvider.Api/appsettings.Development.json` | Development overrides | | Migrations | `SatelliteProvider.DataAccess/Migrations/*.sql` | Database schema (11 sequential scripts) |