Files
satellite-provider/_docs/02_document/system-flows.md
T
Oleksandr Bezdieniezhnykh b0fffa6d42 [AZ-284] Autodev baseline + testability refactor
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>
2026-05-10 04:44:08 +03:00

278 lines
9.0 KiB
Markdown

# Satellite Provider — System Flows
## Flow Inventory
| # | Flow Name | Trigger | Primary Components | Criticality |
|---|-----------|---------|-------------------|-------------|
| F1 | Single Tile Download | HTTP GET /api/satellite/tiles/latlon | WebApi, TileDownloader, DataAccess | High |
| F2 | Region Request | HTTP POST /api/satellite/request | WebApi, RegionProcessing, TileDownloader, DataAccess | High |
| F3 | Region Processing | Queue dequeue (background) | RegionProcessing, TileDownloader, DataAccess | High |
| F4 | Route Creation | HTTP POST /api/satellite/route | WebApi, RouteManagement, DataAccess | High |
| F5 | Route Map Processing | Queue dequeue (background) | RouteManagement, RegionProcessing, TileDownloader, DataAccess | Medium |
| F6 | Status Query | HTTP GET /api/satellite/region/{id} or /route/{id} | WebApi, DataAccess | Low |
## Flow Dependencies
| Flow | Depends On | Shares Data With |
|------|-----------|-----------------|
| F1 | — | F3 (tile cache) |
| F2 | — | F3 (triggers it) |
| F3 | F2 enqueues work | F1 (shares tile cache), F5 |
| F4 | — | F5 (triggers it) |
| F5 | F4 must create route first | F3 (submits region requests) |
| F6 | F2/F4 must exist | — |
---
## Flow F1: Single Tile Download
### Description
Client requests a single satellite tile by geographic coordinates and zoom level. The service checks the cache (DB), downloads from Google Maps if not cached, stores it, and returns metadata.
### Preconditions
- Valid latitude, longitude, and zoom level provided
- Google Maps session token configured
### Sequence Diagram
```mermaid
sequenceDiagram
participant Client
participant WebApi
participant TileService
participant TileRepo
participant GoogleMaps
participant FileSystem
Client->>WebApi: GET /api/satellite/tiles/latlon?lat&lon&zoom
WebApi->>TileService: DownloadTileAsync(lat, lon, zoom)
TileService->>TileRepo: FindByCoordinates(lat, lon, zoom)
alt Tile exists in cache
TileRepo-->>TileService: TileEntity
TileService-->>WebApi: TileMetadata (cached)
else Not cached
TileService->>GoogleMaps: Download tile image
GoogleMaps-->>TileService: JPEG bytes
TileService->>FileSystem: Save to ./tiles/{zoom}/{x}/{y}.jpg
TileService->>TileRepo: Insert(TileEntity)
TileService-->>WebApi: TileMetadata (new)
end
WebApi-->>Client: JSON response
```
### Error Scenarios
| Error | Where | Detection | Recovery |
|-------|-------|-----------|----------|
| Google Maps timeout | Download step | HttpClient timeout | Return error to caller |
| Duplicate download race | Concurrent requests | ConcurrentDictionary check | Await existing download |
| Disk full | File save | IOException | Exception propagated, region fails |
---
## Flow F2: Region Request
### Description
Client submits a region definition (center point, size, zoom). The request is persisted and queued for asynchronous processing.
### Preconditions
- Valid region parameters (lat, lon, size_meters, zoom_level)
### Sequence Diagram
```mermaid
sequenceDiagram
participant Client
participant WebApi
participant RegionService
participant RegionRepo
participant Queue
Client->>WebApi: POST /api/satellite/request {lat, lon, size, zoom}
WebApi->>RegionService: CreateRegionRequest(dto)
RegionService->>RegionRepo: Insert(RegionEntity status=pending)
RegionRepo-->>RegionService: region_id
RegionService->>Queue: Enqueue(region_id)
RegionService-->>WebApi: region_id
WebApi-->>Client: 200 OK {region_id}
```
### Error Scenarios
| Error | Where | Detection | Recovery |
|-------|-------|-----------|----------|
| Queue full | Enqueue step | Channel at capacity | Return 503 / reject request |
| DB insert failure | Persist step | Exception | Return 500 |
---
## Flow F3: Region Processing (Background)
### Description
Background service dequeues region IDs, calculates tile grid, downloads all tiles (with concurrency control), optionally stitches them, and produces output files (CSV, summary, stitched image).
### Preconditions
- Region exists in DB with status "pending"
- Google Maps session token configured
### Sequence Diagram
```mermaid
sequenceDiagram
participant Queue
participant RegionProcessor
participant RegionService
participant TileService
participant GoogleMaps
participant RegionRepo
participant FileSystem
Queue->>RegionProcessor: Dequeue region_id
RegionProcessor->>RegionRepo: GetById(region_id)
RegionProcessor->>RegionRepo: UpdateStatus(processing)
loop For each tile in grid
RegionProcessor->>TileService: DownloadTileAsync(lat, lon, zoom)
TileService->>GoogleMaps: Download (if not cached)
end
RegionProcessor->>FileSystem: Write CSV (tile manifest)
RegionProcessor->>FileSystem: Write summary file
opt stitch_tiles = true
RegionProcessor->>FileSystem: Stitch tiles into composite image
end
RegionProcessor->>RegionRepo: UpdateStatus(completed, file paths)
```
### Data Flow
| Step | From | To | Data | Format |
|------|------|----|------|--------|
| 1 | Queue | RegionProcessor | region_id | int |
| 2 | RegionProcessor | TileService | lat, lon, zoom per tile | method call |
| 3 | TileService | FileSystem | JPEG image | file |
| 4 | RegionProcessor | FileSystem | tile manifest | CSV |
| 5 | RegionProcessor | FileSystem | region summary | TXT |
| 6 | RegionProcessor | FileSystem | composite image | JPEG |
### Error Scenarios
| Error | Where | Detection | Recovery |
|-------|-------|-----------|----------|
| Tile download failure | Per-tile loop | Exception from TileService | Log, continue with remaining tiles |
| All tiles fail | After loop | Zero tiles downloaded | Mark region as "failed" |
| Stitch failure | Image processing | ImageSharp exception | Mark region failed, tiles still available |
---
## Flow F4: Route Creation
### Description
Client submits a route (ordered waypoints + optional geofence polygons). The service interpolates intermediate points every ~200m and persists the full point set.
### Preconditions
- At least 2 waypoints provided
- Valid geofence polygons (if provided)
### Sequence Diagram
```mermaid
sequenceDiagram
participant Client
participant WebApi
participant RouteService
participant RouteRepo
participant GeoUtils
Client->>WebApi: POST /api/satellite/route {points, geofences, options}
WebApi->>RouteService: CreateRoute(request)
RouteService->>GeoUtils: Interpolate points between waypoints
GeoUtils-->>RouteService: All points (original + intermediate)
RouteService->>RouteRepo: InsertRoute(RouteEntity)
RouteService->>RouteRepo: InsertPoints(RoutePointEntities)
RouteService-->>WebApi: RouteResponse
WebApi-->>Client: 200 OK {route_id, total_points, total_distance}
```
### Error Scenarios
| Error | Where | Detection | Recovery |
|-------|-------|-----------|----------|
| Invalid points (< 2) | Validation | Count check | Return 400 |
| DB insert failure | Persist step | Exception | Return 500 |
---
## Flow F5: Route Map Processing (Background)
### Description
When a route requests map tiles (`request_maps = true`), a background service creates region requests for each route point, optionally filtered by geofence, then waits for all regions to complete and produces a ZIP archive.
### Preconditions
- Route exists with `request_maps = true`
- Route points already interpolated and persisted
### Sequence Diagram
```mermaid
sequenceDiagram
participant RouteProcessor
participant RouteRepo
participant RegionService
participant Queue
participant RegionProcessor
participant FileSystem
RouteProcessor->>RouteRepo: GetRouteWithPoints(route_id)
loop For each route point
RouteProcessor->>RouteProcessor: Check geofence (point-in-polygon)
opt Point inside geofence (or no geofence)
RouteProcessor->>RegionService: CreateRegionRequest(point)
RegionService->>Queue: Enqueue(region_id)
end
end
RouteProcessor->>RouteProcessor: Wait for all regions to complete
opt create_tiles_zip = true
RouteProcessor->>FileSystem: Create ZIP of all tiles (max 50MB)
RouteProcessor->>RouteRepo: Update tiles_zip_path
end
```
### Error Scenarios
| Error | Where | Detection | Recovery |
|-------|-------|-----------|----------|
| Region processing timeout | Wait loop | Polling timeout | Mark route partially complete |
| ZIP exceeds 50MB | ZIP creation | Size check during write | Truncate or skip |
| Geofence calculation error | Point-in-polygon | Exception | Include point (fail-open) |
---
## Flow F6: Status Query
### Description
Client polls for the status of a region or route by ID. Returns current processing state and output file paths when complete.
### Sequence Diagram
```mermaid
sequenceDiagram
participant Client
participant WebApi
participant DataAccess
Client->>WebApi: GET /api/satellite/region/{id}
WebApi->>DataAccess: GetRegionById(id)
DataAccess-->>WebApi: RegionEntity (status, file paths)
WebApi-->>Client: JSON {status, files}
```