Files
satellite-provider/_docs/02_document/tests/traceability-matrix.md
T
Oleksandr Bezdieniezhnykh 98cdcd17c1 [AZ-487] [AZ-488] docs: cycle 2 test-spec sync
Append cycle 2 entries to test-spec artifacts (cycle-update mode):

* security-tests.md: SEC-05..SEC-09 (AZ-487 JWT 401/403/parity)
  + SEC-10..SEC-11 (AZ-488 permission + reject-detail leak hygiene).
* blackbox-tests.md: BT-13..BT-17 (UAV happy / mixed / multi-source
  coexistence / same-source UPSERT / rule-ordering) + BT-18 (existing
  endpoints parity with Bearer token).
* resource-limit-tests.md: RL-05..RL-07 (MaxBatchSize, per-item MaxBytes,
  Kestrel/Form envelope cap).
* performance-tests.md: untouched (PT-08 already landed with AZ-488 as
  Deferred — see _docs/_process_leftovers/2026-05-11_perf-pt07-harness).
* traceability-matrix.md: append AC rows for AZ-487 AC-1..AC-8 and
  AZ-488 AC-1..AC-10 + AC-7a..AC-7e; annotate "No authentication"
  restriction as superseded by AZ-487+AZ-488; add NFR rows (perf,
  security, reliability, compatibility) for both tasks; refresh totals
  (78 tests; 47/47 ACs; 8/8 restrictions).

Coverage shape: AZ-487 AC-7 (Swagger Authorize) and the perf NFRs are
recorded but not actively measured this commit (manual UI smoke +
deferred PT-08 harness, respectively).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 00:00:14 +03:00

