Files
satellite-provider/_docs/03_implementation/batch_21_report.md
T
Oleksandr Bezdieniezhnykh 7736cfd761
ci/woodpecker/push/01-test Pipeline was successful
ci/woodpecker/push/02-build-push Pipeline was successful
[AZ-374] Add batch 21 report; autodev state batch 21 complete
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 04:11:57 +03:00

6.8 KiB
Raw Blame History

Batch Report

Batch: 21 Tasks: AZ-374 (C21 — typed/named HttpClient for Google Maps in DI) Date: 2026-05-11 Run: 03-code-quality-refactoring Cycle: 1

Task Results

Task Status Files Modified Tests AC Coverage Issues
AZ-374_refactor_typed_httpclient_googlemaps Done 3 src/test = 3 files 175 unit + 5 smoke pass 3/3 covered None

Design note: registration location

The task spec recommended adding AddHttpClient("GoogleMapsTiles", ...) in Program.cs. I placed it inside TileDownloaderServiceCollectionExtensions.AddTileDownloader() instead. Rationale (per coderule.mdc SRP guidance):

  • The named-client name, User-Agent, and timeout are all TileDownloader-internal concerns. Their owner is the component that resolves them — GoogleMapsDownloaderV2. The DI extension already encapsulates everything else TileDownloader needs (memory cache, ISatelliteDownloader, ITileService).
  • Placing this in Program.cs would have spread component-internal knowledge into the application entry-point file. The extension was created precisely to avoid that.
  • The bare builder.Services.AddHttpClient() call in Program.cs:36 was kept untouched — it is now structurally redundant (the named-client registration also wires up IHttpClientFactory), but removing it is outside this task's scope.

The named-client name itself ("GoogleMapsTiles"), the User-Agent header value, and the 100-second default timeout are now internal consts on GoogleMapsDownloaderV2 so the extension method and the downloader resolve from the same source of truth.

Changes

Modified production code

  • SatelliteProvider.Services.TileDownloader/GoogleMapsDownloaderV2.cs
    • Promoted private const USER_AGENTinternal const UserAgent (PascalCase; visibility to allow the extension method in the same assembly to reference it).
    • Added internal const string GoogleMapsTilesClientName = "GoogleMapsTiles";.
    • Added internal const int DefaultHttpClientTimeoutSeconds = 100; (matches HttpClient's implicit default; preserves prior behavior).
    • Three CreateClient() call sites updated to CreateClient(GoogleMapsTilesClientName):
      • GetSessionToken (session-token POST)
      • DownloadSingleTileAsync retry lambda (single-tile GET)
      • PerformDownloadAsync retry lambda (batch-tile GET)
    • Removed the two per-call httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(USER_AGENT); lines — the header is now set once at registration.
  • SatelliteProvider.Services.TileDownloader/TileDownloaderServiceCollectionExtensions.cs
    • Added services.AddHttpClient(GoogleMapsDownloaderV2.GoogleMapsTilesClientName, c => { c.DefaultRequestHeaders.UserAgent.ParseAdd(GoogleMapsDownloaderV2.UserAgent); c.Timeout = TimeSpan.FromSeconds(GoogleMapsDownloaderV2.DefaultHttpClientTimeoutSeconds); });.

Unchanged (deliberate)

  • SatelliteProvider.Api/Program.csbuilder.Services.AddHttpClient(); kept. See "Design note" above; cleanup deferred.
  • Per-call User-Agent setup is removed; the named client carries the header on every CreateClient(...) resolution.

Modified tests

  • SatelliteProvider.Tests/TileServiceTests.cs
    • Added Microsoft.Extensions.DependencyInjection using.
    • New TileDownloaderRegistrationTests.AddTileDownloader_RegistersNamedGoogleMapsTilesHttpClient_AZ374_AC1 — builds a ServiceCollection, calls AddTileDownloader(), resolves IHttpClientFactory, asks for "GoogleMapsTiles", asserts the returned client carries a Mozilla/5.0...-style User-Agent and a 100-second Timeout. Covers AC-1 directly and AC-2 transitively (the only consumer of CreateClient(GoogleMapsTilesClientName) is GoogleMapsDownloaderV2).

AC Test Coverage

AC Covered by
AC-1 (single registration with User-Agent + Timeout) AddTileDownloader_RegistersNamedGoogleMapsTilesHttpClient_AZ374_AC1
AC-2 (downloader uses CreateClient("GoogleMapsTiles") everywhere) Source-level: the only CreateClient( occurrences in GoogleMapsDownloaderV2.cs reference GoogleMapsTilesClientName. Behavioral: smoke tests GetTileByLatLon + region/route tile downloads succeed end-to-end against the real Google Maps API, exercising all three call sites (session token, single-tile, batch-tile).
AC-3 (tests stay green) scripts/run-tests.sh --smoke reports 175 unit + 5 smoke.

Test Run

Suite Result Count
Unit (SatelliteProvider.Tests) All passed 175 (was 174; +1 new test for the DI registration)
Smoke integration (Docker) All passed 5 scenarios

Code Review Verdict: PASS

Inline review covered:

  • Architecture: Named-client registration co-located with the consumer in AddTileDownloader(); no leakage into the WebApi entry point. SRP improvement over the task-spec recommendation, with rationale recorded above and verified against coderule.mdc.
  • Behavior preservation: User-Agent value byte-identical (Mozilla/5.0 (Windows NT 10.0; …)); timeout preserved at HttpClient's implicit default (100 s); retry/backoff unchanged; session-token / single-tile / batch-tile code paths all confirmed via the smoke tile-download scenarios.
  • AC coverage: 3/3 with at least one running test per AC; AC-2 also relies on the structural fact that there is no other CreateClient( in GoogleMapsDownloaderV2.
  • Code quality: SRP preserved; no narrative comments; consts named per C# conventions; A/A/A test pattern; no suppressed errors; argument validation unaffected.
  • Cross-batch consistency: extends the AZ-371 (C18 magic-numbers-to-config) theme by adding a third configuration-style constant cluster; consistent with the AZ-364 collaborator-extraction pattern (small, well-named extension surfaces); AZ-370 enums (batch 19) and AZ-373 MapsVersion drop (batch 20) untouched.

Findings: None.

Auto-Fix Attempts: 0

Stuck Agents: None

Cumulative review — K=3 trigger

Batches 19, 20, 21 have completed since the last cumulative review (cumulative_review_batches_16-18_cycle1_report.md). The K=3 trigger now fires. Cumulative review will be run as the next step (autodev sub_step cumulative-review), targeting the union of files changed in batches 1921.

Next Batch

After the cumulative review passes, Phase 4 continues with the remaining 7 tasks in todo/:

  • AZ-375 — C22 O(N) existing-tile lookup (2 SP, needs AZ-371 ✓)
  • AZ-376 — C23 delete unused FindExistingTileAsync (1 SP)
  • AZ-377 — C24 consolidate Earth-geometry constants (2 SP, needs AZ-371 ✓)
  • AZ-378 — C25 repo _logger fields (1 SP)
  • AZ-379 — C26 repo SELECT column-list constants (2 SP)
  • AZ-380 — C27 delete CalculatePolygonDiagonalDistance (1 SP)
  • AZ-372 — C19 dotnet format + analyzers + Coverlet (3 SP)