Files
crm-system/docs/02-architecture.md
T

4.4 KiB

13. Phase-3-Decisions-Lockdown (vom User bestätigt 2026-06-03)

Diese Section bündelt alle offenen Punkte aus der Pattern-Summary, die vor Phase 4a-Start geklärt wurden. Diese Defaults sind gelockt und gelten für alle nachfolgenden Phasen, bis explizit geändert.

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

  • Entscheidung: python-jose (nicht PyJWT)
  • Begründung: Pattern-Reuse aus wochenplaner, gleiche API wie dort
  • Verwendung: from jose import jwt (encode, decode)
  • Algorithmus: HS256 (single-secret, single-server)
  • Expiry: 24h (gemäß 01-requirements FR-1.2), konfigurierbar via JWT_EXPIRY_HOURS
  • Refresh-Token: v1.1 (nicht v1)

13.2 DB-Setup: SQLite-only-Dev (kein paralleles PostgreSQL)

  • Entscheidung: SQLite in Dev, PostgreSQL erst in Prod (via Coolify)
  • Driver: aiosqlite für async SQLite
  • Begründung: Schneller Dev-Loop, weniger Test-Aufwand, Production-Driver in 4d definiert
  • Config: DATABASE_URL=sqlite+aiosqlite:///./dev.db (default) oder via ENV
  • Production-Override: DATABASE_URL=postgresql+asyncpg://... in Coolify
  • Test-Override: DATABASE_URL=sqlite+aiosqlite:///:memory: in pytest

13.3 CSP-Header: FastAPI-Middleware (zentral, app-aware)

  • Entscheidung: CSP-Header in FastAPI-Middleware (nicht nginx.conf)
  • Begründung: App-aware, zentral in app/main.py registriert, einfacher zu testen
  • Header-Wert (Dev):
    Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.tailwindcss.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none';
    
  • Header-Wert (Prod): 'unsafe-inline' für Scripts entfernen (Alpine.js inline-eval → v1.1 Fix mit Nonce)
  • Weitere Security-Header: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Strict-Transport-Security (Prod)

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

  • Entscheidung: Brute-Force-Schutz via LoginAttempt erst in v1.1
  • Begründung: Demo-Scope, JWT-Token-Diebstahl ist größeres Risiko als Brute-Force
  • v1-Verhalten: Login-Endpoint hat kein Rate-Limit (siehe A-4 Risiko)
  • v1.1-Plan: LoginAttempt-Tabelle (user_id, ip_address, attempted_at, success), Middleware für Rate-Limit (z.B. 5 Versuche / 15 min)

13.5 Security-Anforderungen (übernommen aus patterns-summary Risiken 3, 4, 5, 8)

  • R-3 KEIN Default-User: Kein admin/admin Bootstrap-User, Registrierung erfolgt explizit via POST /api/v1/auth/register
  • R-4 CORS-Whitelist: Erlaubte Origins in CORS_ORIGINS ENV-Var (Komma-getrennt), KEIN "*"
    • Dev: http://localhost:5500,http://localhost:8000
    • Prod: https://crm.media-on.de
  • R-5 KEIN JWT-Secret-Fallback: Wenn AUTH_SECRET fehlt oder < 32 Zeichen → App-Start bricht ab (Hard-Fail, keine dev-secret Fallback)
  • R-8 PostgreSQL-Service in Prod: Production-Deployment MUSS PostgreSQL-Service in Coolify nutzen, KEIN SQLite in Prod

13.6 Library-Pinning (aus wochenplaner-requirements.txt übernommen)

Library Version Zweck
fastapi >=0.111.0,<0.116 Web-Framework
uvicorn[standard] >=0.29.0 ASGI-Server
sqlalchemy ==2.0.35 ORM (async via aiosqlite/asyncpg)
alembic >=1.13 Migrationen
pydantic >=2.5 Schema-Validation
pydantic-settings >=2.1 Settings-Management
python-jose[cryptography] ==3.3.0 JWT-Encode/Decode
passlib[bcrypt] ==1.7.4 Password-Hashing-Wrapper
bcrypt ==4.0.1 Password-Hashing-Algorithmus
python-multipart >=0.0.7 Form-Data-Parsing
aiosqlite >=0.19 Async-SQLite-Driver
asyncpg >=0.29 Async-PostgreSQL-Driver (Prod)
aiofiles >=23.2 Async-File-I/O für Static-Files
jinja2 >=3.1 Template-Engine (optional, für Error-Pages)
pytest >=8.0 Test-Framework
pytest-asyncio >=0.23 Async-Tests
httpx >=0.27 Async-HTTP-Client (Tests + API-Wrapper)
ruff >=0.4 Linting (Phase 7)
mypy >=1.10 Type-Check (Phase 7)

13.7 Async-Pflicht (R-2 + ADR-1)

  • Alle Routers: async def
  • Alle Services: async def
  • Alle DB-Operations: await session.execute(...)
  • SQLAlchemy: AsyncSession (nicht Session)
  • Tests: pytest-asyncio mit asyncio_mode=auto
  • Alembic: async-template (asyncio.run in env.py)

Nächste Phase nach User-Approval: implementation_engineer (Phase 4a) → Backend-Skeleton + Auth + Health