[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
+82
View File
@@ -0,0 +1,82 @@
# Module Layout
**Language**: csharp
**Layout Convention**: solution-flat (legacy — pre-`src/` convention)
**Root**: `./` (csproj folders sit at workspace root)
**Last Updated**: 2026-05-13
## Layout Rules
1. This admin/ workspace is one **deployable** (the `Azaion.AdminApi` HTTP service) split across four production csproj projects + one e2e test csproj: `Azaion.AdminApi`, `Azaion.Services`, `Azaion.Common`, `Azaion.Test`, `e2e/Azaion.E2E`.
2. Existing task specs (`_docs/02_tasks/*/AZ-*.md`) all use `Component: Admin API` as a single coarse identifier covering this entire workspace. The Per-Component Mapping below honors that convention rather than rewriting every task spec.
3. The conceptual sub-components documented in `_docs/02_document/components/01_data_layer..05_admin_api/` are **read-time** documentation aids, not write-time ownership boundaries. They are listed under "Conceptual Sub-Components" below for reference only.
4. Public API surface = the namespaces / interfaces exposed across csproj boundaries (`I*Service` interfaces in `Azaion.Services`, request DTOs in `Azaion.Common/Requests/`, entities in `Azaion.Common/Entities/`).
5. Tests live in `Azaion.Test/` (in-process unit/integration) and `e2e/Azaion.E2E/` (HTTP black-box). Production code never imports from either.
## Per-Component Mapping
### Component: Admin API
- **Epic**: AZ-181 (and any other admin-API epic, e.g. AZ-509 for the Detection Classes feature)
- **Directory**: workspace root (multi-csproj, see below)
- **Owns (exclusive write during implementation)**:
- `Azaion.AdminApi/**`
- `Azaion.Services/**`
- `Azaion.Common/**`
- `Azaion.Test/**`
- `e2e/Azaion.E2E/**` (xUnit/HttpClient-based black-box tests)
- `e2e/db-init/**` (test-DB seed/init scripts consumed by the e2e harness)
- `docker.test/**` (test fixture / schema-init helpers used by `Azaion.Test`)
- `docker-compose.test.yml`
- **Public API** (visible to other csprojs within the workspace):
- `Azaion.Services/I*Service.cs` interfaces (UserService, AuthService, ResourcesService, …)
- `Azaion.Services/Security.cs`, `Azaion.Services/Cache.cs` (used by `Azaion.AdminApi/Program.cs`)
- `Azaion.Common/Requests/*` request DTOs
- `Azaion.Common/Entities/*` linq2db entities
- `Azaion.Common/Database/*` `IDbFactory` + connection helpers
- `Azaion.Common/Configs/*` strongly-typed config records
- `Azaion.Common/Extensions/*` extension methods
- `Azaion.Common/BusinessException.cs`
- `Azaion.AdminApi/Program.cs` (composition root + minimal-API endpoints)
- `Azaion.AdminApi/BusinessExceptionHandler.cs`
- **Internal (do NOT import across csproj boundaries)**:
- private/internal members within each csproj (default C# visibility rules apply)
- `Azaion.AdminApi/appsettings*.json` (loaded by the host, not imported)
- `e2e/Azaion.E2E/Helpers/*` (test-only helpers, never imported by production)
- **Imports from**: (none — this is the only deployable in the workspace; the Loader is architecturally retired per `suite/_docs/_repo-config.yaml` `unresolved:loader-retirement-arch-doc`)
- **Consumed by**: HTTP clients (UI workspace, edge services on secured Jetson, SaaS browser sessions) — out of process
## Conceptual Sub-Components (documentation only — NOT ownership boundaries)
These come from `_docs/02_document/components/` and exist for reading the codebase, not for assigning task ownership. A single task may legitimately touch multiple sub-components within the `Admin API` umbrella.
| # | Sub-component | Primary file locations |
|---|----------------------|------------------------|
| 1 | Data Layer | `Azaion.Common/Database/`, `Azaion.Common/Configs/`, `Azaion.Common/Entities/` |
| 2 | User Management | `Azaion.Services/UserService.cs`, `Azaion.Common/Requests/{Create,Update,SetPassword,…}UserRequest.cs` |
| 3 | Auth & Security | `Azaion.Services/AuthService.cs`, `Azaion.Services/Security.cs`, `Azaion.Services/Cache.cs` |
| 4 | Resource Management | `Azaion.Services/ResourcesService.cs`, `Azaion.Common/Requests/{GetResource,CheckResources,…}.cs` |
| 5 | Admin API (HTTP) | `Azaion.AdminApi/Program.cs`, `Azaion.AdminApi/BusinessExceptionHandler.cs`, `Azaion.AdminApi/appsettings*.json` |
## Allowed Dependencies (csproj layering)
| Layer | csproj | May reference |
|-------|--------|---------------|
| 4. Entry / Host | `Azaion.AdminApi` | `Azaion.Services`, `Azaion.Common` |
| 3. Application | `Azaion.Services` | `Azaion.Common` |
| 2. Foundation | `Azaion.Common` | (none) |
| —. Tests (in-process) | `Azaion.Test` | `Azaion.Services`, `Azaion.Common`, `Azaion.AdminApi` (integration only) |
| —. Tests (out-of-process e2e) | `e2e/Azaion.E2E` | (none from production csprojs — HTTP only) |
A reference from a lower production layer to a higher production layer is an **Architecture** finding (High severity) in `/code-review` Phase 7. Test projects may reference any production csproj; production csprojs may NOT reference test projects.
## Layout Conventions (reference)
| Language | Root | Per-component path | Public API file | Test path |
|----------|------|-------------------|-----------------|-----------|
| C# (.NET) | `./` (this workspace, legacy flat layout) | `./<Csproj>/` | namespace-root types in each csproj | `Azaion.Test/`, `e2e/Azaion.E2E/` |
## Notes
- This file was authored 2026-05-13 by `/autodev` Step 10 to satisfy `/implement` Step 4. The `_docs/` artifact set predates the Step 1.5 module-layout addition, so this is a **backfill** rather than a fresh decompose Step 1.5 run.
- If the project later splits into multiple deployables (e.g. carving out `Azaion.AnnotationsApi`), re-run `/decompose` Step 1.5 to produce a finer-grained mapping.