mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 07:01:15 +00:00
9a53bff92e
Batch 24 of 03-code-quality-refactoring run; closes the run. AZ-375 (C22): GoogleMapsDownloaderV2.DownloadTilesGridAsync now builds a HashSet<(int X, int Y, int Z)> once from existingTiles and tests Contains((x, y, zoomLevel)) per cell. Removes the per-cell FirstOrDefault tolerance scan and the unused _processingConfig .LatLonTolerance reference at this site. AZ-377 (C24): promote Earth + tile-pixel constants to a single home. GeoUtils now exposes EarthRadiusMeters, EarthEquatorial CircumferenceMeters, MetersPerDegreeLatitude as public const. MapConfig adds DefaultTileSizePixels (const) wired as the TileSizePixels property default. TileRepository and Google MapsDownloaderV2 read those constants instead of duplicating the literals 6378137, 40075016.686, 111000.0, and 256. Tests: +6 new (DownloaderRefactorTests, extended GeoUtils RefactorTests). 200/200 unit tests pass. Cumulative K=3 review (batches 22-24): PASS_WITH_WARNINGS, 4 Low findings only — see _docs/03_implementation/reviews/cumulative_review_22-24.md. Tooling fix: scripts/run-tests.sh --unit-only path now restores before testing (was failing on SixLabors resolution in clean container). Stripped stray BOM from MapConfig.cs to satisfy the .editorconfig charset gate. Updates _dependencies_table.md to reflect all 27 03-code-quality- refactoring tasks done; updates _autodev_state.md to refactor phase 5 (test-sync). Co-authored-by: Cursor <cursoragent@cursor.com>
11 KiB
11 KiB
Cumulative Code Review Report (K=3)
Batches: 22, 23, 24 Tasks covered:
- B22: AZ-372 (C19 — dotnet format + analyzers + Coverlet)
- B23: AZ-376 (C23), AZ-378 (C25), AZ-379 (C26), AZ-380 (C27)
- B24: AZ-375 (C22), AZ-377 (C24) Date: 2026-05-11 Mode: Cumulative (all 7 phases on union of changed files since last cumulative review) Verdict: PASS_WITH_WARNINGS
Scope (changed files since cumulative review @ batch 21 close)
Production source:
SatelliteProvider.Common/Configs/MapConfig.csSatelliteProvider.Common/Utils/GeoUtils.csSatelliteProvider.DataAccess/Repositories/ITileRepository.csSatelliteProvider.DataAccess/Repositories/TileRepository.csSatelliteProvider.DataAccess/Repositories/RegionRepository.csSatelliteProvider.DataAccess/Repositories/RouteRepository.csSatelliteProvider.Services.TileDownloader/GoogleMapsDownloaderV2.csSatelliteProvider.Api/Program.cs
Tooling / config:
.editorconfigDirectory.Build.propsscripts/run-tests.sh
Tests added or extended:
SatelliteProvider.Tests/ToolingConfigurationTests.csSatelliteProvider.Tests/RepositoryRefactorTests.csSatelliteProvider.Tests/GeoUtilsRefactorTests.csSatelliteProvider.Tests/DownloaderRefactorTests.cs
Findings
| # | Severity | Category | File:Line | Title |
|---|---|---|---|---|
| 1 | Low | Architecture | SatelliteProvider.DataAccess/SatelliteProvider.DataAccess.csproj + _docs/02_document/architecture_compliance_baseline.md (F5) |
DataAccess→Common dependency surface widened; baseline doc still claims "no Common dependency" |
| 2 | Low | Maintainability | SatelliteProvider.DataAccess/Repositories/RouteRepository.cs:38 |
route_points column list still inline (single use) |
| 3 | Low | Spec-Gap | _docs/02_tasks/done/AZ-37* task ACs |
Stale "37 unit + 5 smoke" test count in AC text |
| 4 | Low | Maintainability | SatelliteProvider.Common/Configs/MapConfig.cs |
TileSizePixels is now both a property default and a const; small surface duplication for compile-time consumers |
Finding Details
F1: DataAccess→Common dependency surface widened (Low / Architecture)
- Location:
SatelliteProvider.DataAccess/SatelliteProvider.DataAccess.csproj(project reference); affectsarchitecture_compliance_baseline.mdFinding F5. - Description: AZ-377 introduces
using SatelliteProvider.Common.Configs;andusing SatelliteProvider.Common.Utils;inTileRepository.cs. The baseline doc (Resolved F5) andmodule-layout.mdclaim DataAccess has no Common dependency. In reality the<ProjectReference>to Common already exists in the csproj and 5 files in DataAccess (RegionRepository.cs,IRegionRepository.cs,Models/RegionEntity.cs,Models/RoutePointEntity.cs,TypeHandlers/EnumStringTypeHandler.cs) already importSatelliteProvider.Common.Enums. Batch 24 widens the surface to also includeCommon.ConfigsandCommon.Utils. - Impact: Documentation drift only. The actual dependency graph has been DataAccess→Common since at least the AZ-309 cleanup; the baseline marked F5 "Resolved" prematurely. No new layering violation — Common stays at the leaf and DataAccess remains one level above it.
- Suggestion: in the next documentation pass, update
_docs/02_document/module-layout.md(DataAccessImports from) and the baseline F5 entry to match reality (SatelliteProvider.Common.Enums,SatelliteProvider.Common.Configs,SatelliteProvider.Common.Utils). Do not invert the actual code dependency — the constants legitimately belong in Common and DataAccess legitimately needs them. - Task: AZ-377
F2: route_points column list still inline (Low / Maintainability) — carry-over from batch 23
- Location:
SatelliteProvider.DataAccess/Repositories/RouteRepository.cs:38-46 - Description:
GetRoutePointsAsynckeeps its 8-column list inline; AZ-379's "extract once per repository" target is satisfied by theroutesColumnList. - Suggestion: extract only when a second SELECT against
route_pointsarrives. - Task: AZ-379
F3: Stale "37 unit + 5 smoke" count in AC text (Low / Spec-Gap) — carry-over from batch 23
- Location: AC-3 of AZ-375, AZ-376, AZ-377, AZ-378, AZ-379, AZ-380.
- Description: Tasks were authored when the unit count was 37; suite now reports 200/200 passing after batch 24. The "scripts/run-tests.sh --smoke" command still gates correctly; only the literal count in the AC narrative is stale.
- Suggestion: leave as-is — the gate is the script's exit code, not the printed number; rewriting historical AC text would create churn without changing what is verified.
- Task: documentation/process
F4: MapConfig.TileSizePixels exists as both property and const (Low / Maintainability)
- Location:
SatelliteProvider.Common/Configs/MapConfig.cs:12-14 - Description: AZ-377 introduces
public const int DefaultTileSizePixels = 256;so DataAccess (which cannot injectIOptions<MapConfig>from a Repository constructor) can reference a single source. The propertyTileSizePixelskeeps its setter for config binding and is now wired to the const as its default. Small surface duplication, deliberate. - Impact: Two access paths to the same value —
MapConfig.DefaultTileSizePixels(compile-time) andIOptions<MapConfig>.Value.TileSizePixels(runtime). If a deployment ever overrides the property inappsettings.json, DataAccess will silently disagree with config-bound consumers because it reads the const. - Suggestion: accepted trade-off for now —
appsettings.jsondoes not currently override the value and DI in DataAccess is a separate refactor (would require pushingIOptionsthrough the repository interface). Document the decision inMapConfig.cs(already added an XML-style comment in batch 24) and revisit if anyone overridesTileSizePixelsin config. - Task: AZ-377
Phase results (summary)
Phase 2 — Spec compliance
- AZ-372: format gate present (
Step 0inrun-tests.sh), Directory.Build.props has analyzers + Coverlet, ToolingConfigurationTests pin them. ✓ - AZ-376:
FindExistingTileAsyncremoved from interface and impl (RepositoryRefactorTests AZ376_AC1 passes). ✓ - AZ-378: RegionRepository, RouteRepository constructors take only the connection string; TileRepository keeps
_loggerand uses it for slow-query warnings (RepositoryRefactorTests AZ378_AC1, AC2 pass). ✓ - AZ-379: All three repositories define exactly one
private const string ColumnList; SELECTs use the const (RepositoryRefactorTests AZ379_AC1, AC2 pass). ✓ - AZ-380:
CalculatePolygonDiagonalDistanceremoved (GeoUtilsRefactorTests AZ380_AC1 passes). ✓ - AZ-375: HashSet<(int, int, int)> built once and
Contains((x, y, zoomLevel))replaces the per-cellFirstOrDefault;_processingConfig.LatLonToleranceno longer referenced at this site (DownloaderRefactorTests AZ375_AC1 passes; grep confirms0.0001only remains in the unrelatedProcessingConfigdefault and tests). ✓ - AZ-377:
EarthRadiusMeters,EarthEquatorialCircumferenceMeters,MetersPerDegreeLatitudearepublic const doubleonGeoUtils;MapConfig.DefaultTileSizePixelsis apublic const intmirroring the property default; all source-code occurrences of6378137,40075016.686,111000, and source-code occurrences of256are confined to those declarations (DownloaderRefactorTests + GeoUtilsRefactorTests AZ377_AC1, AC2 pass). ✓
Phase 3 — Code quality
- All edits under SRP — no method gained more than one responsibility; HashSet builder is a small, named, local computation in the same method; logger removal from RegionRepository/RouteRepository is purely subtractive.
- No bare catches introduced. No new debug-noise logs. No obvious duplication.
Phase 4 — Security quick-scan
- No new SQL string interpolation (Dapper named params throughout, ColumnList is a
const string, not user input). - No new secrets, no new external inputs.
- Slow-query warning logs query duration and SQL text, both safe.
Phase 5 — Performance scan
- AZ-375 directly removes an O(N) per-cell scan inside an O(grid) loop: a region of NxN tiles previously did O(N² · existingTiles) work; now O(existingTiles) preprocessing + O(1) per cell.
- No N+1 queries introduced; the existing-tiles query batch shape is unchanged.
- No blocking I/O in async paths added.
Phase 6 — Cross-task consistency
- Batch 23 + 24 collectively touch the same three repositories and
GoogleMapsDownloaderV2; constants moved into Common are consumed by DataAccess and the downloader uniformly. No divergent patterns. - AZ-379's ColumnList convention applied identically across all three repos (
private const string ColumnList = @"…", used via$@"… SELECT {ColumnList} …").
Phase 7 — Architecture compliance
- Layer direction: Common (leaf) ← DataAccess ← Services.TileDownloader ← Api. All new imports respect the table.
- Public API respect:
GeoUtils,MapConfig, and their new constants are top-level public types inCommon. No internal-file imports. - New cyclic deps: none introduced (DataAccess→Common is one-way; Common does not reference DataAccess).
- Duplicate symbols: the previous duplicate Earth literals across
GoogleMapsDownloaderV2.csandTileRepository.csare now collapsed to one declaration inGeoUtils.cs. TheMapConfig.TileSizePixelsproperty +MapConfig.DefaultTileSizePixelsconst live in the same class — see F4.
Baseline Delta
| Status | Severity | Title | Note |
|---|---|---|---|
| Carried over | Low | F5 — DataAccess Common dependency drift | Documentation drift; widened by AZ-377 (see F1 above). |
| Resolved | Low | duplicate Earth literals across modules | Cumulative review @ batch 21 had flagged the same literals in two files; AZ-377 collapses them to a single source in GeoUtils. |
| Newly introduced | — | none | No new Critical / High / Medium architectural findings. |
Per-category counts (current scope):
| Category | Critical | High | Medium | Low |
|---|---|---|---|---|
| Architecture | 0 | 0 | 0 | 1 |
| Maintainability | 0 | 0 | 0 | 2 |
| Spec-Gap | 0 | 0 | 0 | 1 |
| Security | 0 | 0 | 0 | 0 |
| Performance | 0 | 0 | 0 | 0 |
| Bug | 0 | 0 | 0 | 0 |
Test posture
scripts/run-tests.sh --unit-only: 200/200 PASS (10 new tests added across batches 23-24).- Format gate (
dotnet format whitespace --verify-no-changes): PASS. - Full smoke / integration suite: not re-run as part of this cumulative review (next session boundary will run it before commit if the engine requires).
Verdict logic
- 0 Critical, 0 High, 0 Medium, 4 Low → PASS_WITH_WARNINGS.
- No FAIL conditions; no auto-fix loop required.
Recommended follow-ups (non-blocking)
- Refresh
_docs/02_document/module-layout.mdand the baseline F5 entry to reflect the actual DataAccess→Common dependency (Common.Enums, Common.Configs, Common.Utils). - Decide whether
MapConfig.DefaultTileSizePixelsshould remain a const or be threaded throughIOptionsinto DataAccess; defer until someone overrides the value in config. - Consider a future task to update the AC test-count narrative across the AZ-37x tickets if/when the project does a doc-sweep.