# Traceability Matrix ## Acceptance Criteria → Test Mapping | AC | Description | Tests | Coverage | |----|-------------|-------|----------| | T1 | Tiles cached, not re-downloaded | BT-02 | ✓ | | T2 | Concurrent download limit | RS-05, RL-03 | ✓ | | T3 | Tile stored with correct path | BT-01 | ✓ | | T4 | Tile metadata persisted | BT-01 | ✓ | | R1 | Region state transitions | BT-03, BT-04, BT-05 | ✓ | | R2 | CSV manifest generated | BT-03, BT-04, BT-05 | ✓ | | R3 | Summary file generated | BT-03, BT-04, BT-05 | ✓ | | R4 | Stitched image when requested | BT-05 | ✓ | | R5 | Stitched image valid content | BT-05 | ✓ | | R6 | Region processing bounded | RL-04 | ✓ | | RT1 | Points interpolated at ~200m | BT-06 | ✓ | | RT2 | Point types correctly assigned | BT-06 | ✓ | | RT3 | Total distance calculated | BT-06 | ✓ | | RT4 | Geofence filtering applied | BT-11 | ✓ | | RT5 | ZIP ≤ 50 MB | BT-09, RL-01 | ✓ | | RT6 | Route map stitched | BT-08, BT-10, BT-12 | ✓ | | A1 | Region request returns immediately | BT-03 | ✓ | | A2 | Status endpoint reflects state | BT-03, BT-07 | ✓ | | A3 | Route returns computed metadata | BT-06 | ✓ | | S1 | Migrations run on startup | RS-02 | ✓ | | S2 | Queue rejects when full | RS-04, RL-02 | ✓ | | S3 | Failed regions marked failed | RS-03 | ✓ | | AZ-484 AC-1 | Schema accepts source + captured_at; multi-source rows coexist under 5-col unique index | `MultiSourceInsertCoexistsUnderNewIndex_AZ484_AC1`, `NewUniqueConstraintIncludesSourceColumn_AZ484_AC1` (integration) | ✓ | | AZ-484 AC-2 | Read returns most-recent across sources | `MostRecentAcrossSourcesSelection_AZ484_AC2` (integration) | ✓ | | AZ-484 AC-3 | Same-source UPSERT collapses to one row with refreshed captured_at | `SameSourceUpsertReplacesPreviousRow_AZ484_AC3` (integration) | ✓ | | AZ-484 AC-4 | Migration 013 backfill leaves no orphans (count preserved, source='google_maps', captured_at=created_at) | `BackfillUpdateAssignsGoogleMapsAndCapturedAt_AZ484_AC4` (integration) | ✓ | | AZ-484 AC-5 | Google Maps download path stamps Source='google_maps' (wire) + CapturedAt UTC | `BuildTileEntity_SetsGoogleMapsSourceAndUtcCapturedAt_AZ484_AC5` (unit) | ✓ | | AZ-484 AC-6 | Existing region/route flows unchanged post-T1 (200 unit + smoke baseline preserved) | Full unit suite (213 tests) + integration smoke scenarios BT-01..BT-12 | ✓ | | AZ-484 AC-7 | Vision + contract docs amended (architecture.md, glossary.md, module-layout.md, tile-storage.md frozen v1.0.0) | doc-state AC; verified by `monorepo-document` reviews | ✓ | ## Restrictions → Test Mapping | Restriction | Tests | Coverage | |-------------|-------|----------| | .NET 8.0 runtime | All (via Docker image) | ✓ | | PostgreSQL 16 | All (via docker-compose) | ✓ | | Single instance | PT-05 (concurrent regions on one instance) | ✓ | | Max 4 concurrent downloads | RS-05, RL-03 | ✓ | | Max 20 concurrent regions | RL-04 | ✓ | | Queue capacity 1000 | RS-04, RL-02 | ✓ | | Max ZIP 50 MB | RL-01 | ✓ | | No authentication | SEC-01 through SEC-04 (all requests accepted without auth) | ✓ | ## NFRs → Test Mapping | NFR | Source | Tests | Coverage | |-----|--------|-------|----------| | AZ-484 Perf — `GetTilesByRegionAsync` p95 ≤ 1.10 × pre-AZ-484 baseline | AZ-484 task spec § Non-Functional Requirements | PT-07 (recorded; active perf comparison deferred to Step 15) | ◐ recorded | | AZ-484 Compatibility — no public HTTP response field added/removed; vestigial `maps_version`/`version` columns preserved (nullable) | AZ-484 task spec § Non-Functional Requirements | Existing integration suite (no API contract change observable); BT-01 / region status responses verify response shape | ✓ | ## Coverage Summary | Category | Total Tests | ACs Covered | Restrictions Covered | |----------|-------------|-------------|---------------------| | Blackbox (positive) | 12 | 19/22 | — | | Blackbox (negative) | 5 | — | — | | Performance | 6 | 2 | 1 | | Resilience | 6 | 4 | 3 | | Security | 4 | — | 1 | | Resource Limits | 4 | 3 | 4 | | Cycle 1 — AZ-484 (integration + unit) | 6 | 7/7 | — | | **Total** | **43** | **29/29 (100%)** | **8/8 (100%)** |