diff --git a/docs/phase0_phase1_acceptance_report.md b/docs/phase0_phase1_acceptance_report.md index 0f0b30b..e036012 100644 --- a/docs/phase0_phase1_acceptance_report.md +++ b/docs/phase0_phase1_acceptance_report.md @@ -191,3 +191,83 @@ Worker verarbeitet Outbox-Jobs und send_password_reset_email. Plugin-Eventhandle - Gate 5 (Worker-Eventhandler): ⏳ Offen Phase 0 und Phase 1 können als technisch abgenommen gelten, sobald Gate 2, 3 und 5 abgeschlossen sind. + +--- + +## Gate 2 — Neuinstallation auf leerer Datenbank ✅ BESTANDEN + +**Datum:** 2026-07-31 +**Git-Commit:** 89b775b +**Test-Service:** g13zwdav6myvpnop96dj7tpx (crmtest.media-on.de) +**Image:** stvabl4vaqru7jclx4ittzr3:89b775b +**DB-Image:** pgvector/pgvector:pg16 + +### Durchführung + +1. Coolify Test-Service mit eigener PostgreSQL, Redis, API, Worker erstellt +2. DB-Volume gelöscht für vollständig leere DB +3. Image aus Git-Commit 89b775b auf Server gebaut +4. Compose aktualisiert: Image 89b775b + pgvector/pgvector:pg16 +5. `docker compose up -d` — alle Container gestartet +6. prestart.sh führte `alembic upgrade head` als crm_user aus +7. Migrationen 0001→0090 automatisch ausgeführt +8. Plugin-Migrationen über crm_migration ausgeführt (P0-Fix) +9. seed_admin.py ausgeführt — Tenant + Role + User + UserTenant erstellt +10. Login über HTTPS getestet + +### Verifikationsergebnisse + +| Kriterium | Ergebnis | +|-----------|----------| +| Coolify-Deployment erfolgreich | ✅ Alle 4 Container healthy | +| API healthy | ✅ Up 2 minutes (healthy) | +| Worker healthy | ✅ Up 2 minutes (healthy) | +| PostgreSQL healthy | ✅ Up 2 minutes (healthy) | +| Redis healthy | ✅ Up 2 minutes | +| Alembic-Head | ✅ 0090 | +| Tabellen erstellt | ✅ 124 Tabellen | +| Keine manuellen Schemaänderungen | ✅ Ausschließlich Migrationen | +| Rollen vorhanden | ✅ crm_migration (BYPASSRLS), crm_api/crm_auth/crm_worker (NOBYPASSRLS, NOSUPERUSER) | +| RLS aktiviert | ✅ 47 Tabellen mit RLS | +| Legacy app.tenant_id Policies | ✅ 0 (Migration 0090 fixt _old Tabellen) | +| Admin erfolgreich angelegt | ✅ Tenant + Role + User + UserTenant | +| Login erfolgreich | ✅ 200 OK mit user_id, csrf_token, tenant_id | +| RLS ohne Kontext fail-closed | ✅ 0 rows | +| Cross-Tenant INSERT blockiert | ✅ 'new row violates row-level security policy' | +| Valid INSERT funktioniert | ✅ INSERT 0 1 | +| crm_api DDL blockiert | ✅ 'permission denied for schema public' | + +### Ausgeführte Befehle + +``` +# Image bauen +git clone https://forgejo.media-on.de/Leopoldadmin/leocrm.git +git checkout 89b775b +docker build -t stvabl4vaqru7jclx4ittzr3:89b775b . + +# Compose aktualisieren und neu starten +docker compose up -d + +# Verifikation +psql -U crm_user -d crm_test_db -f gate2_verify.sql +psql -U crm_user -d crm_test_db -f gate2_rls.sql +psql -U crm_user -d crm_test_db -f gate2_columns.sql + +# Seed +docker exec api-g13zwdav6myvpnop96dj7tpx python3 scripts/seed_admin.py + +# Login +curl -X POST https://crmtest.media-on.de/api/v1/auth/login \ + -H "Content-Type: application/json" \ + -H "Origin: https://crmtest.media-on.de" \ + -d '{"email":"admin@media-on.de","password":"Admin123!"}' +``` + +### Bekannte Issues + +1. **Login-Rolle 'viewer' statt 'admin':** seed_admin.py erstellt Role mit name='admin' und permissions={'*:*': True}, aber Login-Response gibt role='viewer'. Vermutlich wird die Rolle aus UserTenant.role_id nicht korrekt aufgelöst. Kein Gate-2-Blocker — RLS und Tenant-Isolation funktionieren korrekt. +2. **pgvector-Extension:** Test-DB verwendet pgvector/pgvector:pg16 statt postgres:16-alpine. Produktion verwendet ebenfalls pgvector. Compose-Datei des Test-Services muss in Coolify aktualisiert werden. + +### Gate-2-Abnahme: BESTANDEN + +Alle Abnahmekriterien erfüllt. Die Anwendung startet auf einer vollständig leeren Datenbank ohne manuelle Nacharbeit.