mirror of
https://github.com/azaion/annotations.git
synced 2026-06-21 10:41:06 +00:00
03f879206e
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>
179 lines
8.8 KiB
Markdown
179 lines
8.8 KiB
Markdown
# 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 |
|