docs+src: complete Steps 1-3 outcomes + auth re-sync baseline

This commit captures everything produced during autodev existing-code
Steps 1 (Document), 2 (Architecture Baseline Scan), and 3 (Test Spec),
together with the targeted auth + CORS re-sync triggered on 2026-05-14
when codebase drift was detected at Step 4 entry. None of this work was
previously committed.

Step 1 (Document) — 50+ _docs/02_document/ files: problem, solution,
architecture, system flows, glossary, module-layout, per-component
specs (01..06), modules, deployment, diagrams, data model, FINAL
report, verification log, discovery.

Step 2 (Architecture Baseline) — architecture_compliance_baseline.md.
Verdict PASS_WITH_WARNINGS (0 Critical, 0 High, 1 Medium, 2 Low). No
High/Critical findings; auto-chained to Step 3 per existing-code flow.

Step 3 (Test Spec) — _docs/02_document/tests/* (67 scenarios across
blackbox, security, resilience, resource-limit, performance), plus
e2e/docker-compose.test.yml, e2e/seed/run.sh, scripts/run-tests.sh,
scripts/run-performance-tests.sh. Coverage 88% over the active scope
(40 of 45 items covered, 6 RB-deferred, 5 documented-as-uncovered).

Targeted auth + CORS re-sync — replaces the deleted in-house token
issuer with a JWKS-verifier model. AuthController and TokenService
removed; JwtExtensions switched from HS256 symmetric to ES256 over
admin's JWKS. ConfigurationResolver and CorsConfigurationValidator
added under src/Infrastructure/. ADR-002 and ADR-006 retired; SEC-01,
SEC-02, SEC-03 marked Closed. One new testability risk recorded in
architecture.md Open Risks Section 6 (JWKS HTTPS gating).

Source changes:
- src/Auth/JwtExtensions.cs (modified) — ES256, JWKS, alg pinning
- src/Program.cs (modified) — DI wiring for ConfigurationResolver
  and CorsConfigurationValidator
- src/Controllers/AuthController.cs (deleted) — no in-service issuance
- src/Services/TokenService.cs (deleted) — same
- src/Infrastructure/ConfigurationResolver.cs (new)
- src/Infrastructure/CorsConfigurationValidator.cs (new)
- .env.example (new) — required env var documentation
- .gitignore (updated)

Cross-repo coordination: _docs/cross-repo/flights_h1_h2_h3_change_spec
captures the change-spec for downstream services that consumed the now
deleted /auth endpoints.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-14 20:19:05 +03:00
parent 08eadc1158
commit 03f879206e
66 changed files with 6006 additions and 133 deletions
+178
View File
@@ -0,0 +1,178 @@
# Module Layout
**Status**: derived-from-code
**Language**: csharp
**Layout Convention**: single-assembly (`Azaion.Annotations`), vertical slices expressed as **logical components** under flat `src/` folders (`Controllers/`, `Services/`, `DTOs/`).
**Root**: `src/`
**Last Updated**: 2026-05-14
## Verification Needed
1. **No per-component physical root** — all components share `src/Controllers/`, `src/Services/`, `src/DTOs/`. File ownership below is **exclusive for implementation planning**; merges touching the same file need explicit batch ordering.
2. **`AnnotationsController.cs` split (user-approved six-component model)** — **REST + static files** belong to **01 Annotations REST**; **SSE** (`Events`) belongs to **02 Annotations realtime & sync**. For `/implement`, treat **`src/Controllers/AnnotationsController.cs` as owned by 01**; tasks that **only** change SSE must still edit this file — flag as **cross-component** (01 + 02) or split into partial classes in a future refactor.
3. **`src/DTOs/`** — no subfolders; each file has a **primary owner** in [Shared: DTO files](#shared-dto-files-primary-ownership) to resolve FORBIDDEN vs OWNED during tasks.
4. **`FailsafeProducer.cs`** contains `RabbitMqConfig` and `FailsafeProducer` — fully owned by **02** (even though `Program.cs` registers the config as singleton).
---
## Layout Rules (adapted for this repo)
1. Components map to **logical** slices from `_docs/02_document/components/*/description.md`, not to separate top-level directories.
2. **Foundation** (`06_platform`) owns schema, enums, auth registration helpers, middleware, path resolution, and **composition** (`Program.cs`, csproj, Dockerfile).
3. **Feature** components own listed **service + controller** files; they **read** foundation public APIs and **shared DTO** types per the DTO table.
4. Tests are **not present** in-repo; future test project should follow `tests/Azaion.Annotations.Tests/` (conventional) — not owned by feature slices until created.
---
## Per-Component Mapping
### Component: `01_annotations-rest`
- **Epic**: (assign per change; layout is structural)
- **Directory (primary)**: `src/Services/` (partial), `src/Controllers/` (partial)
- **Public API** (types other components may reference through DI / same assembly):
- `Azaion.Annotations.Services.AnnotationService`
- `Azaion.Annotations.Controllers.AnnotationsController` (REST + image/thumbnail actions only — see Verification)
- **Internal**: private methods inside owned types; do not reach into other components services from new code without updating this layout.
- **Owns (exclusive write scope)**:
- `src/Services/AnnotationService.cs`
- `src/Controllers/AnnotationsController.cs`**primary file owner** (REST, `GetThumbnail`, `GetImage`; coordinate with 02 for `Events`)
- **Imports from**: `06_platform` (Database, Enums, DTOs used here, PathResolver, Middleware indirectly), `02_annotations-realtime-sync` (`AnnotationEventService` for publish)
- **Consumed by**: `04_dataset` (read paths share DB entities; no direct `AnnotationService` reference required), external callers
### Component: `02_annotations-realtime-sync`
- **Epic**: (assign per change)
- **Directory (primary)**: `src/Services/` (partial)
- **Public API**:
- `Azaion.Annotations.Services.AnnotationEventService`
- `Azaion.Annotations.Services.RabbitMqConfig`
- `Azaion.Annotations.Services.FailsafeProducer`
- `FailsafeProducer.EnqueueAsync` (static helper on same type as producer)
- **Owns**:
- `src/Services/FailsafeProducer.cs` (includes `RabbitMqConfig` + `FailsafeProducer`)
- `src/Services/AnnotationEventService.cs`
- **SSE contract**: `AnnotationsController.Events` (same `.cs` as 01 — see Verification)
- **Imports from**: `06_platform` (Database, Entities, PathResolver, Enums, `DTOs/QueueMessages.cs`), `DTOs/AnnotationEventDto.cs` (see Shared)
- **Consumed by**: `01_annotations-rest` (publishes events), external RabbitMQ consumers
### Component: `03_media`
- **Epic**: (assign per change)
- **Public API**: `MediaService`, `MediaController`
- **Owns**:
- `src/Services/MediaService.cs`
- `src/Controllers/MediaController.cs`
- **Imports from**: `06_platform`
- **Consumed by**: `01_annotations-rest` (domain: media rows referenced by annotations), UI
### Component: `04_dataset`
- **Epic**: (assign per change)
- **Public API**: `DatasetService`, `DatasetController`
- **Owns**:
- `src/Services/DatasetService.cs`
- `src/Controllers/DatasetController.cs`
- **Imports from**: `06_platform`
- **Consumed by**: Dataset Explorer UI
### Component: `05_settings-metadata`
- **Epic**: (assign per change)
- **Public API**: `SettingsService`, `SettingsController`, `ClassesController`
- **Owns**:
- `src/Services/SettingsService.cs`
- `src/Controllers/SettingsController.cs`
- `src/Controllers/ClassesController.cs`
- **Imports from**: `06_platform`
- **Consumed by**: UI; `PathResolver` / directory settings (via DB) interact with **06** cache reset when dirs change
### Component: `06_platform`
- **Epic**: (assign per change)
- **Public API** (representative; all `public` types in these areas are the integration surface):
- `Azaion.Annotations.Database.AppDataConnection`, `DatabaseMigrator`, `Azaion.Annotations.Database.Entities.*`
- `Azaion.Annotations.Enums.*`
- `Azaion.Annotations.Middleware.ErrorHandlingMiddleware`
- `Azaion.Annotations.Auth.JwtExtensions`
- `Azaion.Annotations.Infrastructure.ConfigurationResolver`, `CorsConfigurationValidator`
- `Azaion.Annotations.Services.PathResolver`
- `Program` (implicit entry), `src/Program.cs`
- **Owns**:
- `src/Enums/**`
- `src/Database/**`
- `src/Middleware/**`
- `src/Auth/**`
- `src/Infrastructure/**`
- `src/Services/PathResolver.cs`
- `src/GlobalUsings.cs`
- `src/Program.cs`
- `src/Azaion.Annotations.csproj`
- `src/Dockerfile`
- **Imports from**: (none — foundation)
- **Consumed by**: all other components
---
## Shared: DTO files (primary ownership)
| File under `src/DTOs/` | Primary component | Notes |
|------------------------|-------------------|--------|
| `PaginatedResponse.cs` | `06_platform` | Generic list wrapper — cross-cutting |
| `ErrorResponse.cs` | `06_platform` | Shared error shape |
| `CreateAnnotationRequest.cs` | `01_annotations-rest` | |
| `UpdateAnnotationRequest.cs` | `01_annotations-rest` | |
| `UpdateStatusRequest.cs` | `01_annotations-rest` / `04_dataset` | **Shared type****01** owns file edits; `04_dataset` uses for PATCH |
| `GetAnnotationsQuery.cs` | `01_annotations-rest` | |
| `AnnotationListItem.cs` | `01_annotations-rest` | |
| `DetectionDto.cs` | `01_annotations-rest` | |
| `AnnotationEventDto.cs` | `02_annotations-realtime-sync` | SSE payload |
| `QueueMessages.cs` | `02_annotations-realtime-sync` | MessagePack stream payloads |
| `CreateMediaRequest.cs` | `03_media` | |
| `GetMediaQuery.cs` | `03_media` | |
| `MediaListItem.cs` | `03_media` | |
| `GetDatasetQuery.cs` | `04_dataset` | |
| `DatasetItem.cs` | `04_dataset` | |
| `ClassDistributionItem.cs` | `04_dataset` | |
| `BulkStatusRequest.cs` | `04_dataset` | |
| `UpdateSystemSettingsRequest.cs` | `05_settings-metadata` | |
| `UpdateDirectoriesRequest.cs` | `05_settings-metadata` | |
| `UpdateCameraSettingsRequest.cs` | `05_settings-metadata` | |
| `UpdateUserSettingsRequest.cs` | `05_settings-metadata` | |
---
## Shared / Cross-Cutting (non-DTO)
### `common-helpers/01_http-error-envelope.md`
- **Purpose**: Documents middleware as cross-cutting (see `_docs/02_document/common-helpers/`).
- **Owned by**: tasks touching **06_platform** (`ErrorHandlingMiddleware`).
- **Consumed by**: all HTTP components.
---
## Allowed Dependencies (layering)
Higher layers may depend on lower; **not** the reverse. Same-layer components should not introduce compile-time cycles (current codebase: none detected).
| Layer | Components | May import from (namespaces / types from) |
|-------|------------|---------------------------------------------|
| 1 — Foundation | `06_platform` | *(none)* |
| 2 — Realtime infra | `02_annotations-realtime-sync` | `06_platform` |
| 3 — Application features | `01_annotations-rest`, `03_media`, `04_dataset`, `05_settings-metadata` | `06_platform`, and **`01` additionally `02`** (`AnnotationEventService`) |
**Rules**
- `03`, `04`, `05`**must not** reference `AnnotationService` / `MediaService` across features without an explicit API (today: only via shared `AppDataConnection` in same assembly — acceptable but treat as **tight coupling**; prefer domain services for new code).
- `02`**must not** reference `01` service types (no reverse dependency today).
Violations are **Architecture** findings for code-review Phase 7.
---
## Layout Conventions (reference)
| Language | Root | This repo |
|----------|------|-----------|
| C# (.NET) | `src/` | Single web project; vertical slices = **logical** component rows above + DTO table |