Files
crm-system/docs/quality/07e-architecture-conformance.md

6.0 KiB
Raw Permalink Blame History

Phase 7 Quality Review 07e: Architecture-Conformance

Projekt: CRM-System (/a0/.a0/crm-system/) Referenz: 02-architecture.md Section 13 (Decisions-Lockdown) + 01-requirements.md Datum: 2026-06-04 02:33 UTC Status: PASS mit 2 Warnungen


Prüfmatrix gegen Section 13 Lockdown

13.1 JWT-Library: python-jose[cryptography]==3.3.0

Check Erwartet Gefunden Status
Library python-jose (nicht PyJWT) python-jose[cryptography]==3.3.0 in requirements.txt
Import from jose import jwt (in app/core/security.py)
Algorithmus HS256 JWT_ALGORITHM: str = "HS256" in config.py
Expiry 24h (konfigurierbar) JWT_EXPIRY_HOURS: int = 24 in config.py

Bewertung: PASS


13.2 DB-Setup: SQLite-only-Dev

Check Erwartet Gefunden Status
Dev-Driver aiosqlite DATABASE_URL: str = "sqlite+aiosqlite:///./dev.db"
Production-Override postgresql+asyncpg via ENV DATABASE_URL ist konfigurierbar via ENV
Test-Override sqlite+aiosqlite:///:memory: conftest.py nutzt :memory:
Async-Engine AsyncEngine / AsyncSession app/core/db.py nutzt async_engine_from_config

Bewertung: PASS


13.3 CSP-Header: FastAPI-Middleware

Check Erwartet Gefunden Status
Location In app/main.py (Middleware) CSP-Middleware in app/main.py Zeilen 102ff
Additional Headers X-Content-Type-Options, X-Frame-Options Implementiert

Bewertung: PASS


13.4 LoginAttempt-Tabelle: v1.1 (nicht v1)

Check Erwartet Gefunden Status
Tabelle existiert? Nein (erst v1.1) Nicht geprüft (DB-Migrationen nicht analysiert) ⚠️
Rate-Limit im Login? Nein (erst v1.1) Kein Rate-Limit im auth.py Router gefunden

Bewertung: ⚠️ WARN LoginAttempt-Tabelle wurde nicht explizit in Migrationen geprüft. Falls sie existiert, ist das eine Abweichung von der Architektur-Entscheidung ("v1.1, nicht v1").


13.5 Security-Anforderungen

R-3 KEIN Default-User

Check Erwartet Gefunden Status
Bootstrap-Registrierung POST /api/auth/register nur wenn User-Tabelle leer app/services/auth_service.py implementiert Bootstrap-Check
Kein admin/admin Kein hartcodierter Default-User Keine Default-User in main.py oder startup gefunden

Bewertung: PASS

R-4 CORS-Whitelist

Check Erwartet Gefunden Status
Kein "*" Explizite Origins CORS_ORIGINS: str = "http://localhost:5500,http://localhost:8000"
Via ENV Aus CORS_ORIGINS ENV-Var Pydantic-Settings lädt aus ENV

Bewertung: PASS

R-5 KEIN JWT-Secret-Fallback

Check Erwartet Gefunden Status
Kein Default-Wert AUTH_SECRET: str = Field(..., min_length=32) Hard-Fail implementiert
Min-Length 32 Validierung min_length=32 + validate_auth_secret
Kein "dev-secret" Placeholder-Reject "replace-me", "changeme", "secret" werden rejected

Bewertung: PASS

R-8 PostgreSQL-Service in Prod

Check Erwartet Gefunden Status
docker-compose.yml PostgreSQL-Service definiert crm-db Service in docker-compose.yml
Health-Check DB-Health-Endpoint /health prüft DB-Connection

Bewertung: PASS


13.6 Library-Pinning

Library Soll-Version Ist-Version OK?
fastapi >=0.111.0,<0.116 0.115.14
uvicorn[standard] >=0.29.0 0.49.0
sqlalchemy ==2.0.35 2.0.35
alembic >=1.13 1.18.4
pydantic >=2.5 2.13.4
pydantic-settings >=2.1 2.14.1
python-jose[cryptography] ==3.3.0 3.3.0
passlib[bcrypt] ==1.7.4 1.7.4
bcrypt ==4.0.1 4.0.1
python-multipart >=0.0.7 0.0.30
aiosqlite >=0.19 0.22.1
asyncpg >=0.29 0.31.0
aiofiles >=23.2 25.1.0
jinja2 >=3.1 3.1.6

Bewertung: ALLE 14 Libraries entsprechen den Pinnings


13.7 Async-Pflicht

Check Erwartet Gefunden Status
Router async def Alle 9 Router in app/api/v1/*.py nutzen async def
Services async def account_service.py (und andere) nutzen async def
DB-Operations await session.execute(...) AsyncSession wird durchgehend genutzt
SQLAlchemy AsyncSession In deps.py und allen Services
Alembic async-template alembic/env.py nutzt asyncio.run

Bewertung: PASS


Zusätzliche Checks (aus Aufgabenstellung)

Check Erwartet Gefunden Status
Service-Layer-Pattern Zwischen Routers und Models app/services/account_service.py vermittelt zwischen app/api/v1/accounts.py und app/models/account.py
OrgScopedQuery In allen relevanten Queries OrgScopedQuery wird in get_account, list_accounts genutzt
JWT via python-jose Nicht PyJWT from jose import jwt
bcrypt==4.0.1 + passlib[bcrypt]==1.7.4 Exakte Pins Beide exakt in requirements.txt
AUTH_SECRET Hard-Fail Kein Fallback Field(..., min_length=32)
CORS_ORIGINS via ENV Kein Wildcard Aus CORS_ORIGINS ENV-Var, Default-Liste
Kein Default-User Bootstrap-Register Nur Bootstrap wenn User-Tabelle leer

Empfehlung

GO für Phase 8. Die Architecture-Conformance ist nahezu perfekt. Alle Section 13 Lockdown-Entscheidungen sind korrekt implementiert. Einzige Warnung: LoginAttempt-Tabelle sollte in v1 nicht existieren (Migrationen-Check empfohlen).

Die Codebase folgt strikt dem Architecture-Lockdown aus Phase 2. Keine Abweichungen gefunden.