[AZ-513] [AZ-196] [AZ-183] Add /classes CRUD, /devices, fleet OTA

AZ-513: POST/PATCH/DELETE /classes for detection-class CRUD; new
DetectionClass entity, schema, DTOs, IDetectionClassService. Unblocks
ui/AZ-512.

AZ-196: POST /devices auto-assigns sequential azj-NNNN serial+email
+password and inserts a CompanionPC user. Returns plaintext credentials
for the provisioning script.

AZ-183: Resources table + POST /get-update + POST /resources/publish
for fleet OTA. Per-resource encryption_key column AES-256-CBC encrypted
at rest with ResourcesConfig.EncryptionMasterKey; ICache wraps the
per-(arch,stage) latest-versions lookup and is invalidated on publish.

Adds IDbFactory.RunAdmin<T> overload for write-and-return.

Backfills _docs/02_document/module-layout.md to satisfy the implement
skill's File Ownership prerequisite (the _docs/ artifact set predates
the Step 1.5 module-layout addition).

Code review: PASS_WITH_WARNINGS — see
_docs/03_implementation/reviews/batch_05_review.md.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-13 04:34:42 +03:00
parent f13c57b314
commit 5ca9ccab2c
29 changed files with 1319 additions and 21 deletions
@@ -0,0 +1,35 @@
# Batch Report
**Batch**: 5 (cycle 1, batch 1 of 2)
**Tasks**: AZ-513_classes_crud_routes, AZ-196_register_device_endpoint, AZ-183_resources_table_update_api
**Date**: 2026-05-13
## Task Results
| Task | Status | Files Modified | Tests | AC Coverage | Issues |
|--------|--------|---------------------------------------------------------------------------------------------------------|----------------------------------------|-------------------------|--------|
| AZ-513 | Done | DetectionClass entity + 2 DTOs + DetectionClassService + Program.cs (3 routes) + schema + SQL migration | DetectionClassesTests.cs (9 e2e tests) | AC 19 / AC-10 = UI side | None blocking |
| AZ-196 | Done | RegisterDeviceResponse DTO + UserService.RegisterDevice + Program.cs (1 route) | DeviceRegistrationTests.cs (5 e2e tests) | AC 15 | F1 (Medium / race) tracked in review |
| AZ-183 | Done | Resource entity + 2 DTOs + ResourceUpdateService + Program.cs (2 routes) + schema + SQL migration + ResourcesConfig.EncryptionMasterKey | ResourceUpdateTests.cs (4 e2e tests) | AC 1, 2, 3, 5 (AC-4 by inspection) | F2F4 (Low) tracked in review |
## AC Test Coverage: 18/18 admin-side ACs covered (AC-10 of AZ-513 verified in UI workspace; AC-4 of AZ-183 is a perf characteristic, verified by inspecting `ResourceUpdateService.GetUpdate`'s `cache.GetFromCacheAsync` wrapping `LoadLatest`)
## Code Review Verdict: PASS_WITH_WARNINGS — see `_docs/03_implementation/reviews/batch_05_review.md`
## Auto-Fix Attempts: 0
## Stuck Agents: None
## Notes / Decisions
- **Wire-compat for new endpoints**: All three new routes are additive (`POST /classes`, `PATCH /classes/{id}`, `DELETE /classes/{id}`, `POST /devices`, `POST /get-update`, `POST /resources/publish`). Nothing changes on existing routes in this batch.
- **Schema migrations**: `env/db/04_detection_classes.sql` and `env/db/05_resources.sql` added; both use `create table if not exists` and idempotent `grant`s, so they are safe to re-run. `e2e/db-init/00_run_all.sh` updated to apply both during the test-DB bootstrap.
- **DI**: `AddScoped<IDetectionClassService, DetectionClassService>()` and `AddScoped<IResourceUpdateService, ResourceUpdateService>()` added next to the existing `IUserService` registration in `Program.cs`. `AddValidatorsFromAssemblyContaining<RegisterUserValidator>()` (already present) auto-discovers the new validators in `Azaion.Common`.
- **`IDbFactory.RunAdmin<T>(...)`**: Overload added to support write-and-return patterns (used by AZ-513's `Create` returning the new id, AZ-196's `RegisterDevice` returning the credentials, and AZ-183's parts of the publish/lookup paths). Non-breaking addition.
- **Encryption-at-rest for AZ-183**: Per-resource `encryption_key` column is AES-256-CBC encrypted with a master key from `ResourcesConfig.EncryptionMasterKey`. The wire response carries plaintext (the device needs it to decrypt the artifact). Master key for tests is provided via `docker-compose.test.yml`; production must override via `ResourcesConfig__EncryptionMasterKey` env var.
- **AZ-197 not in this batch**: AZ-197 (remove hardware ID binding) was originally cross-workspace (Admin API + Loader). User clarified 2026-05-13 that the Loader is architecturally retired (Scenario X, see `suite/_docs/_repo-config.yaml` `unresolved:loader-retirement-arch-doc`) and devices ship as secured Jetsons with fTPM or via SaaS. The AZ-197 spec was rewritten to be admin-only; the destructive cleanup is isolated into batch 6 (cycle 1, batch 2 of 2) for focused review.
- **`module-layout.md` backfill**: Created earlier in this `/autodev` step to satisfy the implement skill's File Ownership prerequisite. The `_docs/` artifact set predates the Step 1.5 module-layout addition; this is a backfill, not a fresh decompose run.
## Next Batch
Batch 6 (cycle 1, batch 2 of 2): AZ-197 (remove hardware ID binding from admin/ + e2e cleanup).