# 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) |
