mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-22 08:21:15 +00:00
[AZ-315] Sync architecture docs after coupling refactor
Phase C of architecture coupling refactor (epic AZ-309). Closes the
last baseline finding (F5 — DataAccess incorrectly documented as
importing Common) and synchronizes the rest of _docs/02_document/
with the post-split project layout from AZ-312/313/314:
- module-layout.md: per-component sections for the three new csprojs
with explicit ProjectReferences and the no-cross-sibling-reference
invariant the split enforces.
- architecture.md: components and internal-communication tables
updated to show calls flow through Common interfaces.
- architecture_compliance_baseline.md: F1..F5 marked Resolved with
task IDs and commit refs; baseline summary now 0 findings.
- diagrams/components.md, components/03_tile_downloader/description.md,
modules/{common_interfaces,services_tile_service,
services_google_maps_downloader,tests_unit}.md updated for the
split, RateLimitException relocation, and new ITileService methods.
Documentation-only batch — no code, no tests, no build changes.
Epic AZ-309 complete (6 tasks across 3 batches).
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# Module: Common/Interfaces
|
||||
|
||||
## Purpose
|
||||
Service contracts defining the application's core operations. Implementations live in `SatelliteProvider.Services`.
|
||||
Service contracts defining the application's core operations. Implementations live in the per-component service projects (`SatelliteProvider.Services.TileDownloader`, `SatelliteProvider.Services.RegionProcessing`, `SatelliteProvider.Services.RouteManagement`). Cross-component runtime calls between Layer-3 components flow exclusively through these interfaces — there are no compile-time `ProjectReference` entries between the three sibling service projects.
|
||||
|
||||
## Public Interface
|
||||
|
||||
@@ -9,6 +9,8 @@ Service contracts defining the application's core operations. Implementations li
|
||||
- `DownloadAndStoreTilesAsync(double lat, double lon, double sizeMeters, int zoomLevel, CancellationToken) → Task<List<TileMetadata>>`: downloads missing tiles for a region and returns all tile metadata (existing + new)
|
||||
- `GetTileAsync(Guid id) → Task<TileMetadata?>`: retrieve a single tile by ID
|
||||
- `GetTilesByRegionAsync(double lat, double lon, double sizeMeters, int zoomLevel) → Task<IEnumerable<TileMetadata>>`: query tiles within a geographic region
|
||||
- `GetOrDownloadTileAsync(int z, int x, int y, CancellationToken) → Task<TileBytes>`: serve a tile by Z/X/Y, hitting cache, then repository, then downloader (added in AZ-310)
|
||||
- `DownloadAndStoreSingleTileAsync(double latitude, double longitude, int zoomLevel, CancellationToken) → Task<TileMetadata>`: download one tile by lat/lon and persist (added in AZ-311)
|
||||
|
||||
### IRegionService
|
||||
- `RequestRegionAsync(Guid id, double lat, double lon, double sizeMeters, int zoomLevel, bool stitchTiles) → Task<RegionStatus>`: creates a region record and enqueues for async processing
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
## Purpose
|
||||
Downloads satellite imagery tiles from Google Maps. Handles session token management, concurrent download throttling, retry logic with exponential backoff, and tile deduplication.
|
||||
|
||||
**csproj**: `SatelliteProvider.Services.TileDownloader/GoogleMapsDownloaderV2.cs`
|
||||
|
||||
## Public Interface
|
||||
|
||||
### GoogleMapsDownloaderV2
|
||||
@@ -14,7 +16,7 @@ Downloads satellite imagery tiles from Google Maps. Handles session token manage
|
||||
- `X`, `Y` (int), `ZoomLevel` (int), `CenterLatitude`, `CenterLongitude` (double), `FilePath` (string), `TileSizeMeters` (double)
|
||||
|
||||
### RateLimitException (exception)
|
||||
Custom exception thrown when Google Maps returns 429 Too Many Requests and retries are exhausted.
|
||||
Lives in `SatelliteProvider.Common.Exceptions` (relocated from this module in epic AZ-309 so RegionProcessing can catch it without acquiring a `ProjectReference` to TileDownloader). Thrown when Google Maps returns 429 Too Many Requests and retries are exhausted.
|
||||
|
||||
## Internal Logic
|
||||
- **Allowed zoom levels**: 15, 16, 17, 18, 19 — throws `ArgumentException` for others
|
||||
@@ -30,13 +32,13 @@ Custom exception thrown when Google Maps returns 429 Too Many Requests and retri
|
||||
## Dependencies
|
||||
- `SatelliteProvider.Common.Configs` — MapConfig, StorageConfig, ProcessingConfig
|
||||
- `SatelliteProvider.Common.DTO` — GeoPoint
|
||||
- `SatelliteProvider.Common.Exceptions` — RateLimitException
|
||||
- `SatelliteProvider.Common.Utils` — GeoUtils
|
||||
- `SatelliteProvider.DataAccess.Models` — TileEntity (for existingTiles parameter)
|
||||
- NuGet: `Newtonsoft.Json`, `Microsoft.Extensions.Http`, `Microsoft.Extensions.Options`
|
||||
|
||||
## Consumers
|
||||
- `TileService` — `GetTilesWithMetadataAsync`
|
||||
- `Program.cs` (ServeTile, GetTileByLatLon) — `DownloadSingleTileAsync`
|
||||
- `TileService` — `GetTilesWithMetadataAsync` and `DownloadSingleTileAsync` (the API endpoints reach this class only through `ITileService` post AZ-310 / AZ-311)
|
||||
|
||||
## Data Models
|
||||
Produces `DownloadedTileInfoV2` records; accepts `TileEntity` for cache checks.
|
||||
|
||||
@@ -1,29 +1,35 @@
|
||||
# Module: Services/TileService
|
||||
|
||||
## Purpose
|
||||
Orchestrates tile downloading and persistence. Bridges the downloader (Google Maps) with the tile repository (PostgreSQL), handling cache checks, entity creation, and metadata mapping.
|
||||
Orchestrates tile downloading and persistence. Bridges the downloader (Google Maps) with the tile repository (PostgreSQL), handling in-memory caching, entity creation, and metadata mapping. Single ownership point for all tile read/write business logic — both region-batch and single-tile API endpoints route through this service.
|
||||
|
||||
**csproj**: `SatelliteProvider.Services.TileDownloader/TileService.cs`
|
||||
|
||||
## Public Interface
|
||||
|
||||
### TileService (implements ITileService)
|
||||
- `DownloadAndStoreTilesAsync(double lat, double lon, double sizeMeters, int zoomLevel, CancellationToken) → Task<List<TileMetadata>>`:
|
||||
1. Queries existing tiles in the region from the repository (filtered to current year's version)
|
||||
2. Calls `GoogleMapsDownloaderV2.GetTilesWithMetadataAsync` with existing tiles to skip
|
||||
2. Calls `ISatelliteDownloader.GetTilesWithMetadataAsync` with existing tiles to skip
|
||||
3. Creates `TileEntity` for each newly downloaded tile and inserts via repository (upsert)
|
||||
4. Returns combined list of existing + new tile metadata
|
||||
- `GetTileAsync(Guid id) → Task<TileMetadata?>`: single tile lookup
|
||||
- `GetTilesByRegionAsync(double lat, double lon, double sizeMeters, int zoomLevel) → Task<IEnumerable<TileMetadata>>`: query tiles in a region
|
||||
- `GetOrDownloadTileAsync(int z, int x, int y, CancellationToken) → Task<TileBytes>` (AZ-310): cache → repository → downloader fallback for single Z/X/Y serving
|
||||
- `DownloadAndStoreSingleTileAsync(double latitude, double longitude, int zoomLevel, CancellationToken) → Task<TileMetadata>` (AZ-311): download one tile by lat/lon, persist, return metadata
|
||||
|
||||
## Internal Logic
|
||||
- Version is `DateTime.UtcNow.Year` — tiles are considered fresh for the current calendar year
|
||||
- `MapToMetadata(TileEntity) → TileMetadata`: entity-to-DTO mapping (static helper)
|
||||
- Tile size hardcoded to 256 pixels, image type "jpg"
|
||||
- `MapsVersion` formatted as `"downloaded_{date}"`
|
||||
- `IMemoryCache` keyed by `(z, x, y)` with 1h absolute / 30min sliding expiration; populated on first hit and on downloader fallback
|
||||
|
||||
## Dependencies
|
||||
- `GoogleMapsDownloaderV2` (concrete class, not interface)
|
||||
- `ISatelliteDownloader` (resolved via DI; concrete is `GoogleMapsDownloaderV2`)
|
||||
- `ITileRepository`
|
||||
- `SatelliteProvider.Common.DTO` — GeoPoint, TileMetadata
|
||||
- `IMemoryCache` (registered by `AddTileDownloader()`)
|
||||
- `SatelliteProvider.Common.DTO` — GeoPoint, TileMetadata, TileBytes
|
||||
- `SatelliteProvider.DataAccess.Models` — TileEntity
|
||||
|
||||
## Consumers
|
||||
|
||||
@@ -12,8 +12,8 @@ Unit test project. Currently contains only a single dummy test as a placeholder.
|
||||
No meaningful test logic.
|
||||
|
||||
## Dependencies
|
||||
- Project references: `SatelliteProvider.Services`, `SatelliteProvider.Common`
|
||||
- NuGet: xUnit (2.5.3), Moq (4.20.72), FluentAssertions (8.8.0), coverlet.collector (6.0.0), Microsoft.NET.Test.Sdk (17.8.0), Microsoft.Extensions.* (Configuration, DI, Logging, Options, Http)
|
||||
- Project references: `SatelliteProvider.Services.TileDownloader`, `SatelliteProvider.Services.RegionProcessing`, `SatelliteProvider.Services.RouteManagement`, `SatelliteProvider.Common`, `SatelliteProvider.DataAccess`
|
||||
- NuGet: xUnit (2.5.3), Moq (4.20.72), FluentAssertions (8.8.0), coverlet.collector (6.0.0), Microsoft.NET.Test.Sdk (17.8.0), Microsoft.Extensions.* (Caching.Memory, Configuration, DI, Logging, Options, Http)
|
||||
- Has `appsettings.json` copied to output (empty config for potential future test setups)
|
||||
|
||||
## Consumers
|
||||
|
||||
Reference in New Issue
Block a user