Files
admin/_docs/02_document/tests/traceability-matrix.md
T
Oleksandr Bezdieniezhnykh 3a925b9b0f
ci/woodpecker/push/01-test Pipeline failed
ci/woodpecker/push/02-build-push unknown status
refactor: remove obsolete resource download and installer endpoints
- Deleted the `POST /resources/get/{dataFolder?}` and `GET /resources/get-installer` endpoints as part of the architectural shift towards simplified resource management.
- Removed associated methods and configurations, including `ResourcesService.GetEncryptedResource`, `ResourcesService.GetInstaller`, and related properties in `ResourcesConfig`.
- Cleaned up environment variables and configuration files to reflect the removal of installer-related settings.
- Eliminated the `GetResourceRequest` DTO and its validator, along with the `WrongResourceName` error code.
- Updated documentation to clarify the changes in resource handling and the retirement of per-user file encryption.

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

12 KiB

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 (baseline) 19 19 0 100%
Acceptance Criteria (cycle 1) 24 24 0 100%
Acceptance Criteria (cycle 2) 6 6 0 100%
Restrictions 8 5 3 63%
Total 57 54 3 95%

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

Cycle 1 Additions (2026-05-13) — AZ-513, AZ-196, AZ-183, AZ-197

Appended during the existing-code cycle 1 Test-Spec Sync (autodev Step 12). Cycle 1 ACs are namespaced by their tracker ID to avoid colliding with the baseline AC-1..AC-19 numbering above.

AZ-513 — Detection Classes CRUD

AC ID Acceptance Criterion Test IDs Coverage
AZ-513 AC-1 POST /classes creates a class FT-P-14 Covered
AZ-513 AC-2 POST /classes requires ApiAdmin authorization FT-N-09 Covered
AZ-513 AC-3 PATCH /classes/{id} updates an existing class (full body) FT-P-15 Covered
AZ-513 AC-4 PATCH /classes/{id} accepts partial body (partial-merge) FT-P-16 Covered
AZ-513 AC-5 PATCH /classes/{id} returns 404 for unknown id FT-N-10 Covered
AZ-513 AC-6 PATCH /classes/{id} requires ApiAdmin authorization FT-N-11 Covered
AZ-513 AC-7 DELETE /classes/{id} removes a class FT-P-17 Covered
AZ-513 AC-8 DELETE /classes/{id} returns 404 for unknown id FT-N-12 Covered
AZ-513 AC-9 DELETE /classes/{id} requires ApiAdmin authorization FT-N-13 Covered
AZ-513 AC-10 UI add/delete/edit affordances work end-to-end Cross-workspace (ui/ e2e harness) — out of scope for this workspace

AZ-196 — Device Auto-Registration

AC ID Acceptance Criterion Test IDs Coverage
AZ-196 AC-1 First device gets serial azj-0000 (shape: serial / email / 32-hex password) FT-P-18 Covered
AZ-196 AC-2 Sequential numbering on subsequent calls FT-P-19 Covered
AZ-196 AC-3 Persisted user has Role=CompanionPC, IsEnabled=true FT-P-20 Covered (verified via successful login → role-gated behaviour)
AZ-196 AC-4 Returned plaintext password is hashed (SHA-384) in DB, not stored plaintext FT-P-20 Covered (verified via successful login round-trip)
AZ-196 AC-5 Requires ApiAdmin authorization FT-N-14 Covered

AZ-183 — Resources OTA Update Check (REVERTED post-cycle-1)

The OTA Update Check & Publish feature shipped in cycle 1 was reverted later the same day after the security audit (finding F-1: /get-update disclosed plaintext per-resource encryption keys to any authenticated caller; the OTA delivery model itself was deemed obsolete in the target architecture). The endpoints, service, entity, table, request DTOs, response DTO, cache key, master-key config field, and the e2e test class ResourceUpdateTests were all removed.

AC ID Acceptance Criterion Test IDs Status
AZ-183 AC-1 Resources table created with required columns Reverted — table dropped from migration set (env/db/05_resources.sql deleted)
AZ-183 AC-2 POST /get-update returns newer resources FT-P-21 Reverted — endpoint and test deleted
AZ-183 AC-3 POST /get-update returns empty when device already current FT-P-22 Reverted — endpoint and test deleted
AZ-183 AC-4 Memory cache avoids DB pressure under 2000-device polling Reverted — cache key removed
AZ-183 AC-5 Cache invalidated on CI/CD publish FT-P-23 Reverted — endpoint and test deleted

AZ-197 — Hardware-Binding Removal

