REFACTOR: Contacts-Entities aus statischem ENTITY_MODELS entfernt — ContactsPlugin ist Single Source; + VORBESTAND: 12 ACL-Batch-Failures durch Suite-Isolation (relation users does not exist) #357

Closed
opened 2026-08-27 16:53:39 +00:00 by Leopoldadmin · 3 comments
Owner

Live gemessen 2026-08-27 (Kritikpunkte 9–11 gegengeprüft):

Doppelquelle bewiesen: ENTITY_MODELS in app/services/entity_permission_service.py enthielt statisch contact/contacts/company — während ContactsPlugin.get_entity_models() exakt dieselben drei Entities bereits dynamisch liefert. Der eigene Kommentar in der Datei ("Plugin models are registered dynamically via plugin.get_entity_models()") wurde von den Contacts-Einträgen verletzt.

Grundsatz (Kritikpunkt 10): is_core=True heißt Pflichtplugin/nicht deaktivierbar — NICHT Core-Verdrahtung. Die statischen Einträge waren Symptom der halbfertigen Contacts-Migration.

Fix (e1a59e7):

  1. Die 3 statischen Contacts-Einträge aus dem Core-Registry entfernt — ContactsPlugin.get_entity_models() ist Single Source of Truth.
  2. tests/conftest.py spiegelt den Produktions-Bootstrap (main.py lifespan) idempotent vor jedem Test: get_entity_models()register_entity_model() — garantiert Test-Isolation ohne statische Dublette.
  3. Neue Regressionstests tests/test_contacts_entity_registry.py (3/3 passed): Statik-Quelle weg (Source-Inspektion), Plugin liefert die Entities, Bootstrap registriert sie.

Bewiesener Vorbestand (separates Finding): Der ACL-Batch (entity_permissions + rbac_comprehensive + cross_tenant_security + contacts) zeigt 12 Failures identisch auf clean HEAD (Stash-Test: 12 failed/118 passed auf e1a59e7-Vorgänger UND mit Fix: 12 failed/121 passed — nur die 3 neuen Tests differieren). Ursache: Suite-Isolation — relation "users" does not exist in Nachfolger-Suiten (eine Suite zerstört/resetiert das DB-Schema). Gehört in ein eigenes Isolation-Bugfix-Paket.

Funktionserhalt: entity_permissions + cross_tenant_security Suiten vollständig grün; ruff modified-files 0 Fehler; create_app() OK.

Live gemessen 2026-08-27 (Kritikpunkte 9–11 gegengeprüft): **Doppelquelle bewiesen:** `ENTITY_MODELS` in `app/services/entity_permission_service.py` enthielt statisch `contact/contacts/company` — während `ContactsPlugin.get_entity_models()` exakt dieselben drei Entities bereits dynamisch liefert. Der eigene Kommentar in der Datei ("Plugin models are registered dynamically via plugin.get_entity_models()") wurde von den Contacts-Einträgen verletzt. **Grundsatz (Kritikpunkt 10):** `is_core=True` heißt Pflichtplugin/nicht deaktivierbar — NICHT Core-Verdrahtung. Die statischen Einträge waren Symptom der halbfertigen Contacts-Migration. **Fix (e1a59e7):** 1. Die 3 statischen Contacts-Einträge aus dem Core-Registry entfernt — `ContactsPlugin.get_entity_models()` ist Single Source of Truth. 2. `tests/conftest.py` spiegelt den Produktions-Bootstrap (main.py lifespan) idempotent vor jedem Test: `get_entity_models()` → `register_entity_model()` — garantiert Test-Isolation ohne statische Dublette. 3. Neue Regressionstests `tests/test_contacts_entity_registry.py` (3/3 passed): Statik-Quelle weg (Source-Inspektion), Plugin liefert die Entities, Bootstrap registriert sie. **Bewiesener Vorbestand (separates Finding):** Der ACL-Batch (entity_permissions + rbac_comprehensive + cross_tenant_security + contacts) zeigt **12 Failures identisch auf clean HEAD** (Stash-Test: 12 failed/118 passed auf e1a59e7-Vorgänger UND mit Fix: 12 failed/121 passed — nur die 3 neuen Tests differieren). Ursache: Suite-Isolation — `relation "users" does not exist` in Nachfolger-Suiten (eine Suite zerstört/resetiert das DB-Schema). Gehört in ein eigenes Isolation-Bugfix-Paket. **Funktionserhalt:** entity_permissions + cross_tenant_security Suiten vollständig grün; ruff modified-files 0 Fehler; `create_app()` OK.
Leopoldadmin added the bughigh labels 2026-08-27 16:53:39 +00:00
Author
Owner

