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
+208
View File
@@ -0,0 +1,208 @@
# Codebase discovery — Azaion.Annotations
## Canonical product documentation (external)
Suite-level API and integration reference (maintained with the monorepo):
`/Users/obezdienie001/dev/azaion/suite/_docs/01_annotations.md`
(Relative from this repo: `../_docs/01_annotations.md`.)
This `_docs/02_document/` run is **bottom-up from code**; keep `01_annotations.md` aligned when HTTP contracts or integration behavior change.
---
## Directory tree (source)
```
annotations/
├── README.md
├── src/
│ ├── Azaion.Annotations.csproj
│ ├── Dockerfile
│ ├── GlobalUsings.cs
│ ├── Program.cs
│ ├── Auth/
│ ├── Controllers/
│ ├── Database/
│ │ ├── AppDataConnection.cs
│ │ ├── DatabaseMigrator.cs
│ │ └── Entities/
│ ├── DTOs/
│ ├── Enums/
│ ├── Middleware/
│ └── Services/
└── _docs/
```
Ignored per scan policy: `bin/`, `obj/`, `.git`, `node_modules`, `__pycache__`.
---
## Tech stack
| Area | Choice |
|------|--------|
| Language | C# / .NET (`net10.0` in csproj) |
| Host | ASP.NET Core minimal hosting + controllers |
| ORM / DB | Linq2DB + Npgsql → PostgreSQL |
| Auth | JWT Bearer (`Microsoft.AspNetCore.Authentication.JwtBearer`) |
| Messaging | RabbitMQ Streams (`RabbitMQ.Stream.Client`), MessagePack |
| API docs | Swashbuckle (Swagger / OpenAPI) |
| Hashing | `System.IO.Hashing` (annotation id / media paths) |
---
## Package manifest
- `src/Azaion.Annotations.csproj` — single web project.
---
## Config and operations
| Artifact | Role |
|----------|------|
| `src/Dockerfile` | Container build |
| `Program.cs` | `DATABASE_URL`, `JWT_ISSUER` / `JWT_AUDIENCE` / `JWT_JWKS_URL`, `CorsConfig:*`, RabbitMQ env vars (`RABBITMQ_*`), migrator on startup. All required vars are resolved through `ConfigurationResolver` (fail-fast). |
| `.vscode/launch.json` | Local debugging (if present) |
No `.github/workflows` in this repository (CI may live in suite/monorepo).
---
## Entry points
- **`Program.cs`** — service registration, JWT, CORS, Swagger, `DatabaseMigrator.Migrate`, middleware pipeline, `MapControllers()`, `/health`.
---
## Tests
No `*.Tests.csproj` or `tests/` tree in this workspace — **no automated test project** discovered.
---
## Existing documentation in repo
- Root `README.md` — points to suite `01_annotations.md`.
- `src/README.md` — short service blurb + link to root README.
---
## Module boundaries (revised — aligned with `01_annotations.md`)
The suite file is organized around **annotation lifecycle**, **media**, **settings/camera**, **SSE**, **RabbitMQ sync**, and **auth** (JWT refresh). The codebase splits the same concerns across controllers/services; **dataset** and **detection classes** are additional HTTP surfaces referenced from suite `09_dataset_explorer.md` / UI.
| # | Module (doc file) | Primary code | Suite `01_annotations.md` anchor |
|---|-------------------|--------------|-----------------------------------|
| 1 | `wire-enums.md` | `src/Enums/*` | “Wire format”, enum tables |
| 2 | `database-layer.md` | `src/Database/*` | Annotation identity, tables, `SilentDetection` / `GenerateAnnotatedImage` columns |
| 3 | `common-infrastructure.md` | `PathResolver`, `ErrorHandlingMiddleware`, `PaginatedResponse`, `ErrorResponse`, `GlobalUsings.cs` | File paths for image/label/thumb/results; error JSON shape |
| 4 | `auth-identity.md` | `JwtExtensions` (verifier-only over admin's JWKS) | JWT forward only — refresh is admin's responsibility (annotations no longer hosts `/auth/refresh`) |
| 5 | `media-service.md` | `MediaService`, `MediaController`, media DTOs | §710 POST/GET/DELETE media, batch upload |
| 6 | `annotations-service.md` | `AnnotationService`, `AnnotationsController` (REST + static files, not SSE) | §16 annotations CRUD/query |
| 7 | `dataset-service.md` | `DatasetService`, `DatasetController`, dataset DTOs | Cross-ref §3 note (DATASET); `09_dataset_explorer.md` |
| 8 | `settings-metadata-service.md` | `SettingsService`, `SettingsController`, `ClassesController`, settings DTOs | §1112 camera; directories/system/user settings; GET `/classes` |
| 9 | `sse-realtime.md` | `AnnotationEventService`, SSE action on `AnnotationsController` | §SSE `GET /annotations/events`, `AnnotationEvent` |
| 10 | `rabbitmq-stream-sync.md` | `FailsafeProducer`, `RabbitMqConfig`, `DTOs/QueueMessages.cs`, queue entity | §Annotation Sync, Failsafe, Stream |
| 11 | `composition-program.md` | `Program.cs` | Wiring, env defaults, startup migrate |
**DTOs** (`src/DTOs/`) are documented **inside the module that owns the HTTP contract**, with cross-links (no separate monolithic “DTOs” module).
See `modules/README.md` for the same index and file naming.
---
## Module dependency graph (revised)
```mermaid
flowchart BT
WE[wire-enums]
DB[database-layer]
CI[common-infrastructure]
AUTH[auth-identity]
MEDIA[media-service]
ANN[annotations-service]
DS[dataset-service]
SET[settings-metadata-service]
SSE[sse-realtime]
RMQ[rabbitmq-stream-sync]
PRG[composition-program]
WE --> DB
DB --> CI
DB --> MEDIA
DB --> ANN
DB --> DS
DB --> SET
CI --> MEDIA
CI --> ANN
AUTH --> MEDIA
AUTH --> ANN
AUTH --> DS
AUTH --> SET
MEDIA --> ANN
ANN --> SSE
ANN --> RMQ
SET --> CI
SSE --> ANN
RMQ --> ANN
RMQ --> MEDIA
RMQ --> DB
MEDIA --> PRG
ANN --> PRG
DS --> PRG
SET --> PRG
SSE --> PRG
RMQ --> PRG
AUTH --> PRG
CI --> PRG
```
Edges are “depends on for types, DB, paths, or events” (approximate). `ClassesController` reads DB directly — captured under **settings-metadata-service** for doc cohesion (small surface).
---
## Topological order (document skill Step 1)
1. `wire-enums`
2. `database-layer`
3. `common-infrastructure`
4. `auth-identity`
5. `media-service`
6. `annotations-service`
7. `dataset-service`
8. `settings-metadata-service`
9. `sse-realtime`
10. `rabbitmq-stream-sync`
11. `composition-program`
---
## Notes for downstream steps
- **Component assembly (Step 2):** expect components such as “Annotations + sync”, “Media”, “Dataset”, “Settings”, “Platform (auth+db+infra)” — refine with user confirmation (BLOCKING gate).
- **RabbitMQ:** `RabbitMqConfig` class lives in `FailsafeProducer.cs`; document in `rabbitmq-stream-sync` module.
---
## Suite spec cross-check (`suite/_docs/01_annotations.md`)
Canonical product/API narrative for this service. Use it when writing module and component docs.
| Topic in suite doc | Adds context for this repo |
|--------------------|------------------------------|
| Annotation identity (hash id, image + YOLO label, `Time` / `CreatedDate`) | `annotations-service` + `database-layer` + `common-infrastructure` (`PathResolver`) |
| Wire enums as integers | `wire-enums` module |
| REST §16 vs §710 | `annotations-service` vs `media-service` |
| Settings §1112, directories | `settings-metadata-service` |
| SSE | `sse-realtime` |
| Failsafe + RabbitMQ Stream | `rabbitmq-stream-sync` |
| Dataset note (DATASET permission) | `dataset-service` |
**Drifts spotted (suite vs current code)** — reconcile in suite or in code as you prefer:
1. **POST /annotations user id:** Suite lists `UserId` on request body; code uses JWT `NameIdentifier` (`annotations-service`).
2. **GET /annotations filter:** Suite lists `missionId`; code has `FlightId` and a partial filter — see `annotations-service` module.
Module docs (`modules/*.md`) carry contract detail per slice; this section stays the cross-file index.