# Schema Authority > **Task:** B-SCHEMA — Dokumentieren der Schema-Verantwortlichkeiten > **Status:** Done --- ## Übersicht LeoCRM hat **drei Schema-Ebenen** mit klar getrennten Verantwortlichkeiten. Es gibt keinen zusätzlichen Schema-Mechanismus — die bestehenden Wege sind verbindlich. ## 1. Core-Schema → Alembic **Verantwortlich:** Alembic-Migrationen (`alembic/versions/`) - Alle Core-Tabellen (contacts, companies, users, tenants, roles, audit, etc.) werden ausschließlich über Alembic-Migrationen erstellt und geändert. - Jede Schema-Änderung erfordert eine neue Alembic-Revision (`alembic revision --autogenerate -m "description"`). - Migrationen müssen downgrade-fähig sein. - Migrationen werden beim Container-Start via `prestart.sh` (Alembic upgrade head) ausgeführt. - **Kein** `Base.metadata.create_all()` in Produktion — nur in Tests als Notlösung. ## 2. Plugin-Schema → Plugin-Migrationsweg **Verantwortlich:** Plugin-eigene Migrationen (`app/plugins/builtins//migrations/`) - Jedes Plugin verwaltet seine eigenen Tabellen über eigene Migrationen. - Plugin-Migrationen werden beim Plugin-Start via `sync_plugin_schema.py` ausgeführt. - Plugin-Tabellen müssen `tenant_id` enthalten (siehe AGENTS.md Forbidden Patterns). - Plugin-Migrationen sind unabhängig von Core-Alembic-Migrationen. - **Kein** Plugin darf Core-Tabellen modifizieren. ## 3. Runtime Auto-Sync → Nicht Authoritative **Verantwortlich:** `Base.metadata.create_all()` (nur Test-Modus) - In Test-Umgebungen wird `create_all()` verwendet, um Tabellen ohne Alembic zu erstellen. - **Nicht authoritative** — ersetzt nie Migrationen. - In Produktion **verboten** — `prestart.sh` führt `alembic upgrade head` aus. - Bekannte Einschränkung: `create_all()` erstellt keine Indizes, Constraints oder erweiterte Typen (pgvector, ENUM, etc.) korrekt. ## Verbindliche Regeln | Ebene | Mechanismus | Authoritative? | Produktion? | |-------|-----------|----------------|-------------| | Core | Alembic | Ja | Ja | | Plugin | Plugin-Migrationen | Ja | Ja | | Runtime Auto-Sync | `create_all()` | Nein | Nur Tests | ## Schema-Änderungs-Workflow 1. **Core-Schema ändern:** - Modell in `app/models/` ändern - `alembic revision --autogenerate -m "description"` - Migration prüfen (Indizes, Constraints, Defaults) - `alembic upgrade head` lokal testen - Commit + Deploy (prestart.sh führt Migration aus) 2. **Plugin-Schema ändern:** - Modell in `app/plugins/builtins//models.py` ändern - Plugin-Migration in `app/plugins/builtins//migrations/` erstellen - `python scripts/sync_plugin_schema.py` testen - Commit + Deploy 3. **Niemals:** - `create_all()` in Produktion verwenden - Plugin-Tabellen ohne `tenant_id` erstellen - Core-Tabellen von Plugins aus ändern - Migrationen ohne Downgrade-Path erstellen