# Refactor: move hardcoded magic numbers to ProcessingConfig / MapConfig

**Task**: AZ-371_refactor_magic_numbers_to_config
**Name**: Promote operational constants to config + forward CT in GetTileByLatLon
**Description**: Add config-bound replacements for the magic timeouts, intervals, tolerances, retry delays, and tile-size constants. Forward `CancellationToken` from `Program.cs:GetTileByLatLon` into the downloader (LF-2).
**Complexity**: 3 points
**Dependencies**: None
**Component**: Common + Services.* (all)
**Tracker**: AZ-371
**Epic**: AZ-350

## Problem

Operational levers are baked into source: `RegionService.cs:94` (5 min timeout), `RouteService.cs:15` (200 m point spacing), `RouteProcessingService.cs:22` (5 s polling), `RouteService.cs:154` + `GoogleMapsDownloaderV2.cs:252` (`0.0001` lat/lon tolerance), `GoogleMapsDownloaderV2.cs:18-21` (TILE_SIZE_PIXELS, MAX_RETRY_DELAY_SECONDS, BASE_RETRY_DELAY_SECONDS, ALLOWED_ZOOM_LEVELS), `TileService.cs:152` (TileSizePixels = 256). Plus `Program.cs:GetTileByLatLon` (line 150) does not forward its `CancellationToken` to `DownloadAndStoreSingleTileAsync` (LF-2).

## Outcome

- New config keys: `ProcessingConfig.RegionProcessingTimeout`, `ProcessingConfig.RouteProcessingPollInterval`, `ProcessingConfig.MaxRoutePointSpacingMeters`, `ProcessingConfig.LatLonTolerance`, `MapConfig.TileSizePixels`, `MapConfig.AllowedZoomLevels`, `MapConfig.RetryBaseDelaySeconds`, `MapConfig.RetryMaxDelaySeconds`.
- All listed magic numbers replaced by config-bound values; defaults match current literals.
- `GetTileByLatLon` request cancellation flows into the downloader.
- 37 unit + 5 smoke tests stay green.

## Scope

### Included
- Extend `ProcessingConfig` and `MapConfig` (or equivalent options classes) with the new keys and defaults.
- Update `appsettings.json` and `appsettings.Development.json` with the new keys (with the current literal values as defaults).
- Replace the magic-number sites with `_processingConfig.<Key>` / `_mapConfig.<Key>` reads.
- Forward `CancellationToken ct` in `Program.cs:GetTileByLatLon` into `DownloadAndStoreSingleTileAsync(..., ct)`.

### Excluded
- Changing default values (must match current literals).
- Refactoring HTTP retry policy beyond surfacing the delay constants.

## Acceptance Criteria

**AC-1: All listed magic numbers moved to config**
Given the post-refactor source
When grepped for the literal values `5*60*1000`, `200`, `5000`, `0.0001`, `256` in service code
Then matches are confined to config defaults / `MapConfig.cs` / `ProcessingConfig.cs`.

**AC-2: Defaults preserve behavior**
Given the post-refactor build with no overrides
When `scripts/run-tests.sh --smoke` runs
Then all 37 unit + 5 smoke scenarios pass with no observable behavior change.

**AC-3: Cancellation flows through GetTileByLatLon**
Given a `GET /api/satellite/tiles/latlon` request
When the client cancels mid-flight
Then the downloader observes the cancellation and aborts the in-progress download.

## Constraints

- Default values must match current literals exactly.
- No new public API surface.

## Risks & Mitigation

**Risk 1: `LatLonTolerance` is consumed by both C18 and C22**
- *Risk*: ordering — C22 needs `LatLonTolerance` to exist as config.
- *Mitigation*: C22 declares C18 as a dependency.

**Risk 2: forwarding CT may surface previously-hidden hangs**
- *Risk*: tests that assumed the request runs to completion despite client cancel may fail.
- *Mitigation*: smoke tests don't currently rely on this; investigate any new failures during implementation.

Full change entry: `_docs/04_refactoring/03-code-quality-refactoring/list-of-changes.md` (C18).