Umgesetzt in Commit e1a59e7 — deployed und live verifiziert (2026-08-27 18:59):

Fix

  1. Statische Contacts-Dublette entfernt: contact/contacts/company aus dem Core-ENTITY_MODELS gelöscht — ContactsPlugin.get_entity_models() ist die einzige Quelle (wie bei jedem anderen Plugin auch).
  2. Test-Bootstrap spiegelt Produktion: tests/conftest.py registriert vor jedem Test idempotent alle Plugin-Entity-Models (gleicher Mechanismus wie main.py lifespan) — Isolation ohne statische Dublette.
  3. Keine Über-Korrektur: contact_folder, address, bank_account, attachment etc. bleiben korrekt im Core-Registry (werden von keinem Plugin geliefert — echte Core-Entities).

Verifikation (Live-Messung)

  • Neue Regressionstests tests/test_contacts_entity_registry.py: 3/3 passed (Source-Inspektion beweist Statik-Weg; Plugin liefert die Entities; Bootstrap registriert sie)
  • ACL-Funktionserhalt: entity_permissions + cross_tenant_security Suiten grün
  • ruff modified-files: 0 Fehler · create_app() OK · Full Deploy SUCCESS · Health healthy · Alembic 0142 OK

Offenes Vorbestand-Finding (separates Paket)

Der kombinierte ACL-Batch zeigt 12 Failures identisch auf clean HEAD (Stash-Test bewiesen: 118 passed ohne / 121 passed mit Fix — nur die 3 neuen Tests differieren). Ursache: Suite-Isolation (relation "users" does not exist in Nachfolger-Suiten — eine Suite zerstört das DB-Schema). Wird als eigenes Isolation-Bugfix-Paket behandelt, nicht hier vermengt.

**Umgesetzt in Commit `e1a59e7` — deployed und live verifiziert (2026-08-27 18:59):** ## Fix 1. **Statische Contacts-Dublette entfernt:** `contact/contacts/company` aus dem Core-`ENTITY_MODELS` gelöscht — `ContactsPlugin.get_entity_models()` ist die einzige Quelle (wie bei jedem anderen Plugin auch). 2. **Test-Bootstrap spiegelt Produktion:** `tests/conftest.py` registriert vor jedem Test idempotent alle Plugin-Entity-Models (gleicher Mechanismus wie `main.py` lifespan) — Isolation ohne statische Dublette. 3. **Keine Über-Korrektur:** `contact_folder`, `address`, `bank_account`, `attachment` etc. bleiben korrekt im Core-Registry (werden von keinem Plugin geliefert — echte Core-Entities). ## Verifikation (Live-Messung) - Neue Regressionstests `tests/test_contacts_entity_registry.py`: **3/3 passed** (Source-Inspektion beweist Statik-Weg; Plugin liefert die Entities; Bootstrap registriert sie) - ACL-Funktionserhalt: entity_permissions + cross_tenant_security Suiten grün - ruff modified-files: 0 Fehler · `create_app()` OK · Full Deploy SUCCESS · Health healthy · Alembic 0142 OK ## Offenes Vorbestand-Finding (separates Paket) Der kombinierte ACL-Batch zeigt **12 Failures identisch auf clean HEAD** (Stash-Test bewiesen: 118 passed ohne / 121 passed mit Fix — nur die 3 neuen Tests differieren). Ursache: Suite-Isolation (`relation "users" does not exist` in Nachfolger-Suiten — eine Suite zerstört das DB-Schema). Wird als eigenes Isolation-Bugfix-Paket behandelt, nicht hier vermengt.
Author
Owner

Suite-Isolation-Teil umgesetzt in Commit b691dd3 (2026-08-28 00:02) — ACL-Batch jetzt vollständig grün.

Mechanismus (Live-Messung)

Die mail_app-Fixture in tests/test_rbac_comprehensive.py ruft im Teardown close_engine() — das disposiert und setzt alle globalen Engines auf None (app/core/db/__init__.py Zeile 348–353). Jede nachfolgende Test-Suite lief ohne funktionierende Engine-Registrierung → relation "users" does not exist in 12 Tests.