AC ID Acceptance Criterion Test IDs Coverage
AZ-197 AC-1 Resource download works without Hardware field FT-P-09 / FT-P-10 (legacy bodies retained; wire shape now omits the field) Covered (e2e ResourceTests updated by AZ-197 batch 6)
AZ-197 AC-2 PUT /users/hardware/set and POST /resources/check return 404 FT-N-15 Covered
AZ-197 AC-3 Security.GetApiEncryptionKey signature simplified to (email, password) Internal signature — covered by Azaion.Test/SecurityTest unit tests, not blackbox
AZ-197 AC-4 HardwareBindingTests removed; no remaining test asserts code 40 / hardware-hash binding Build/CI invariant — verified by test-suite enumeration
AZ-197 AC-5 Resource calls in remaining tests do not send Hardware Build/CI invariant — verified by source review during AZ-197 batch 6
AZ-197 AC-6 ExceptionEnum no longer carries HardwareIdMismatch / BadHardware Build/CI invariant — verified by enum read
AZ-197 AC-7 dotnet build is clean (no new warnings) Build invariant
AZ-197 AC-8 Test suite passes (excluding deleted HardwareBindingTests) All e2e tests + Azaion.Test Covered by Step 11 Run Tests (48/48 e2e + 2/2 unit, 2026-05-13)

Obsoleted Baseline Entries (superseded by AZ-197)

The matrix rows below are kept for ID stability but no longer reflect production behaviour. They are superseded by the AZ-197 entries above and by FT-N-15 in blackbox-tests.md. Do NOT regenerate or delete these in cycle-update mode — wait for a full /test-spec rerun.

Legacy Matrix Row Status
AC-10 (First hardware check stores) Obsoleted by AZ-197 — endpoint removed
AC-11 (Subsequent hardware check validates) Obsoleted by AZ-197 — endpoint removed
AC-12 (Hardware mismatch returns code 40) Obsoleted by AZ-197 — ExceptionEnum value removed
AC-19 (Encryption key derived from email+password+hw) Partially obsoleted — derivation is now email + password only

Cycle 2 Cleanup (2026-05-14) — Obsolete Resource Endpoints Removed

The encrypted-download and installer-download endpoints were removed as obsolete. Affected matrix rows below are kept for ID stability but the underlying behaviour is gone; they are superseded by FT-N-16 in blackbox-tests.md.

Removed surface Endpoint(s) Affected legacy entries Status
Per-user encrypted resource download POST /resources/get/{dataFolder?} AC-14 (AES-256-CBC encryption), AC-15 (round-trip), AC-19 (key derivation), FT-P-09, FT-P-10 Reverted — endpoint deleted; Security.GetApiEncryptionKey / EncryptTo / DecryptTo and ResourcesService.GetEncryptedResource deleted; GetResourceRequest DTO deleted; e2e tests Encrypted_download_returns_octet_stream_and_non_empty_body and Encryption_round_trip_decrypt_matches_original_bytes deleted from ResourceTests.cs; e2e test Per_user_encryption_produces_distinct_ciphertext_for_same_file deleted from SecurityTests.cs; Azaion.Test/SecurityTest.cs deleted (and the now-empty Azaion.Test project removed from the solution).
Installer download (production + staging) GET /resources/get-installer, GET /resources/get-installer/stage AC-23 (latest installer), ResourcesConfig.SuiteInstallerFolder / SuiteStageInstallerFolder references Reverted — endpoints deleted; ResourcesService.GetInstaller deleted; both config properties removed from appsettings.json, .env.example, secrets/staging.public.env, secrets/production.public.env, and docker-compose.test.yml. No e2e tests had been written for these endpoints, so no tests required removal.
AC ID Acceptance Criterion Test IDs Coverage
Cycle-2 AC-1 POST /resources/get/{dataFolder?} returns 404 FT-N-16 Covered
Cycle-2 AC-2 GET /resources/get-installer returns 404 FT-N-16 Covered
Cycle-2 AC-3 GET /resources/get-installer/stage returns 404 FT-N-16 Covered
Cycle-2 AC-4 ExceptionEnum no longer carries WrongResourceName (50); the gap is preserved Build/CI invariant — verified by enum read
Cycle-2 AC-5 Azaion.Test project no longer in solution; build is clean Build invariant — dotnet build Azaion.AdminApi.sln clean post-cleanup
Cycle-2 AC-6 E2E suite passes after the test deletions above All e2e tests Covered by Step 11 Run Tests post-cleanup (2026-05-14)