# Cycle 7 — Documentation Ripple Log

**Cycle**: 7 (AZ-794 z/x/y rename + AZ-795 strict-validation epic + AZ-796 inventory-endpoint validation)
**Generated by**: `/document` skill (task mode) during autodev Step 13
**Resolution method**: `Grep --type cs` against every new or changed symbol introduced by the three tasks. C# `using`-based import analysis on `TileCoord` (renamed fields + `[JsonRequired]`), `InventoryRequestValidator`, `ValidationEndpointFilter<T>`, `GlobalExceptionHandler`, `GlobalValidatorConfig`, plus `ProblemDetailsAssertions` and `ValidatorTestModuleInitializer` in the test projects. No static-analyzer (NDepend, etc.) was used — the new surface is shallow and lives almost entirely behind `Program.cs` + the two new test files, so the literal usage scan is exhaustive.

## Directly-changed source files (cycle 7)

- `SatelliteProvider.Common/DTO/TileInventory.cs` (AZ-794, modified) — `TileCoord` properties renamed `TileZoom/TileX/TileY` → `Z/X/Y` with `[JsonRequired]` on each; `TileInventoryEntry` echo fields renamed in lockstep. Wire field names are `z`/`x`/`y` per the camelCase resolver.
- `SatelliteProvider.Api/Program.cs` (AZ-795 + AZ-796, modified) —
  - `ConfigureHttpJsonOptions(o => o.SerializerOptions.UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow)` (AZ-795).
  - `AddProblemDetails(...)` global ProblemDetails configurator (AZ-795).
  - `AddExceptionHandler<GlobalExceptionHandler>()` + `UseExceptionHandler()` middleware order (AZ-795).
  - `AddValidatorsFromAssemblyContaining<Program>()` + `GlobalValidatorConfig.ApplyOnce()` at startup (AZ-795 + AZ-796).
  - `.WithValidation<TileInventoryRequest>()` on the `MapPost("/api/satellite/tiles/inventory", …)` builder (AZ-796).
  - Endpoint summary / description bumped to reference `tile-inventory.md` v2.0.0 + `error-shape.md` v1.0.0.
- `SatelliteProvider.Api/Validators/InventoryRequestValidator.cs` (AZ-796, **new**) — `AbstractValidator<TileInventoryRequest>` + nested `TileCoordValidator` with 9 rules (XOR, per-array cap, Z/X/Y ranges).
- `SatelliteProvider.Api/Validators/ValidationEndpointFilter.cs` (AZ-795, **new**) — generic `IEndpointFilter<T>` that runs the registered `IValidator<T>` and emits `Results.ValidationProblem(...)` on failure.
- `SatelliteProvider.Api/Validators/ValidationEndpointFilterExtensions.cs` (AZ-795, **new**) — opt-in `RouteHandlerBuilder.WithValidation<T>()` extension; intentionally orthogonal to per-endpoint authorization configuration.
- `SatelliteProvider.Api/Validators/GlobalValidatorConfig.cs` (AZ-795 + AZ-796, **new**) — idempotent `ApplyOnce()` configures FluentValidation's global `PropertyNameResolver` to camelCase (`tiles[0].z` instead of `Tiles[0].Z`) per `error-shape.md` Inv-4. Called from `Program.cs` and from the unit-test assembly's `[ModuleInitializer]`.
- `SatelliteProvider.Api/GlobalExceptionHandler.cs` (AZ-795, **new**) — `IExceptionHandler` that intercepts `BadHttpRequestException(JsonException)` (the System.Text.Json strict-parse path: unknown fields, `[JsonRequired]` violations, type mismatches) and emits the same `ValidationProblemDetails` shape that FluentValidation produces. 5xx paths pass through with sanitised body + correlation id (continuation of the AZ-353 contract).
- `_docs/02_document/contracts/api/error-shape.md` (AZ-795, **new**) — v1.0.0 uniform error-body contract. Single source of truth for the `ValidationProblemDetails` wire shape across both layers and across all future child tickets of the AZ-795 epic.
- `_docs/02_document/contracts/api/tile-inventory.md` (AZ-794 + AZ-796, modified) — bumped to v2.0.0; documents the 9 validation rules + the `z/x/y` rename; `Producer task` block extended to credit AZ-505 + AZ-794 + AZ-796.
- `SatelliteProvider.Tests/Validators/InventoryRequestValidatorTests.cs` (AZ-796, **new**) — 16 unit tests against the validator via `TestValidate(...)`.
- `SatelliteProvider.Tests/TestSupport/ValidatorTestModuleInitializer.cs` (AZ-795, **new**) — calls `GlobalValidatorConfig.ApplyOnce()` at test-assembly load.
- `SatelliteProvider.IntegrationTests/ProblemDetailsAssertions.cs` (AZ-795, **new**) — shared response-shape helper consumed by every future per-endpoint validation test.
- `SatelliteProvider.IntegrationTests/TileInventoryValidationTests.cs` (AZ-796, **new**) — 16 end-to-end tests; one per validation rule (with sub-cases) plus a happy path.
- `SatelliteProvider.IntegrationTests/TileInventoryTests.cs` (AZ-794, modified) — updated `tileZoom/tileX/tileY` JSON payloads to `z/x/y`; reduced the synthetic x/y values to stay inside the slippy-map bounds enforced by `TileCoordValidator`.
- `SatelliteProvider.IntegrationTests/IdempotentPostTests.cs` (AZ-795, modified) — route-point payload PascalCase → camelCase (`lat`/`lon`) because the post-cycle-7 strict deserializer no longer silently drops the wrong field names that the test had been sending pre-cycle 7.
- `scripts/probe_inventory_validation.sh` (AZ-796, **new**) — manual probe script; exercises each failure mode end-to-end and captures responses for change-review evidence.

