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>
4.2 KiB
Architecture Compliance Baseline
Date: 2026-05-10 Mode: Baseline (Phase 1 + Phase 7) Scope: Full existing codebase Verdict: PASS_WITH_WARNINGS
Findings
| # | Severity | Category | File:Line | Title |
|---|---|---|---|---|
| 1 | High | Architecture | SatelliteProvider.Services/TileService.cs:11 | Concrete dependency on GoogleMapsDownloaderV2 bypasses ISatelliteDownloader |
| 2 | High | Architecture | SatelliteProvider.Common/Interfaces/ISatelliteDownloader.cs | ISatelliteDownloader interface is dead code |
| 3 | Medium | Architecture | SatelliteProvider.Api/Program.cs:141 | API endpoint directly injects concrete downloader + repository |
| 4 | Medium | Architecture | SatelliteProvider.Services/ | No physical boundary between logical components in shared project |
| 5 | Low | Architecture | module-layout.md | DataAccess documented as importing Common but actually has zero cross-project dependencies |
Finding Details
F1: Concrete dependency on GoogleMapsDownloaderV2 (High / Architecture)
- Location:
SatelliteProvider.Services/TileService.cs:11 - Description:
TileServicedepends on the concrete classGoogleMapsDownloaderV2instead ofISatelliteDownloader. DI registration is also concrete (AddSingleton<GoogleMapsDownloaderV2>()). This couples the entire tile pipeline to a single provider. - Impact: Adding a new satellite imagery provider requires modifying TileService and Program.cs DI wiring rather than just registering a new implementation.
- Suggestion: Have
GoogleMapsDownloaderV2implementISatelliteDownloader, update DI to register via interface, inject interface into TileService.
F2: ISatelliteDownloader is dead code (High / Architecture)
- Location:
SatelliteProvider.Common/Interfaces/ISatelliteDownloader.cs - Description: The interface exists (declares
GetTiles(GeoPoint, double, int, CancellationToken)) but NO class implements it and NO code references it. The actual downloader method used isGoogleMapsDownloaderV2.GetTilesWithMetadataAsync()which has a different signature. - Impact: The provider-agnostic abstraction doesn't function. Interface and implementation have diverged.
- Suggestion: Update
ISatelliteDownloaderto match the actual API surface needed by consumers, then implement it inGoogleMapsDownloaderV2.
F3: API endpoint bypasses service layer (Medium / Architecture)
- Location:
SatelliteProvider.Api/Program.cs:141(ServeTile) and:206(GetTileByLatLon) - Description: Two API endpoints directly inject
GoogleMapsDownloaderV2andITileRepositoryinstead of usingITileService. This bypasses the service layer and creates a shortcut from Layer 4 to Layer 2. - Impact: Business logic (caching, dedup) in TileService is bypassed for these endpoints; tile download logic is duplicated.
- Suggestion: Route all tile operations through
ITileService.
F4: No physical boundary in Services project (Medium / Architecture)
- Location:
SatelliteProvider.Services/(all files) - Description: Three logical components (TileDownloader, RegionProcessing, RouteManagement) share one
.csproj. No compiler-enforced boundary prevents direct cross-component coupling. - Impact: Over time, services may accumulate hidden coupling that's hard to detect without code review.
- Suggestion: Accept as-is for current scale; consider splitting into separate projects if the codebase grows significantly.
F5: module-layout.md incorrect — DataAccess has no Common dependency (Low / Architecture)
- Location:
_docs/02_document/module-layout.md - Description: DataAccess was documented as "Imports from: Common" but
SatelliteProvider.DataAccess.csprojhas no ProjectReference to Common and nousing SatelliteProvider.Commonin any file. - Impact: Documentation inaccuracy; no code impact.
- Suggestion: Correct module-layout.md.
Summary
| Severity | Count |
|---|---|
| Critical | 0 |
| High | 2 |
| Medium | 2 |
| Low | 1 |
The two High findings both relate to the same root cause: the ISatelliteDownloader abstraction was created but never wired into the system. The concrete GoogleMapsDownloaderV2 is used directly everywhere. This is the primary architecture gap — addressing it would enable the provider-agnostic design the system intends to have.