# Traceability Matrix ## Acceptance Criteria Coverage | AC ID | Acceptance Criterion | Test IDs | Coverage | |-------|---------------------|----------|----------| | AC-1 | Valid login returns JWT | FT-P-01, NFT-PERF-01, NFT-RES-01, NFT-RES-LIM-04 | Covered | | AC-2 | Unknown email returns code 10 | FT-N-01 | Covered | | AC-3 | Wrong password returns code 30 | FT-N-02 | Covered | | AC-4 | JWT lifetime 4 hours | FT-P-03, NFT-SEC-04 | Covered | | AC-5 | Email min 8 chars | FT-P-02, FT-N-03 | Covered | | AC-6 | Email format validation | FT-P-02, FT-N-04 | Covered | | AC-7 | Password min 8 chars | FT-P-02, FT-N-08 | Covered | | AC-8 | Duplicate email returns code 20 | FT-N-07 | Covered | | AC-9 | Only ApiAdmin can manage users | FT-P-06, FT-P-07, FT-P-11, FT-P-12, FT-P-13, NFT-SEC-02, NFT-SEC-06 | Covered | | AC-10 | First hardware check stores | FT-P-04, NFT-RES-03 | Covered | | AC-11 | Subsequent hardware check validates | FT-P-05, NFT-RES-03 | Covered | | AC-12 | Hardware mismatch returns code 40 | FT-N-06 | Covered | | AC-13 | Max upload 200 MB | FT-P-08, NFT-RES-LIM-01, NFT-RES-LIM-02, NFT-PERF-03 | Covered | | AC-14 | AES-256-CBC encryption | FT-P-09, FT-P-10, NFT-PERF-02, NFT-PERF-03, NFT-RES-LIM-03 | Covered | | AC-15 | Encrypt-decrypt round-trip | FT-P-10 | Covered | | AC-16 | Empty file upload returns code 70 | FT-N-05 | Covered | | AC-17 | SHA-384 password hashing | NFT-SEC-03 | Covered | | AC-18 | All non-login endpoints require auth | FT-P-09, NFT-SEC-01, NFT-RES-02, NFT-RES-LIM-04 | Covered | | AC-19 | Encryption key derived from email+password+hw | FT-P-10, NFT-SEC-05 | Covered | ## Restrictions Coverage | Restriction ID | Restriction | Test IDs | Coverage | |---------------|-------------|----------|----------| | RESTRICT-SW-01 | .NET 10.0 runtime | All tests (implicit — Docker build uses .NET 10.0) | Covered | | RESTRICT-SW-02 | PostgreSQL database | All DB tests (implicit — docker-compose uses PostgreSQL) | Covered | | RESTRICT-SW-03 | Max request body 200 MB | NFT-RES-LIM-01, NFT-RES-LIM-02 | Covered | | RESTRICT-SW-04 | JWT HMAC-SHA256 signing | FT-P-03, NFT-SEC-04 | Covered | | RESTRICT-HW-01 | ARM64 target architecture | — | NOT COVERED — CI builds ARM64; tests run on dev x64 host | | RESTRICT-ENV-01 | Secrets via env vars | All tests (implicit — docker-compose passes env vars) | Covered | | RESTRICT-ENV-02 | CORS admin.azaion.com | — | NOT COVERED — CORS is browser-enforced, not testable at API level | | RESTRICT-OP-01 | Serilog logging | — | NOT COVERED — log output verification not in scope | ## Coverage Summary | Category | Total Items | Covered | Not Covered | Coverage % | |----------|-----------|---------|-------------|-----------| | Acceptance Criteria | 19 | 19 | 0 | 100% | | Restrictions | 8 | 5 | 3 | 63% | | **Total** | **27** | **24** | **3** | **89%** | ## Uncovered Items Analysis | Item | Reason Not Covered | Risk | Mitigation | |------|-------------------|------|-----------| | RESTRICT-HW-01 (ARM64) | Tests run on x64 dev/CI host; cross-architecture testing requires ARM hardware | Low — .NET runtime handles arch differences; no arch-specific code in application | CI builds ARM64 image; manual smoke test on target device | | RESTRICT-ENV-02 (CORS) | CORS is enforced by browsers, not by server-to-server HTTP calls | Low — CORS policy is declarative in Program.cs | Visual inspection of CORS configuration in code | | RESTRICT-OP-01 (Logging) | Log output format/content verification adds complexity without proportional value | Low — Serilog configuration is declarative | Code review of Serilog setup |