refactor(b3): dynamic entity registry, custom_fields permissions decoupled from contacts, write perms generated from registry

This commit is contained in:
Agent Zero
2026-08-23 20:54:04 +02:00
parent 7467c01d38
commit e3fb4728d7
5 changed files with 75 additions and 23 deletions
+39 -16
View File
@@ -235,22 +235,45 @@ async def list_all_permissions(
async def list_entity_registry(
current_user: dict = Depends(get_current_user),
):
"""List all registered entity types that support permissions."""
# Static list for now — will be dynamic from Permission Registry in Sprint 4
entity_types = [
{"entity_type": "contact", "label": "Kontakte", "table": "contacts"},
{"entity_type": "contact_folder", "label": "Ordner", "table": "contact_folders"},
{"entity_type": "address", "label": "Adressen", "table": "addresses"},
{"entity_type": "attachment", "label": "Anhänge", "table": "attachments"},
{"entity_type": "bank_account", "label": "Bankkonten", "table": "bank_accounts"},
{"entity_type": "workflow", "label": "Workflows", "table": "workflows"},
{"entity_type": "sequence", "label": "Sequenzen", "table": "sequences"},
{"entity_type": "saved_filter", "label": "Gespeicherte Filter", "table": "saved_filters"},
{"entity_type": "saved_view", "label": "Gespeicherte Ansichten", "table": "saved_views"},
{"entity_type": "webhook", "label": "Webhooks", "table": "webhooks"},
{"entity_type": "notification", "label": "Benachrichtigungen", "table": "notifications"},
{"entity_type": "custom_field_definition", "label": "Custom Fields", "table": "custom_field_definitions"},
]
"""List all registered entity types that support permissions.
Generated dynamically from the entity model registry (ARCH-016): core
models plus every entity registered by an active plugin at activation
time. Plugin entities appear automatically without touching this file.
"""
from app.services.entity_permission_service import ENTITY_MODELS
# Human-readable labels for known types; plugin entities fall back to a
# title-cased entity_type so they are still presentable.
_labels = {
"contact": "Kontakte",
"contact_folder": "Ordner",
"address": "Adressen",
"attachment": "Anhänge",
"bank_account": "Bankkonten",
"workflow": "Workflows",
"sequence": "Sequenzen",
"saved_filter": "Gespeicherte Filter",
"saved_view": "Gespeicherte Ansichten",
"webhook": "Webhooks",
"notification": "Benachrichtigungen",
"custom_field_definition": "Custom Fields",
}
seen_models: set[int] = set()
entity_types: list[dict[str, str]] = []
for entity_type, model_class in ENTITY_MODELS.items():
# Skip aliases pointing at the same model (contact/contacts/company)
if id(model_class) in seen_models:
continue
seen_models.add(id(model_class))
table = getattr(model_class, "__tablename__", f"{entity_type}s")
entity_types.append({
"entity_type": entity_type,
"label": _labels.get(entity_type, entity_type.replace("_", " ").title()),
"table": table,
})
entity_types.sort(key=lambda e: e["entity_type"])
return {"items": entity_types, "total": len(entity_types)}