# Inventory API: rename body fields to OSM-style z/x/y

**Task**: AZ-794_inventory_field_rename_osm
**Name**: Rename inventory body fields tileZoom/tileX/tileY → z/x/y (OSM convention)
**Description**: Align the `POST /api/satellite/tiles/inventory` body shape with the URL-path slippy-map convention (`{z}/{x}/{y}`). Same coordinate concept is named two different ways inside the same API today; this task makes the body match the URL.
**Complexity**: 3 points (recommended; final call by parent-suite team)
**Dependencies**: — (coordinate release window with AZ-795 / AZ-796 to bundle the breaking changes)
**Component**: SatelliteProvider.Api + SatelliteProvider.Common (DTOs)
**Tracker**: AZ-794 (https://denyspopov.atlassian.net/browse/AZ-794)
**Epic**: — (related to AZ-795 input-validation epic via Jira "Relates" link)
**Originating ticket**: gps-denied-onboard AZ-777 Phase 1 (Jetson probe, 2026-05-22)

## Origin

Surfaced during gps-denied-onboard AZ-777 Phase 1 Jetson probing of the parent-suite `satellite-provider` service. The reviewing engineer noted that the inventory endpoint uses two different naming conventions for the same coordinate concept:

- URL: `GET /tiles/{z}/{x}/{y}` — OSM/XYZ-standard short names.
- Body: `{"tiles": [{"tileZoom":12,"tileX":2424,"tileY":1424}]}` — verbose .NET-style names.

Conformance to the URL convention end-to-end (both URL and body) aligns with 20 years of slippy-map ecosystem norms (OSM, Google, Mapbox, Bing, Leaflet, MapLibre) and removes the need for consumers to translate at the boundary. Jira AZ-794 is the authoritative spec; this file mirrors the in-workspace-only sections that the satellite-provider implementer will need.

## Problem

Same coordinate concept; two names; same API:
- URL path uses `z`, `x`, `y`.
- Request and response bodies use `tileZoom`, `tileX`, `tileY`.

Every consumer that thinks in slippy-map vocabulary has to translate at the boundary. Wire size is also ~3× larger than necessary on the field names (a 900-tile inventory request carries ~5 KB of `tileZoom`/`tileX`/`tileY` vs ~1.7 KB of `z`/`x`/`y`).

## Outcome

- `POST /api/satellite/tiles/inventory` request body uses `{"tiles": [{"z":...,"x":...,"y":...}]}` per tile entry.
- Response body uses `{"results": [{"z":...,"x":...,"y":...,"locationHash":...,"present":...,...}]}` per entry. All non-coord fields (`locationHash`, `present`, `id`, `capturedAt`, `source`, `flightId`, `resolutionMPerPx`) unchanged.
- OpenAPI / Swagger spec updated to match.
- Schema doc `_docs/02_document/contracts/api/tile-inventory.md` bumped (v1.x.0 → next major) with a Migration / Coexistence section.
- Integration tests updated.
- Release notes / migration guide entry naming AZ-794 as the breaking-rename owner.

## Scope

### Included

- DTOs for the inventory request + response — exact file path to be confirmed by the implementer (likely `SatelliteProvider.Common/DTO/TileInventory.cs` per AZ-505 spec).
- The MapPost handler / minimal-api endpoint registration in `SatelliteProvider.Api/Program.cs` (or wherever the inventory endpoint is wired today).
- `SatelliteProvider.IntegrationTests/TileInventoryTests.cs` — update payload builders + response assertions.
- `_docs/02_document/contracts/api/tile-inventory.md` — major version bump with Change Log entry naming this task.
- Release notes / migration guide.

### Excluded

- The `GET /tiles/{z}/{x}/{y}` endpoint — already uses the correct names; no change.
- Strict input validation — owned by AZ-796 (sibling under epic AZ-795).
- Other endpoint renames.
- Internal storage / query / repo-method names (`tile_zoom`, `tile_x`, `tile_y` DB columns) — wire-format change only.

## Acceptance Criteria

**AC-1: Request body uses short names**
Given a POST body `{"tiles":[{"z":12,"x":2424,"y":1424}]}` with valid JWT
When `POST /api/satellite/tiles/inventory` is called
Then HTTP 200 with `results[0].z == 12`, `results[0].x == 2424`, `results[0].y == 1424` and a deterministic non-zero `locationHash`.

**AC-2: Response body uses short names**
Given a successful inventory call
When the response is parsed
Then every `results[i]` object contains `z`, `x`, `y` keys (not `tileZoom`, `tileX`, `tileY`). All other fields (`locationHash`, `present`, `id`, `capturedAt`, `source`, `flightId`, `resolutionMPerPx`) are unchanged byte-for-byte from the pre-rename contract.

**AC-3: OpenAPI spec accuracy**
Given `/swagger/v1/swagger.json` (or equivalent)
When the InventoryRequest + InventoryEntry schemas are inspected
Then they declare `z`, `x`, `y` (not the old names) as the required coordinate properties.

**AC-4: Migration guidance documented**
Given the rename ships
Then `_docs/02_document/contracts/api/tile-inventory.md` is bumped to a new major version, the Change Log entry names AZ-794 and the breaking-rename, and a Migration / Coexistence section either (a) names the hard-switch release with the consumer-side bump coordinated, or (b) documents the accept-both transition window.

## Rollout — pick one

- **Option 1 — hard switch** (recommended while consumer count is small): rename atomically, bump API version, ship coordinated consumer update in the same release.
- **Option 2 — accept-both transition**: server accepts both `z` and `tileZoom` on input for one release; response always uses short names; deprecation notice in release notes; remove long names in next release.

## Constraints

- **Breaking change** — coordinate with all known consumers before shipping. Known consumer at filing time: `gps-denied-onboard` `HttpTileDownloader` in `src/gps_denied_onboard/components/c11_tile_manager/tile_downloader.py`. Parent-suite team to enumerate the full consumer set before deciding rollout cadence.
- **No internal storage rename** — DB columns (`tile_zoom`, `tile_x`, `tile_y`) stay as named. Wire-format change only; internal Postgres schema is out of scope.
- **Coordinate with AZ-795 / AZ-796** — if validation strictness ships in the same release as the rename, the validators must use the new short names from day one. Recommended ordering: ship AZ-794 first, then AZ-795 shared infra, then AZ-796.

## References

- Jira AZ-794: https://denyspopov.atlassian.net/browse/AZ-794
- Related: AZ-795 (validation epic), AZ-796 (inventory validation child)
- Originating discovery: gps-denied-onboard AZ-777 (Phase 1 Jetson probe, 2026-05-22)
- Current contract doc: `_docs/02_document/contracts/api/tile-inventory.md` v1.0.0
- Known consumer side: `gps-denied-onboard/src/gps_denied_onboard/components/c11_tile_manager/tile_downloader.py`
