# Multi-Tenancy Das Compliance SDK ist vollstaendig mandantenfaehig. Jeder Tenant hat isolierte Daten — kein Tenant kann auf Daten eines anderen zugreifen. ## Tenant-ID - Format: UUID v4 (z.B. `9282a473-5c95-4b3a-bf78-0ecc0ec71d3e`) - Der String `"default"` wird NICHT mehr akzeptiert - Validierung via Regex in `tenant_utils.py` ## Shared Tenant Middleware `compliance/api/tenant_utils.py` stellt eine zentrale FastAPI-Dependency: ```python from compliance.api.tenant_utils import get_tenant_id @router.get("/example") async def example(tid: str = Depends(get_tenant_id)): # tid ist validierte UUID ... ``` ### Resolution-Reihenfolge 1. `X-Tenant-ID` HTTP-Header 2. `tenant_id` Query-Parameter 3. `DEFAULT_TENANT_ID` Umgebungsvariable 4. Fallback: `9282a473-5c95-4b3a-bf78-0ecc0ec71d3e` ## Migration 035: VVT Tenant Isolation - `compliance_vvt_activities`, `compliance_vvt_organization`, `compliance_vvt_audit_log`: `tenant_id VARCHAR(255) NOT NULL` hinzugefuegt - Bestehende Daten auf Standard-UUID backfilled - UNIQUE-Constraint `(tenant_id, vvt_id)` statt globalem `vvt_id` - DSFA/Vendor: `"default"` → UUID migriert ## Betroffene Module | Modul | Aenderung | |-------|-----------| | VVT | `tenant_id` Column + Query-Filter auf alle Endpoints | | DSFA | `DEFAULT_TENANT_ID` von `"default"` auf UUID | | Vendor Compliance | `DEFAULT_TENANT_ID` von `"default"` auf UUID | | Change-Requests | Nativ mit `tenant_id` | | Versionierung | Nativ mit `tenant_id` | | Company Profile | Nativ mit `tenant_id` | ## Frontend-Proxy Der Next.js-Proxy setzt automatisch den `X-Tenant-ID` Header: ```typescript headers['X-Tenant-ID'] = clientTenantId || process.env.DEFAULT_TENANT_ID || '9282a473-...' ``` ## Tests - 20 Tests in `test_vvt_tenant_isolation.py` - UUID-Validierung, Header-/Query-Precedence, Model-Column-Checks, Route-Isolation