11 KiB
Raw Blame History

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
AZ-487 AC-1 Anonymous request returns 401 from every authenticated endpoint SEC-05 (blackbox); JwtIntegrationTests.AnonymousRequest_*_Returns401 (integration)
AZ-487 AC-2 Expired token returns 401; no internal leak in body SEC-06 (blackbox); JwtIntegrationTests.ExpiredToken_Returns401 (integration)
AZ-487 AC-3 Tampered signature returns 401 SEC-07 (blackbox); JwtIntegrationTests.InvalidSignature_Returns401 (integration)
AZ-487 AC-4 Valid token reaches handler with identical response SEC-09, BT-18 (blackbox); JwtIntegrationTests.ValidToken_Returns200_OnHealthyEndpoint (integration)
AZ-487 AC-5 Startup fails on missing / short JWT_SECRET SEC-08 (behavioral); AuthenticationServiceCollectionExtensionsTests.AddSatelliteJwt_Throws* (unit)
AZ-487 AC-6 HttpContext.User exposes claims (sub, permissions, …) JwtTokenFactoryTests.Create_WithExtraClaims_PropagatesClaimsThroughValidation (unit) + indirect via AZ-488 AC-6 (live permission check)
AZ-487 AC-7 Swagger UI Authorize button works JwtIntegrationTests.SwaggerDocument_AdvertisesBearerSecurityScheme (integration; programmatic equivalent of UI flow) ◐ doc-verified
AZ-487 AC-8 All existing tests pass with attached test token Full scripts/run-tests.sh --full run (cycle 2 Step 11 — passed)
AZ-488 AC-1 Happy-path 1-item batch persists with source='uav' BT-13 (blackbox); UavUploadTests.HappyPathSingleItem_PersistsRow (integration)
AZ-488 AC-2 3-item mixed batch returns per-item results BT-14 (blackbox); UavUploadTests.MixedBatch_ReturnsPerItemResults (integration)
AZ-488 AC-3 UAV upload coexists with pre-seeded google_maps row BT-15 (blackbox); UavUploadTests.MultiSourceCoexistence_AZ484_Cycle2 (integration); reuses AZ-484 AC-1 + AC-2 invariants
AZ-488 AC-4 Same-source UPSERT keeps one source='uav' row BT-16 (blackbox); UavUploadTests.SameSourceUpsert_AZ484_Cycle2 (integration); reuses AZ-484 AC-3 invariant
AZ-488 AC-5 Unauthenticated upload returns 401 (covered by AZ-487) UavUploadTests.NoToken_Returns401 (integration); AZ-487 AC-1 row covers contract
AZ-488 AC-6 Authenticated request without GPS permission returns 403 SEC-10 (blackbox); UavUploadTests.ValidTokenWithoutGpsPermission_Returns403 (integration); PermissionsRequirementTests (unit)
AZ-488 AC-7a INVALID_FORMAT reject reason on wrong content-type or magic bytes UavTileQualityGateTests.Validate_NonJpegContentType_* and Validate_WrongMagicBytes_* (unit)
AZ-488 AC-7b SIZE_OUT_OF_BAND reject reason on bytes outside [MinBytes, MaxBytes] RL-06 (resource-limit); UavTileQualityGateTests.Validate_BytesBelowMin_* and Validate_BytesAboveMax_* (unit)
AZ-488 AC-7c WRONG_DIMENSIONS reject reason on non-256×256 images BT-14, BT-17 (blackbox); UavTileQualityGateTests.Validate_WrongDimensions_* (unit)
AZ-488 AC-7d CAPTURED_AT_FUTURE / CAPTURED_AT_TOO_OLD reject reasons UavTileQualityGateTests.Validate_CapturedAtFuture_* and Validate_CapturedAtTooOld_* (unit)
AZ-488 AC-7e IMAGE_TOO_UNIFORM reject reason on uniform / low-variance JPEGs UavTileQualityGateTests.Validate_UniformGreyImage_RejectsImageTooUniform (unit)
AZ-488 AC-7 (ordering) First-applicable rule wins (e.g. format-fail beats dimensions-fail) BT-17 (blackbox); UavTileQualityGateTests.Validate_MultipleViolations_* (unit)
AZ-488 AC-8 Oversized batch (> MaxBatchSize) returns 400 envelope error RL-05 (resource-limit); UavUploadTests.OversizedBatch_Returns400 (integration)
AZ-488 AC-9 Contract uav-tile-upload.md v1.0.0 frozen and matches implementation doc-state AC; verified by Step 13 (Update Docs) review
AZ-488 AC-10 All existing tests + new AZ-487/AZ-488 tests pass; no AZ-484 regression Full scripts/run-tests.sh --full run (cycle 2 Step 11 — passed)

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 → JWT (HS256) on every endpoint, GPS permission on UAV upload SEC-01..SEC-04 (input handling); SEC-05..SEC-09 (AZ-487 JWT layer); SEC-10..SEC-11 (AZ-488 permission + leak hygiene) ✓ (superseded by AZ-487 + AZ-488, cycle 2)

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
AZ-487 Performance — JWT validation < 1 ms overhead per request AZ-487 task spec § Non-Functional Requirements Not separately measured (HMAC-SHA256 + claims parse is sub-millisecond on any modern x86; no caching needed). Re-measure if PT-07 harness shows aggregate regression. ◐ recorded
AZ-487 Security — RequireSignedTokens, RequireExpirationTime, ClockSkew = 30 s, secret ≥ 32 bytes AZ-487 task spec § Non-Functional Requirements + Constraints AuthenticationServiceCollectionExtensionsTests.AddSatelliteJwt_ThrowsOnShortSecret (unit) + SEC-06/SEC-07 (blackbox)
AZ-487 Reliability — Fail-fast on missing / short JWT_SECRET at startup AZ-487 task spec § Non-Functional Requirements SEC-08 (behavioral) + unit AddSatelliteJwt_ThrowsOnMissingSecret
AZ-488 Performance — Per-item gate cost < 50 ms; p95 batch-of-10 < 2 s AZ-488 task spec § Non-Functional Requirements PT-08 (Deferred — harness reuses PT-07 work; tracked in _docs/_process_leftovers/2026-05-11_perf-pt07-harness.md). Active enforcement starts at cycle 2 Step 15. ◐ recorded (Deferred)
AZ-488 Reliability — File-first then DB row; per-item failures never fail the batch envelope (except 400/401/403) AZ-488 task spec § Non-Functional Requirements BT-14 (mixed-batch shows per-item isolation); UavTileUploadHandlerTests.*PersistAsync* (unit); reject reason STORAGE_FAILURE defined in contract for the orphan-row recovery path
AZ-488 Compatibility — Replaces 501 stub; coexists with AZ-484 tile-storage v1.0.0 contract on the write side AZ-488 task spec § Non-Functional Requirements + Contract StubAndErrorContractTests updated to drop the stub-501 expectation; BT-15 + BT-16 validate the AZ-484 invariants under live UAV writes
AZ-488 Security — Reject details never leak server internals; integer-only file-path construction AZ-488 task spec § Non-Functional Requirements + Risk 2 SEC-11 (blackbox); UavTileFilePathTests (unit)

Coverage Summary

Category Total Tests ACs Covered Restrictions Covered
Blackbox (positive) 12 19/22
Blackbox (negative) 5
Performance 8 4 1
Resilience 6 4 3
Security 11 9 (AZ-487 AC-1..AC-7, AZ-488 AC-6, leak-hygiene NFR) 1 (AZ-487 supersedes "No authentication")
Resource Limits 7 5 4
Cycle 1 — AZ-484 (integration + unit) 6 7/7
Cycle 2 — AZ-487 (integration + unit + behavioral) 4 integration + 3 unit + 1 behavioral 8/8
Cycle 2 — AZ-488 (integration + unit + blackbox) 7 integration + 14 unit + 6 blackbox 10/10
Total 78 47/47 (100%) 8/8 (100%)

Coverage shape notes (Cycle 2):

  • AZ-487 AC-7 (Swagger UI Authorize) is verified programmatically (SwaggerDocument_AdvertisesBearerSecurityScheme) rather than via a real UI flow; marked ◐ doc-verified. The end-to-end browser-UI Authorize-button check remains a manual smoke before deploy.
  • AZ-487 perf NFR (< 1 ms JWT overhead) and AZ-488 perf NFR (PT-08) are ◐ recorded; active enforcement deferred to cycle 2 Step 15 (Performance Test). Both depend on the shared PT-07 harness expansion (_docs/_process_leftovers/2026-05-11_perf-pt07-harness.md).