4.4 KiB
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:
aiosqlitefü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.pyregistriert, 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/adminBootstrap-User, Registrierung erfolgt explizit viaPOST /api/v1/auth/register - R-4 CORS-Whitelist: Erlaubte Origins in
CORS_ORIGINSENV-Var (Komma-getrennt), KEIN"*"- Dev:
http://localhost:5500,http://localhost:8000 - Prod:
https://crm.media-on.de
- Dev:
- R-5 KEIN JWT-Secret-Fallback: Wenn
AUTH_SECRETfehlt oder < 32 Zeichen → App-Start bricht ab (Hard-Fail, keinedev-secretFallback) - 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(nichtSession) - Tests:
pytest-asynciomitasyncio_mode=auto - Alembic: async-template (
asyncio.runin env.py)
Nächste Phase nach User-Approval: implementation_engineer (Phase 4a) → Backend-Skeleton + Auth + Health