## Importer scan results

| Symbol | Importer count | Importer files | Component touched |
|--------|----------------|----------------|-------------------|
| `TileCoord.Z` / `TileCoord.X` / `TileCoord.Y` (renamed properties; wire names `z`/`x`/`y`) | 5 | `TileService.cs` (`Uuidv5.LocationHashForTile`), `TileInventoryTests.cs`, `TileInventoryValidationTests.cs`, `InventoryRequestValidatorTests.cs`, `TileInventory.cs` self-references in `TileInventoryEntry` | TileDownloader (production), Tests (unit + integration) |
| `[JsonRequired]` on `TileCoord.Z/X/Y` | n/a | enforced at runtime by `System.Text.Json` + caught by `GlobalExceptionHandler` (no compile-time consumer) | WebApi (deserializer + handler) |
| `InventoryRequestValidator` / `TileCoordValidator` | 3 | `Program.cs` (assembly-scan registration via `AddValidatorsFromAssemblyContaining<Program>()`), `InventoryRequestValidatorTests.cs`, `TileInventoryValidationTests.cs` (indirect through the running API) | WebApi (production), Tests (unit + integration) |
| `ValidationEndpointFilter<T>` / `WithValidation<T>()` | 1 (current) + N-future | `Program.cs` (`MapPost("/api/satellite/tiles/inventory", …).WithValidation<TileInventoryRequest>()`) | WebApi |
| `GlobalValidatorConfig.ApplyOnce` | 2 | `Program.cs` (production), `ValidatorTestModuleInitializer.cs` (unit-test assembly load) | WebApi, Tests (unit) |
| `GlobalExceptionHandler` | 1 | `Program.cs` (DI registration + middleware order) | WebApi |
| `ProblemDetailsAssertions.AssertValidationProblem` | 1 (current) + N-future | `TileInventoryValidationTests.cs`; designed to be reused by every future per-endpoint child task under AZ-795 | Tests (integration) |
| `FluentValidation` package (12.0.0) | 4 | `SatelliteProvider.Api.csproj`, `SatelliteProvider.Tests.csproj`, `InventoryRequestValidator.cs`, `InventoryRequestValidatorTests.cs` | WebApi, Tests (unit) |

## Doc refresh decisions

All importers land inside components that already received targeted updates during Step 10 (Implement) and this Step 13:

