Phase B of architecture coupling refactor (epic AZ-309). Replaces the monolithic SatelliteProvider.Services with three per-component csprojs to add a compiler-enforced module boundary (resolves F4): - SatelliteProvider.Services.TileDownloader - SatelliteProvider.Services.RegionProcessing - SatelliteProvider.Services.RouteManagement DI registrations relocated into per-component AddTileDownloader / AddRegionProcessing / AddRouteManagement extension methods called from Program.cs. RateLimitException moved to Common/Exceptions/ to keep the three new csprojs as siblings (no Region->TileDownloader ProjectReference). Dockerfiles and consumer csprojs (Api, Tests) rewired to the new project paths. No DI lifetime or hosted-service order changes. Build: 0 warn, 0 err. Unit tests: 40/40. Smoke integration: green. Co-authored-by: Cursor <cursoragent@cursor.com>
3.7 KiB
Batch Report
Batch: 5 (refactor 02-coupling-refactoring · Phase B) Tasks: AZ-312, AZ-313, AZ-314 Date: 2026-05-10
Task Results
| Task | Status | Files Modified | Tests | AC Coverage | Issues |
|---|---|---|---|---|---|
| AZ-312 Split Services into 3 csprojs | Done | 3 new csprojs + 7 source moves + sln + 2 Dockerfiles | 40/40 + smoke | 4/4 ACs | None |
| AZ-313 Update consumer csprojs | Done | Api.csproj + Tests.csproj + 5 test usings | 40/40 + smoke | 3/3 ACs | None |
| AZ-314 DI extension methods | Done | 3 new ServiceCollectionExtensions + Program.cs | 40/40 + smoke | 4/4 ACs | None |
Files Changed
New:
SatelliteProvider.Services.TileDownloader/SatelliteProvider.Services.TileDownloader.csprojSatelliteProvider.Services.TileDownloader/TileDownloaderServiceCollectionExtensions.csSatelliteProvider.Services.RegionProcessing/SatelliteProvider.Services.RegionProcessing.csprojSatelliteProvider.Services.RegionProcessing/RegionProcessingServiceCollectionExtensions.csSatelliteProvider.Services.RouteManagement/SatelliteProvider.Services.RouteManagement.csprojSatelliteProvider.Services.RouteManagement/RouteManagementServiceCollectionExtensions.csSatelliteProvider.Common/Exceptions/RateLimitException.cs
Moved (with namespace updates):
TileService.cs,GoogleMapsDownloaderV2.cs→SatelliteProvider.Services.TileDownloader/RegionService.cs,RegionProcessingService.cs,RegionRequestQueue.cs→SatelliteProvider.Services.RegionProcessing/RouteService.cs,RouteProcessingService.cs→SatelliteProvider.Services.RouteManagement/
Modified:
SatelliteProvider.Api/Program.cs(DI cleanup + namespace usings)SatelliteProvider.Api/SatelliteProvider.Api.csproj(3 new ProjectReferences)SatelliteProvider.Api/Dockerfile(COPY new csproj paths)SatelliteProvider.IntegrationTests/Dockerfile(drop stale COPY of old Services csproj)SatelliteProvider.Tests/SatelliteProvider.Tests.csproj(3 new ProjectReferences)SatelliteProvider.Tests/InfrastructureTests.cs,TileServiceTests.cs,RegionServiceTests.cs,RouteServiceTests.cs,RegionRequestQueueTests.cs(using updates)SatelliteProvider.sln
Deleted:
SatelliteProvider.Services/directory (csproj + 7 source files moved out)
AC Test Coverage
11 of 11 ACs across the 3 tasks covered. Build/test acceptance verified by dotnet build (0 warn, 0 err), 40/40 unit tests, and smoke integration suite passing end-to-end.
Code Review Verdict
PASS — no findings. See _docs/03_implementation/reviews/batch_05_review.md.
Auto-Fix Attempts
1 (in-batch): RateLimitException was originally defined in GoogleMapsDownloaderV2.cs (TileDownloader) and caught in RegionService.cs (RegionProcessing). After the split, this would have required a RegionProcessing → TileDownloader ProjectReference (cross-Layer-3 dependency). Resolved by relocating the exception to SatelliteProvider.Common/Exceptions/.
Build / Tests
dotnet build SatelliteProvider.sln --configuration Release→ 0 warnings, 0 errors (47.98s)dotnet test SatelliteProvider.Tests→ 40/40 passed (1.93s)./scripts/run-tests.sh --smoke→ all integration tests pass end-to-end (~2 min)
Architecture-Baseline Impact
- F4 (Medium — single Services csproj packs three components): resolved by project split. Compiler now enforces the layer-3 sibling boundary.
- F3 (Medium — already resolved in Batch 4): no regression.
- Documentation sync (
module-layout.md,architecture.md) deferred to AZ-315 (Batch 6).
Next Batch
AZ-315 (Phase C — documentation sync: update architecture.md and module-layout.md to reflect the split, then close epic AZ-309).