Root-Causes und Fixes: (1) conftest.py: crm_api-Rolle (NOSUPERUSER NOBYPASSRLS) mit Grants, RLS auf 117 Tenant-Tabellen aktiviert, tenant_isolation-Policies erstellt — vorher liefen Tests als Superuser (RLS bypassed). (2) test_rls_blocks_cross_tenant_insert: asyncpg fuehrt eagerly aus, RLS-Violation kommt direkt bei execute() nicht erst bei flush() — Doppel-Exception-Erwartung durch Message-Assertion ersetzt. (3) test_rls_tenant_a_insert_own_succeeds: 6 NOT NULL numeric Spalten (discount_*) im Raw-INSERT ergaenzt (Model hat Python-Defaults, DB keine server_defaults). (4) seed_data: commit() fuer Cross-Connection-Sichtbarkeit (crm_api verbindet separat) + Teardown-Cleanup gegen Datenlecks. (5) admin_session: ohne conn.begin() — sonst conditional_savepoint und commit() wirkungslos. (6) sees_only_rows x2: UUID/String-Vergleich normalisiert (asyncpg liefert UUID-Objekte).
Vorher: 9 von 10 Tests vakuum-trivial gruen (leere DB, Superuser). Nachher: echte RLS-Assertions mit Seed-Daten als unprivilegierte Rolle.
- Fix report_generator/jobs.py: use DmsContract instead of direct DMS import
- Remove app.tenant_id from set_tenant_context (only app.current_tenant_id)
- Create tests/test_cross_tenant_security_v2.py with real RLS tests using
unprivileged crm_api role (NOSUPERUSER, NOBYPASSRLS)
- Fix existing tests referencing app.tenant_id
- Git baseline tag v-phase0-baseline at 11d6faa
- Production DB backup at /tmp/crm_backup_20260731_015514.dump