fix(d3): systemischer Permission-Resolver-Bug behoben — DMS/Mail get_entity_models-Overrides ergänzt (dms_file/dms_folder/file/mail_account fehlten im ENTITY_MODELS-Mapping → ValueError bei allen Entity-Freigaben zur Laufzeit); pgvector-Extension in conftest db_setup verankert; test_permissions 22/22 grün; Resolver-Auflösung aller 4 Typen direkt bewiesen
Check Cross-Plugin Imports / check (push) Has been cancelled

This commit is contained in:
Agent Zero
2026-08-24 10:07:48 +02:00
parent 0768cfb29a
commit ef90d57f0a
4 changed files with 29 additions and 0 deletions
+6
View File
@@ -71,6 +71,12 @@
| D1-d | ai_proactive Produktionsbug: 4 Stellen nutzten snake_case-Attribute auf CalendarContract (`_cal.calendar_entry`), Contract exponiert PascalCase-Klassenattribute → AttributeError zur Laufzeit (get_open_tasks_handler, gather_context ×2, mail→calendar Konversion) | ✅ Auf `_cal.CalendarEntry`/`CalendarEntryLink`/`Calendar` umgestellt; 5 ai_proactive-Failures behoben | f6e117b |
| D1-e | 2 stale Rate-Limit-Tests mockten entferntes services.get_cache (bb36378 zentralisierte Rate-Limiting auf check_rate_limit) | ✅ Tests auf neue Grenze umgestellt (patch app.core.rate_limit.check_rate_limit); disabled-Test braucht keinen Redis-Patch mehr | f6e117b |
| D1-f | SystemSettings-Schema-Drift (P1): 10b1f83 fügte backup_interval/backup_retention_days/backup_destination zu Schema+Service+Frontend hinzu, aber Model-Spalten+Migration fehlten → Settings-API Create/Read 500 TypeError; Stash-verifiziert als Vorbestand | ✅ Model-Spalten ergänzt + Migration 0142 (server_defaults daily/7/local); TestSystemSettingsRoutes 4/4 grün; Fresh-DB-Kette 0001→0142 exit=0; Spalten via information_schema bewiesen | — |
| D3-a | ARCH-055: errors.py nutzte error.userAgent, ErrorReport definiert user_agent → AttributeError zur Laufzeit beim Frontend-Error-Reporting | ✅ Beide Zugriffe auf error.user_agent korrigiert; ruff clean | 0768cfb |
| D3-b | ARCH-056: roles.py SYSTEM_PERMISSIONS hardcoded (36 Permissions) duplizierte CORE_PERMISSIONS (47) — Drift bewiesen (roles-only: [], core-only: 11) | ✅ SYSTEM_PERMISSIONS aus CORE_PERMISSIONS abgeleitet (category→system für Frontend-Gruppierung); keine Imports/Count-Assertions betroffen | 0768cfb |
| D3-c | ARCH-057: registry._plugins.items() privater Zugriff in roles.py | ✅ Öffentliche API list_discovered()+get_plugin() genutzt | 0768cfb |
| D3-d | Systemischer P1-Bug: DMS/Mail überschrieben get_entity_models() nicht → 'dms_file'/'dms_folder'/'file'/'mail_account' fehlten im ENTITY_MODELS-Mapping → ValueError bei allen Entity-Freigaben/Berechtigungen zur Laufzeit (28 Mail-Test-Failures + 2 test_permissions-Failures, Stash-verifiziert) | ✅ Overrides ergänzt (DMS: dms_file/dms_folder/file-Alias; Mail: mail_account); test_permissions 22/22 grün; Resolver-Auflösung aller 4 Typen direkt bewiesen | — |
| D3-e | conftest db_setup: pgvector-Extension fehlte nach DB-Recreate → alle create_all-Läufe scheiterten an 'type vector does not exist' | ✅ CREATE EXTENSION IF NOT EXISTS vector in db_setup-Fixture verankert (nach CREATE SCHEMA, vor alembic upgrade head) | — |
| D3-f | BUG-027029/031035/071 (falsche Test-Pfade/Payloads): Recherche zeigte — falsche Pfade existieren NICHT mehr in tests/, reale API hat korrekte Prefixe (/api/v1/user/preferences, /api/v1/permissions, /api/v1/mail) | ✅ Als obsolet/bereits behoben dokumentiert | — |
**Block A ABGESCHLOSSEN** — Gate A bestanden (32f63ad).
**Block B ABGESCHLOSSEN** — Gate B bestanden (alle 5 Checks bewiesen).
+13
View File
@@ -54,6 +54,19 @@ class DmsPlugin(BasePlugin):
contract_version="1.0.0",
)
def get_entity_models(self) -> dict[str, type]:
"""Entity types owned by DMS for the permission resolver.
``file`` is a legacy alias still used by the permissions routes.
"""
from app.plugins.builtins.dms.models import File, Folder
return {
"dms_file": File,
"dms_folder": Folder,
"file": File,
}
async def on_activate(self, db, service_container, event_bus) -> None:
"""Activate plugin: register restore config + history hooks."""
await super().on_activate(db, service_container, event_bus)
+6
View File
@@ -159,6 +159,12 @@ class MailPlugin(BasePlugin):
contract_version="1.0.0",
)
def get_entity_models(self) -> dict[str, type]:
"""Entity types owned by Mail for the permission resolver."""
from app.plugins.builtins.mail.models import MailAccount
return {"mail_account": MailAccount}
async def on_activate(
self, db, service_container, event_bus
) -> None:
+4
View File
@@ -167,6 +167,10 @@ def db_setup():
conn.execute(text("DROP SCHEMA IF EXISTS public CASCADE;"))
conn.execute(text("CREATE SCHEMA public;"))
conn.execute(text("GRANT ALL ON SCHEMA public TO leocrm;"))
# Plugin models use the pgvector Vector type (contacts.embedding);
# the extension lives at database level and must exist before
# alembic creates those tables.
conn.execute(text("CREATE EXTENSION IF NOT EXISTS vector"))
except Exception:
conn.rollback()
conn.execute(text("SET lock_timeout = '10s';"))