mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 17:51:13 +00:00
[AZ-312] [AZ-313] [AZ-314] Split Services into per-component csprojs
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>
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
# 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.csproj`
|
||||
- `SatelliteProvider.Services.TileDownloader/TileDownloaderServiceCollectionExtensions.cs`
|
||||
- `SatelliteProvider.Services.RegionProcessing/SatelliteProvider.Services.RegionProcessing.csproj`
|
||||
- `SatelliteProvider.Services.RegionProcessing/RegionProcessingServiceCollectionExtensions.cs`
|
||||
- `SatelliteProvider.Services.RouteManagement/SatelliteProvider.Services.RouteManagement.csproj`
|
||||
- `SatelliteProvider.Services.RouteManagement/RouteManagementServiceCollectionExtensions.cs`
|
||||
- `SatelliteProvider.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).
|
||||
@@ -0,0 +1,107 @@
|
||||
# Code Review Report
|
||||
|
||||
**Batch**: 5 (AZ-312, AZ-313, AZ-314 — coupling refactor: project split + DI extension methods)
|
||||
**Date**: 2026-05-10
|
||||
**Verdict**: PASS
|
||||
|
||||
## Scope
|
||||
|
||||
Structural refactoring (architecture baseline finding F4): split monolithic `SatelliteProvider.Services` into three per-component csprojs, rewire consumers, and extract DI registrations into per-component extension methods.
|
||||
|
||||
Tasks reviewed:
|
||||
- **AZ-312** — split Services into TileDownloader + RegionProcessing + RouteManagement csprojs
|
||||
- **AZ-313** — update consumer csprojs (Api, Tests, IntegrationTests) + `using` directives
|
||||
- **AZ-314** — DI extension methods per csproj + Program.cs cleanup
|
||||
|
||||
## Changed files
|
||||
|
||||
- New csprojs:
|
||||
- `SatelliteProvider.Services.TileDownloader/SatelliteProvider.Services.TileDownloader.csproj`
|
||||
- `SatelliteProvider.Services.RegionProcessing/SatelliteProvider.Services.RegionProcessing.csproj`
|
||||
- `SatelliteProvider.Services.RouteManagement/SatelliteProvider.Services.RouteManagement.csproj`
|
||||
- New DI extension files:
|
||||
- `SatelliteProvider.Services.TileDownloader/TileDownloaderServiceCollectionExtensions.cs`
|
||||
- `SatelliteProvider.Services.RegionProcessing/RegionProcessingServiceCollectionExtensions.cs`
|
||||
- `SatelliteProvider.Services.RouteManagement/RouteManagementServiceCollectionExtensions.cs`
|
||||
- Moved (with namespace updates): `TileService.cs`, `GoogleMapsDownloaderV2.cs`, `RegionService.cs`, `RegionProcessingService.cs`, `RegionRequestQueue.cs`, `RouteService.cs`, `RouteProcessingService.cs`
|
||||
- New common exception: `SatelliteProvider.Common/Exceptions/RateLimitException.cs`
|
||||
- Modified: `SatelliteProvider.Api/Program.cs`, `SatelliteProvider.Api/SatelliteProvider.Api.csproj`, `SatelliteProvider.Tests/SatelliteProvider.Tests.csproj`, all 5 `*Tests.cs` files (`using` updates), `SatelliteProvider.sln`, both `Dockerfile`s
|
||||
- Deleted: `SatelliteProvider.Services/` directory and `SatelliteProvider.Services.csproj`
|
||||
|
||||
## Findings
|
||||
|
||||
| # | Severity | Category | File:Line | Title |
|
||||
|---|----------|----------|-----------|-------|
|
||||
|
||||
No findings.
|
||||
|
||||
## Phase results
|
||||
|
||||
### Phase 2 — Spec compliance
|
||||
|
||||
**AZ-312 (project split)**
|
||||
|
||||
- AC-1 ✓ — Three new csprojs exist with the seven moved source files distributed correctly (verified by `ls`).
|
||||
- AC-2 ✓ — Old `SatelliteProvider.Services/` directory and csproj deleted; `SatelliteProvider.sln` updated.
|
||||
- AC-3 ✓ — `dotnet build SatelliteProvider.sln` succeeds with 0 warnings, 0 errors.
|
||||
- AC-4 ✓ — None of the three new csprojs reference each other. All three reference only `SatelliteProvider.Common` + `SatelliteProvider.DataAccess`.
|
||||
|
||||
**AZ-313 (consumer rewire)**
|
||||
|
||||
- AC-1 ✓ — Solution builds clean (47.98s, 0 warnings).
|
||||
- AC-2 ✓ — All 40 unit tests pass (1.93s).
|
||||
- AC-3 ✓ — Grep for `using SatelliteProvider.Services;` (no `.<Component>` suffix) returns zero source-file matches.
|
||||
|
||||
**AZ-314 (DI extension methods)**
|
||||
|
||||
- AC-1 ✓ — Each `*ServiceCollectionExtensions.cs` registers exactly the services owned by its csproj:
|
||||
- `AddTileDownloader`: `IMemoryCache`, `ISatelliteDownloader`, `ITileService`
|
||||
- `AddRegionProcessing`: `IRegionRequestQueue` (factory), `IRegionService`, `RegionProcessingService` (hosted)
|
||||
- `AddRouteManagement`: `IRouteService`, `RouteProcessingService` (hosted)
|
||||
- AC-2 ✓ — `Program.cs:33-35` calls the three extension methods; previously inlined registrations are gone.
|
||||
- AC-3 ✓ — Smoke integration suite passes end-to-end (region processing, route processing, tile ZIP, security tests). Every required service resolves at runtime.
|
||||
- AC-4 ✓ — No old service-registration code remains in `Program.cs`.
|
||||
|
||||
### Phase 3 — Code quality
|
||||
|
||||
- SOLID (SRP/DIP) **improved** — components now have a compiler-enforced boundary; cross-component coupling can no longer be introduced silently.
|
||||
- Lifetimes preserved — `Singleton` stayed `Singleton`, hosted services stayed hosted services.
|
||||
- Hosted-service registration order preserved (`RegionProcessingService` before `RouteProcessingService`, matching pre-refactor order in Program.cs).
|
||||
- No new dead code; no scope creep.
|
||||
|
||||
### Phase 4 — Security quick-scan
|
||||
|
||||
Refactor is structural; no new input handling, query construction, or deserialization paths. Smoke security tests (SEC-01 SQL injection, SEC-02 path traversal, SEC-03 oversized region, SEC-04 malformed JSON) all pass post-refactor.
|
||||
|
||||
### Phase 5 — Performance scan
|
||||
|
||||
No hot-path changes. No new allocations in the moved code (only namespace and project boundary changes).
|
||||
|
||||
### Phase 6 — Cross-task consistency
|
||||
|
||||
- All three new extension methods follow the same `Add<Component>(this IServiceCollection)` naming convention.
|
||||
- All three new csprojs share identical TFM (`net8.0`), `ImplicitUsings`, and `Nullable` settings.
|
||||
- Package versions consistent (`9.0.10` for `Microsoft.Extensions.*`, `13.0.4` for `Newtonsoft.Json`, `3.1.11` for `SixLabors.ImageSharp`).
|
||||
|
||||
### Phase 7 — Architecture compliance
|
||||
|
||||
- **Layer direction** ✓ — TileDownloader (Layer 2) imports only Common + DataAccess (Layer 1). RegionProcessing and RouteManagement (Layer 3) import only Common + DataAccess (no cross-Layer-3 references after the refactor — even better than the pre-refactor baseline allowed).
|
||||
- **Public API respect** ✓ — All cross-component imports use interfaces from `SatelliteProvider.Common.Interfaces`, never concrete types from sibling components.
|
||||
- **No new cyclic dependencies** ✓ — Graph is a clean DAG: Common ← {DataAccess} ← {TileDownloader, RegionProcessing, RouteManagement} ← WebApi.
|
||||
- **Architecture baseline F4** — **RESOLVED**. The single `SatelliteProvider.Services.csproj` packing three components is replaced by three csprojs with compiler-enforced boundaries.
|
||||
- **Architecture baseline F3** — already resolved in Batch 4 (AZ-310 + AZ-311); this batch did not regress it (`Program.cs` tile endpoints still route through `ITileService`).
|
||||
- **`RateLimitException` placement** — moved to `SatelliteProvider.Common/Exceptions/` rather than allowing a `RegionProcessing → TileDownloader` ProjectReference. This is the cleanest of the three options considered (move to Common / add reference / catch general `Exception`) and preserves layer 3 components as siblings rather than coupling them.
|
||||
|
||||
## Baseline Delta
|
||||
|
||||
| Status | Finding | Severity | Notes |
|
||||
|--------|---------|----------|-------|
|
||||
| Resolved | F4 — `SatelliteProvider.Services.csproj` packs three logical components | Medium | Split into three csprojs |
|
||||
| Carried over | (none for this batch) | — | — |
|
||||
| Newly introduced | (none) | — | — |
|
||||
|
||||
`module-layout.md` and `architecture.md` still describe the pre-split layout (single `SatelliteProvider.Services/` project). This is **expected** — documentation sync is task **AZ-315** (Batch 3 of this refactor run). Not a finding.
|
||||
|
||||
## Verdict
|
||||
|
||||
**PASS** — all 12 ACs across 3 tasks satisfied. Build clean. Unit tests 40/40. Smoke integration green. Architecture baseline F4 resolved with no new findings.
|
||||
Reference in New Issue
Block a user