# Refactor: decompose RouteService.CreateRouteAsync 165-LOC method

**Task**: AZ-365_refactor_decompose_route_create_method
**Name**: Split CreateRouteAsync into validator + builder + grid + mapper
**Description**: Extract `RouteValidator`, `RoutePointGraphBuilder`, `GeofenceGridCalculator`, and `RouteResponseMapper` from `RouteService.CreateRouteAsync`.
**Complexity**: 5 points
**Dependencies**: None
**Component**: Services.RouteManagement
**Tracker**: AZ-365
**Epic**: AZ-350

## Problem

`SatelliteProvider.Services.RouteManagement/RouteService.cs:27-211` is a 165-LOC method that does input validation (4 separate rules, ~25 LOC of nested `if` chains), point-graph construction with `GeoUtils.CalculateIntermediatePoints`, route entity persistence, route-points persistence, geofence polygon validation, geofence grid generation, geofence region requests, and response mapping. Five distinct responsibilities in one method.

## Outcome

- `CreateRouteAsync` is reduced to orchestration of the four extracted helpers (~30-50 LOC).
- Validation aggregates errors instead of short-circuiting on the first.
- Each helper is unit-testable in isolation.
- 37 unit + 5 smoke tests stay green.

## Scope

### Included
- Extract `RouteValidator` (all `ArgumentException`-throwing checks; aggregates errors instead of short-circuiting).
- Extract `RoutePointGraphBuilder` (interpolation + sequence numbering — pure).
- Extract `GeofenceGridCalculator` (NW/SE → list of region centers — promote the existing private method).
- Extract `RouteResponseMapper` (entity → DTO; eliminates duplication with `GetRouteAsync`).
- Add unit tests for each helper.

### Excluded
- Changing the response shape.
- Changing the persistence calls.
- Changing the geofence semantics.

## Acceptance Criteria

**AC-1: CreateRouteAsync is now an orchestrator**
Given the post-refactor source
When `CreateRouteAsync` is inspected
Then it is reduced to ~30-50 LOC of `_validator.Validate(...)`, `_pointGraphBuilder.Build(...)`, `_geofenceGridCalculator.GenerateRegions(...)`, `_responseMapper.Map(...)` calls (or equivalent).

**AC-2: Validation aggregates errors**
Given an input with multiple validation failures
When validated
Then all failures are collected and surfaced as a single 400 response (still typed as `ArgumentException` or a typed `ValidationException`).

**AC-3: Same persistence + same response**
Given any input that succeeds today
When the post-refactor code runs
Then the same DB rows are created and the same response shape is returned.

**AC-4: Tests stay green**
Given the post-refactor build
When `scripts/run-tests.sh --smoke` runs
Then all 37 unit + 5 smoke scenarios pass; `RouteServiceTests` is unchanged.

## Constraints

- Same persistence calls.
- Same response shape (no DTO change).
- 400 status preserved for validation failures.

## Risks & Mitigation

**Risk 1: aggregated validation surfaces multiple errors but tests assert on first**
- *Risk*: existing tests may assert on a specific single-error message.
- *Mitigation*: update test assertions to allow a list of errors.

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