From 0c526c48f9489dd4caeed0b23033909af15cab43 Mon Sep 17 00:00:00 2001 From: Kitos Date: Fri, 20 Feb 2026 15:14:07 +0100 Subject: [PATCH] docs: update ARCHITECTURE.md, ARCHITECTURAL_ANALYSIS.md, and skill file with Tier 1-4 changes --- docs/ARCHITECTURAL_ANALYSIS.md | 35 +++++++++++++++++++++------------- docs/ARCHITECTURE.md | 15 ++++++++++++--- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/docs/ARCHITECTURAL_ANALYSIS.md b/docs/ARCHITECTURAL_ANALYSIS.md index b0bc70a..62ba515 100644 --- a/docs/ARCHITECTURAL_ANALYSIS.md +++ b/docs/ARCHITECTURAL_ANALYSIS.md @@ -1,7 +1,7 @@ # Aegis — Deep Architectural Analysis > **Author:** Automated architecture review -> **Date:** February 11, 2026 (updated February 20, 2026) +> **Date:** February 11, 2026 (updated February 20, 2026; Tier 1-4 complete) > **Scope:** Backend (FastAPI/Python), Frontend (React/TypeScript), Infrastructure (Docker) > > **Note:** Sections marked with ✅ reflect changes implemented since the initial analysis. @@ -69,9 +69,9 @@ Aegis follows a **layered monolithic architecture** deployed as two containers ( | Layer | Files | Actual Responsibility | |-------|-------|----------------------| -| **Routers** | 21 files | ✅ Thin HTTP adapters — auth, param parsing, response formatting. All delegate to services. | -| **Services** | 33+ files | ✅ All business logic, query orchestration, domain validation. Framework-agnostic. | -| **Domain** | 15+ files | ✅ Pure entities (Test, Technique, Campaign, Compliance), value objects, ports (repos + ImportService protocol), errors. Zero framework imports. | +| **Routers** | 21 files | ✅ Thin HTTP adapters — auth, param parsing, response formatting. All delegate to services. Zero inline ORM queries. | +| **Services** | 40+ files | ✅ All business logic, query orchestration, domain validation. Framework-agnostic. Includes: 4 newly extracted (advanced_metrics, analytics, test_template, auth) + 7 new query services (technique_query, d3fend_query, etc.). | +| **Domain** | 15+ files | ✅ Pure entities (Test, Technique, Campaign, Compliance, ThreatActor), value objects, ports (repos + ImportService protocol), errors. Zero framework imports. | | **Infrastructure** | 5+ files | ✅ Repository implementations, Redis client, mappers. | | **Models** | 19 files | ORM table definitions — persistence mapping only | | **Schemas** | 10 files | Pydantic DTOs for request/response | @@ -95,6 +95,8 @@ Extracted services: `coverage_report_service`, `metrics_query_service`, `complia **Update (Feb 20):** All routers now delegate to services. No routers contain direct ORM queries or business logic. +**Update (Feb 20 — Tier 1-2):** Four more routers fully extracted to new services: `advanced_metrics.py` → `advanced_metrics_service`, `analytics.py` → `analytics_service`, `test_templates.py` → `test_template_service`, `auth.py` → `auth_service`. Nine additional routers had remaining inline logic moved to their existing services: `techniques`, `campaigns`, `snapshots`, `notifications`, `scores`, `jira`, `d3fend`, `osint`, `worklogs`. + --- ## 2. Coupling Analysis @@ -383,13 +385,13 @@ Background jobs create sessions outside the request lifecycle. This is technical **Update (Feb 20):** `CampaignEntity` (with lifecycle state machine) and `ComplianceFrameworkEntity` / `ComplianceControlEntity` (with coverage calculation logic) have been added. -**Remaining:** ThreatActor still lacks a domain entity counterpart. +**Update (Feb 20 — Tier 4):** `ThreatActorEntity` (with coverage analysis: `coverage_pct`, `covered_techniques`, `uncovered_techniques`, `from_orm`) has been added. All major domain concepts now have rich entity counterparts. ### 5.8. ~~MEDIUM RISK: No Explicit Transaction Management~~ ✅ PARTIALLY RESOLVED **Update (Feb 18):** A `UnitOfWork` context manager exists at `domain/unit_of_work.py` with explicit `commit()`, `rollback()`, and `flush()`. Used by `test_workflow_service.py` which explicitly states "The caller (router) is responsible for committing the session via the Unit of Work pattern." -**Remaining:** Some services like `audit_service.py` still call `db.commit()` directly. Needs incremental migration. +**Update (Feb 20 — Tier 3):** Business services (`scoring_config_service`, `worklog_service`, `osint_enrichment_service.mark_osint_reviewed`) no longer call `db.commit()` — their callers use `UnitOfWork`. Documented exceptions: `audit_service.log_action` (15+ callers, high blast radius), import services (self-contained batch ops), and background jobs keep their internal commits. ### 5.9. LOW RISK: No Semantic API Versioning @@ -673,7 +675,7 @@ class SQLAlchemyTestRepository(TestRepository): | Fat controllers (routers with business logic) | HIGH | ✅ Resolved — all 21 routers now delegate to services (12 extracted) | | No repository layer | HIGH | ✅ Resolved (Test, Technique repos + 12 service modules) | | Services depend on FastAPI | HIGH | ✅ Resolved (domain exceptions + middleware) | -| Anemic models | MEDIUM | ✅ Largely resolved (TestEntity, TechniqueEntity, CampaignEntity, ComplianceFrameworkEntity) | +| Anemic models | MEDIUM | ✅ Resolved (TestEntity, TechniqueEntity, CampaignEntity, ComplianceFrameworkEntity, ThreatActorEntity) | | In-memory token blacklist | HIGH | ✅ Resolved (Redis-backed) | | Mutable settings at runtime | MEDIUM | ✅ Resolved (scoring_config DB table) | | No CI/CD | MEDIUM | ✅ Resolved (GitHub Actions) | @@ -688,14 +690,15 @@ class SQLAlchemyTestRepository(TestRepository): │ Maturity: Production-ready │ │ SOLID: 4.5/5 (SRP ✅, OCP mostly ✅, LSP n/a, │ │ ISP mostly ✅, DIP mostly ✅) │ -│ Testability: 8/10 (354 tests, domain unit tests, repo │ +│ Testability: 9/10 (362+ tests, domain unit tests, repo │ │ integration tests, service layer tests) │ -│ Coupling: 8/10 (domain decoupled, services agnostic, │ -│ all routers are thin adapters) │ +│ Coupling: 9/10 (domain decoupled, services agnostic, │ +│ all routers zero inline ORM, UoW pattern) │ │ Cohesion: 9/10 (domain entities own business rules, │ │ services own query logic, clear contracts) │ -│ Estimated remaining tech debt: ~2-3 days │ -│ (ThreatActor domain entity, heatmap layer extensibility)│ +│ Estimated remaining tech debt: ~1 day │ +│ (heatmap layer extensibility, full repo protocol │ +│ coverage, audit_service commit migration) │ └──────────────────────────────────────────────────────────┘ ``` @@ -718,7 +721,13 @@ The architectural refactoring is **complete**. All items from the original analy 10. ~~Extract `users.py`, `audit.py`, `data_sources.py` to services~~ ✅ Done 11. ~~Add common interface for import services (OCP)~~ ✅ Done (`ImportService` protocol + registry) +**Tier 1–4 (completed Feb 20):** +12. ~~Extract 4 fat routers to new services (advanced_metrics, analytics, test_templates, auth)~~ ✅ Done +13. ~~Move remaining inline logic from 9 routers to existing services~~ ✅ Done — all routers have zero inline ORM queries +14. ~~Migrate business services from direct db.commit() to UoW pattern~~ ✅ Done (3 services migrated, exceptions documented) +15. ~~Create ThreatActor domain entity~~ ✅ Done (with coverage analysis) + **Remaining nice-to-haves (not blocking):** -- ThreatActor domain entity (currently only a service exists) - Heatmap layer extensibility (currently hardcoded endpoints) - Full migration of all services to use Repository pattern (incremental) +- Migrate `audit_service.log_action` from internal commit to UoW (15+ callers to update) diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index ca97530..d8892d9 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -125,7 +125,9 @@ database.py ← Engine + session management (lazy initialization) | `score_cache` | In-memory TTL cache (5 min) for expensive score/metric calculations | | `operational_metrics_service` | MTTD, MTTR, detection efficacy, alert fidelity, coverage velocity | | `metrics_query_service` | Dashboard aggregation queries | -| `snapshot_service` | Coverage snapshot creation, temporal comparison, cleanup | +| `advanced_metrics_service` | Coverage by tactic, never-tested, avg validation time, detection trends | +| `analytics_service` | BI-ready flat datasets (coverage, tests, trends, operators) | +| `snapshot_service` | Coverage snapshot CRUD, temporal comparison, cleanup | | `campaign_crud_service` | Campaign CRUD, lifecycle, scheduling | | `campaign_service` | Campaign progress tracking, circular dependency prevention | | `campaign_scheduler_service` | Recurring campaign execution (clone + schedule next run) | @@ -136,11 +138,17 @@ database.py ← Engine + session management (lazy initialization) | `threat_actor_service` | Threat actor queries, coverage, gap analysis | | `evidence_service` | Evidence permission validation and queries | | `heatmap_service` | ATT&CK Navigator layer generation | +| `test_template_service` | Test template CRUD, stats, bulk-activate, filtered queries | +| `auth_service` | Credential validation, password management | | `user_service` | User CRUD, role validation, password hashing | | `audit_query_service` | Paginated audit log queries and distinct lookups | | `audit_service` | Immutable audit trail logging (write-only) | | `data_source_service` | Data source CRUD, sync dispatch, statistics | -| `notification_service` | In-app notification CRUD and state-change alerts | +| `notification_service` | In-app notification CRUD, state-change alerts, role-based dispatch | +| `technique_query_service` | Technique detail queries with test/D3FEND aggregation | +| `d3fend_query_service` | D3FEND defensive technique listing and tactic queries | +| `osint_enrichment_service` | OSINT item queries, enrichment, summary statistics | +| `worklog_service` | Worklog CRUD, integrity verification | | `intel_service` | RSS-based threat intelligence scanning | #### Import Services (all satisfy `ImportService` protocol) @@ -164,7 +172,8 @@ domain/ ├── entities/ # Rich domain entities with business logic │ ├── technique.py # TechniqueEntity with status recalculation │ ├── campaign.py # CampaignEntity with lifecycle state machine -│ └── compliance.py # ComplianceFrameworkEntity with coverage calculation +│ ├── compliance.py # ComplianceFrameworkEntity with coverage calculation +│ └── threat_actor.py # ThreatActorEntity with coverage analysis ├── value_objects/ # Immutable value types │ ├── mitre_id.py # MITRE ATT&CK ID validation │ └── scoring_weights.py # Scoring weights (sum=100, non-negative)