Korrektur-Ergänzung der Messung: Nach dem rbac-Lauf existierten 129 Tabellen, users war leer (0 Zeilen) — die Daten wurden durch die Suite-Interaktion geleert, das Schema blieb. Beides floss in die Diagnose ein.

Fix

Nach close_engine() im Teardown: reset_engine_for_testing(engine) — die conftest-Engine wird als globale Engine wiederhergestellt (Spiegelung des Produktions-Bootstrap in main.py lifespan).

Verifikation (Live-Messung)

ACL-Batch (rbac_comprehensive + contacts + entity_permissions + cross_tenant_security):

  • Vorher: 12 failed / 118 passed (Stash-Verifiziert als Vorbestand auf clean HEAD)
  • Nachher: 130 passed — alle 12 Failures behoben

Nur tests/ geändert — kein Production-Deploy nötig (Tests laufen nicht in Produktion).

**Suite-Isolation-Teil umgesetzt in Commit `b691dd3` (2026-08-28 00:02) — ACL-Batch jetzt vollständig grün.** ## Mechanismus (Live-Messung) Die `mail_app`-Fixture in `tests/test_rbac_comprehensive.py` ruft im Teardown `close_engine()` — das disposiert **und setzt alle globalen Engines auf None** (`app/core/db/__init__.py` Zeile 348–353). Jede nachfolgende Test-Suite lief ohne funktionierende Engine-Registrierung → `relation "users" does not exist` in 12 Tests. **Korrektur-Ergänzung der Messung:** Nach dem rbac-Lauf existierten 129 Tabellen, `users` war leer (0 Zeilen) — die Daten wurden durch die Suite-Interaktion geleert, das Schema blieb. Beides floss in die Diagnose ein. ## Fix Nach `close_engine()` im Teardown: `reset_engine_for_testing(engine)` — die conftest-Engine wird als globale Engine wiederhergestellt (Spiegelung des Produktions-Bootstrap in `main.py` lifespan). ## Verifikation (Live-Messung) ACL-Batch (rbac_comprehensive + contacts + entity_permissions + cross_tenant_security): - Vorher: **12 failed / 118 passed** (Stash-Verifiziert als Vorbestand auf clean HEAD) - Nachher: **130 passed — alle 12 Failures behoben** Nur `tests/` geändert — kein Production-Deploy nötig (Tests laufen nicht in Produktion).
Author
Owner

W4b-Verifikation (2026-08-28 08:49):

Funktionserhalt

  • 10/11 tests/test_saved_filters.py passed
  • create_app() OK
  • tsc --noEmit exit 0
  • Production-Build exit 0

Vorbestand bewiesen (Stash-Test)

  • test_create_saved_filter_invalid_entity_returns_422: identisch auf clean HEAD — der Test erwartet 422, aber _validate_entity_type wirft seit jeher 400 (HTTPException 400). Vorbestand-Bug, nicht W4b.
  • AppShell.test.tsx no tests / useCurrentUser mock-Fehler: identisch auf clean HEAD — die Testdatei mockt @/api/hooks ohne den useCurrentUser-Export.

Offen

  • Test 422 vs 400: Test-Expectation anpassen oder Statuscode korrigieren (separates Paket)
  • AppShell mock-Fix: useCurrentUser-Export im Mock ergänzen (separates Paket)
**W4b-Verifikation (2026-08-28 08:49):** ## Funktionserhalt - 10/11 tests/test_saved_filters.py passed - create_app() OK - tsc --noEmit exit 0 - Production-Build exit 0 ## Vorbestand bewiesen (Stash-Test) - `test_create_saved_filter_invalid_entity_returns_422`: **identisch auf clean HEAD** — der Test erwartet 422, aber `_validate_entity_type` wirft seit jeher **400** (HTTPException 400). Vorbestand-Bug, nicht W4b. - AppShell.test.tsx `no tests` / `useCurrentUser` mock-Fehler: **identisch auf clean HEAD** — die Testdatei mockt `@/api/hooks` ohne den `useCurrentUser`-Export. ## Offen - Test 422 vs 400: Test-Expectation anpassen oder Statuscode korrigieren (separates Paket) - AppShell mock-Fix: `useCurrentUser`-Export im Mock ergänzen (separates Paket)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Leopoldadmin/leocrm#357