- **WebApi (`Program.cs`)** — updated `_docs/02_document/modules/api_program.md` with the new endpoint description, the new `Api/Validators` section (filter + extensions + validator + global config), the new `Api/GlobalExceptionHandler` section, expanded DI registration (ProblemDetails + GlobalExceptionHandler + strict JSON + FluentValidation), and the new dependency entries.
- **Common (DTOs)** — updated `_docs/02_document/modules/common_dtos.md`: `TileCoord` now documents the rename + `[JsonRequired]` markers + ValidationProblemDetails fallout; `TileInventoryRequest` documents the XOR enforcement by `InventoryRequestValidator`; `TileInventoryEntry` documents the rename echo; `TileInventoryLimits` documents the validator as the enforcer.
- **Validators (new subfolder)** — captured under `module-layout.md` with two new entries:
  - `Api/Validators/{InventoryRequestValidator,TileCoordValidator,ValidationEndpointFilter,ValidationEndpointFilterExtensions,GlobalValidatorConfig}`.
  - `Api/GlobalExceptionHandler`.
- **Tests (unit)** — updated `_docs/02_document/modules/tests_unit.md` with the new "AZ-795 + AZ-796 — strict inventory validation (cycle 7)" subsection, the new `[ModuleInitializer]` helper, the new FluentValidation/TestHelper NuGet entry, and the cycle 7 unit-suite totals (311 tests).
- **Tests (integration)** — updated `_docs/02_document/modules/tests_integration.md`: new `TileInventoryValidationTests` entry, new `ProblemDetailsAssertions` helper entry, cycle-7 stability note on `TileInventoryTests`, and the cycle-7 fix on `IdempotentPostTests` (payload rename forced by strict deserializer).

System-level docs also updated this pass:

- `architecture.md` — already carries the new "§ 9 Input Validation (AZ-795)" section (was added during the implementation phase along with the validator coverage table). No further changes needed; the AZ-794 wire-format rename is captured at the inventory-contract level rather than in architecture prose.
- `system-flows.md` — F8 flow header updated to credit cycle 7; sequence diagram annotated with the two new validation gates (deserializer + filter); Validation Surface table expanded from 4 rows to 13 rows covering every failure mode from `error-shape.md`.
- `glossary.md` — `Tile Inventory` entry updated to v2.0.0 wire shape + cite the cycle-7 validator; added three new entries: `Validation Problem Details`, `FluentValidation`, `Unmapped Member Handling`.
- `module-layout.md` — Last Updated bumped + cycle-7 changelog line prepended.
- `tests/blackbox-tests.md` and `tests/traceability-matrix.md` — updated during Step 12 (Test-Spec Sync): BT-27 added + 12 AC rows added (AZ-794 AC-1..AC-4 + AZ-795 epic-level + AZ-796 AC-1..AC-7) + Coverage Summary refresh.

## No-ripple components

These components were NOT touched by cycle-7 changes and require no doc update:

- **DataAccess** — no schema or repository signature changes in cycle 7. The cycle-6 `tiles_leaflet_path` covering index and the cycle-5 identity columns are unaffected by the wire-format rename or by the new validators.
- **TileDownloader (`TileService.GetInventoryAsync`)** — the algorithm is unchanged: it still computes `Uuidv5.LocationHashForTile(z, x, y)` per coord. Only the *property names* on the DTO changed (`TileZoom` → `Z`, etc.); the value contract is identical.
- **RegionProcessing / RouteManagement** — no imports against cycle-7 symbols.
- **DataAccess migrations** — no new migration in cycle 7; the existing identity columns and indices already carry the production load.

## Parse-failure / heuristic notes

None — every symbol resolved via direct `Grep --type cs`. No fallback heuristic was needed. The cycle 7 surface is intentionally narrow (3 tasks, all WebApi-layer concerns) which keeps the ripple log short.

## AZ-795 epic posture

The `architecture.md` § 9 table classifies all other public endpoints as `partial` and tags them as "future AZ-795 child" — the epic remains open. Cycle 7 lands the shared infrastructure + the first per-endpoint application (AZ-796). Subsequent child tickets will reuse `ValidationEndpointFilter<T>`, `ProblemDetailsAssertions`, and the `error-shape.md` contract without adding new infrastructure.
