gateway/modules/datamodels/datamodelMembership.py
2026-04-26 08:31:35 +02:00

167 lines
6 KiB
Python

# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""
Membership models: UserMandate, FeatureAccess, and Junction Tables.
Diese Models definieren die m:n Beziehungen zwischen User, Mandate und FeatureInstance.
Rollen werden über Junction Tables verknüpft für saubere CASCADE DELETE.
"""
import uuid
from pydantic import BaseModel, Field
from modules.datamodels.datamodelBase import PowerOnModel
from modules.shared.i18nRegistry import i18nModel
@i18nModel("Benutzer-Mandant")
class UserMandate(PowerOnModel):
"""
User-Mitgliedschaft in einem Mandanten.
Kein User gehört direkt zu einem Mandanten - Zugehörigkeit wird über dieses Model gesteuert.
"""
id: str = Field(
default_factory=lambda: str(uuid.uuid4()),
description="Unique ID of the user-mandate membership",
json_schema_extra={"label": "ID", "frontend_type": "text", "frontend_readonly": True, "frontend_visible": False, "frontend_required": False}
)
userId: str = Field(
description="FK → User.id (CASCADE DELETE)",
json_schema_extra={
"label": "Benutzer",
"frontend_type": "select",
"frontend_readonly": False,
"frontend_required": True,
"fk_model": "User",
"fk_label_field": "username",
"fk_target": {"db": "poweron_app", "table": "User"},
},
)
mandateId: str = Field(
description="FK → Mandate.id (CASCADE DELETE)",
json_schema_extra={
"label": "Mandant",
"frontend_type": "select",
"frontend_readonly": False,
"frontend_required": True,
"fk_model": "Mandate",
"fk_label_field": "label",
"fk_target": {"db": "poweron_app", "table": "Mandate"},
},
)
enabled: bool = Field(
default=True,
description="Whether this membership is enabled",
json_schema_extra={"label": "Aktiviert", "frontend_type": "checkbox", "frontend_readonly": False, "frontend_required": False}
)
@i18nModel("Feature-Zugang")
class FeatureAccess(PowerOnModel):
"""
User-Zugriff auf eine Feature-Instanz.
Definiert welche User auf welche Feature-Instanzen zugreifen können.
"""
id: str = Field(
default_factory=lambda: str(uuid.uuid4()),
description="Unique ID of the feature access",
json_schema_extra={"label": "ID", "frontend_type": "text", "frontend_readonly": True, "frontend_visible": False, "frontend_required": False}
)
userId: str = Field(
description="FK → User.id (CASCADE DELETE)",
json_schema_extra={
"label": "Benutzer",
"frontend_type": "select",
"frontend_readonly": False,
"frontend_required": True,
"fk_model": "User",
"fk_label_field": "username",
"fk_target": {"db": "poweron_app", "table": "User"},
},
)
featureInstanceId: str = Field(
description="FK → FeatureInstance.id (CASCADE DELETE)",
json_schema_extra={
"label": "Feature-Instanz",
"frontend_type": "select",
"frontend_readonly": False,
"frontend_required": True,
"fk_model": "FeatureInstance",
"fk_label_field": "label",
"fk_target": {"db": "poweron_app", "table": "FeatureInstance"},
},
)
enabled: bool = Field(
default=True,
description="Whether this feature access is enabled",
json_schema_extra={"label": "Aktiviert", "frontend_type": "checkbox", "frontend_readonly": False, "frontend_required": False}
)
@i18nModel("Benutzer-Mandant-Rolle")
class UserMandateRole(PowerOnModel):
"""
Junction Table: UserMandate zu Role.
Ermöglicht CASCADE DELETE auf Datenbankebene.
"""
id: str = Field(
default_factory=lambda: str(uuid.uuid4()),
description="Unique ID of the junction record",
json_schema_extra={"label": "ID", "frontend_type": "text", "frontend_readonly": True, "frontend_visible": False, "frontend_required": False}
)
userMandateId: str = Field(
description="FK → UserMandate.id (CASCADE DELETE)",
json_schema_extra={
"label": "Benutzer-Mandant",
"frontend_type": "text",
"frontend_readonly": True,
"frontend_required": True,
"fk_target": {"db": "poweron_app", "table": "UserMandate"},
},
)
roleId: str = Field(
description="FK → Role.id (CASCADE DELETE)",
json_schema_extra={
"label": "Rolle",
"frontend_type": "select",
"frontend_readonly": False,
"frontend_required": True,
"fk_model": "Role",
"fk_label_field": "roleLabel",
"fk_target": {"db": "poweron_app", "table": "Role"},
},
)
@i18nModel("Feature-Zugang-Rolle")
class FeatureAccessRole(PowerOnModel):
"""
Junction Table: FeatureAccess zu Role.
Ermöglicht CASCADE DELETE auf Datenbankebene.
"""
id: str = Field(
default_factory=lambda: str(uuid.uuid4()),
description="Unique ID of the junction record",
json_schema_extra={"label": "ID", "frontend_type": "text", "frontend_readonly": True, "frontend_visible": False, "frontend_required": False}
)
featureAccessId: str = Field(
description="FK → FeatureAccess.id (CASCADE DELETE)",
json_schema_extra={
"label": "Feature-Zugang",
"frontend_type": "text",
"frontend_readonly": True,
"frontend_required": True,
"fk_target": {"db": "poweron_app", "table": "FeatureAccess"},
},
)
roleId: str = Field(
description="FK → Role.id (CASCADE DELETE)",
json_schema_extra={
"label": "Rolle",
"frontend_type": "select",
"frontend_readonly": False,
"frontend_required": True,
"fk_model": "Role",
"fk_label_field": "roleLabel",
"fk_target": {"db": "poweron_app", "table": "Role"},
},
)