[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:
Oleksandr Bezdieniezhnykh
2026-05-10 07:25:21 +03:00
parent 8b0ddae075
commit 6b373082c8
14 changed files with 290 additions and 89 deletions
@@ -6,9 +6,11 @@
**Architectural Pattern**: Service + Gateway (wraps external API with retry/throttling)
**Upstream dependencies**: Common (DTOs, GeoUtils, configs), DataAccess (TileEntity, ITileRepository)
**csproj**: `SatelliteProvider.Services.TileDownloader/SatelliteProvider.Services.TileDownloader.csproj` (split out of the monolithic `SatelliteProvider.Services` project in epic AZ-309)
**Downstream consumers**: RegionProcessing (via ITileService), WebApi (GoogleMapsDownloaderV2 directly for single-tile endpoints)
**Upstream dependencies**: Common (DTOs, GeoUtils, configs, RateLimitException), DataAccess (TileEntity, ITileRepository)
**Downstream consumers**: RegionProcessing and WebApi — both via `ITileService` from Common (no compile-time `ProjectReference` from any consumer to this project's concrete types).
## 2. Internal Interfaces
@@ -24,13 +26,15 @@
| `DownloadAndStoreTilesAsync` | lat, lon, sizeM, zoom, CancellationToken | `List<TileMetadata>` | Yes | propagated from downloader |
| `GetTileAsync` | Guid | `TileMetadata?` | Yes | NpgsqlException |
| `GetTilesByRegionAsync` | lat, lon, sizeM, zoom | `IEnumerable<TileMetadata>` | Yes | NpgsqlException |
| `GetOrDownloadTileAsync` (AZ-310) | z, x, y, CancellationToken | `TileBytes` | Yes | propagated from downloader |
| `DownloadAndStoreSingleTileAsync` (AZ-311) | lat, lon, zoom, CancellationToken | `TileMetadata` | Yes | propagated from downloader |
## 4. Data Access Patterns
### Caching Strategy
| Data | Cache Type | TTL | Invalidation |
|------|-----------|-----|-------------|
| Tile bytes | In-memory (IMemoryCache, WebApi layer) | 1h absolute, 30min sliding | None (manual restart) |
| Tile bytes | In-memory (IMemoryCache, owned by TileService since AZ-310) | 1h absolute, 30min sliding | None (manual restart) |
| Tile metadata | Database | Until year rollover | Version-based (current year) |
| Active downloads | ConcurrentDictionary | Duration of download | Removed on completion |
@@ -53,7 +57,7 @@
## 7. Caveats & Edge Cases
- `GoogleMapsDownloaderV2` is registered as a concrete singleton (not behind an interface), creating tight coupling in `TileService` and `Program.cs`
- `GoogleMapsDownloaderV2` is registered behind `ISatelliteDownloader` (resolved by AZ-310 cleanup); the previous concrete-type coupling is gone.
- User-Agent header spoofs Chrome — could be rejected if Google changes detection
- Allowed zoom levels hardcoded to [15,16,17,18,19] — throws for others
- Session token rotation threshold (100 tiles) is an educated guess; Google's actual limit is not documented