# Copyright (c) 2025 Patrick Motsch # All rights reserved. """Feature models: Feature, FeatureInstance.""" import uuid from typing import Optional, Dict, Any from pydantic import BaseModel, Field from modules.shared.attributeUtils import registerModelLabels from modules.datamodels.datamodelUtils import TextMultilingual class Feature(BaseModel): """ Feature-Definition (global, z.B. 'trustee', 'chatbot'). Features sind die verfügbaren Funktionalitäten der Plattform. """ code: str = Field( description="Unique feature code (Primary Key), z.B. 'trustee', 'chatbot'", json_schema_extra={"frontend_type": "text", "frontend_readonly": False, "frontend_required": True} ) label: TextMultilingual = Field( description="Feature label in multiple languages (I18n)", json_schema_extra={"frontend_type": "multilingual", "frontend_readonly": False, "frontend_required": True} ) icon: str = Field( default="", description="Icon identifier for the feature", json_schema_extra={"frontend_type": "text", "frontend_readonly": False, "frontend_required": False} ) registerModelLabels( "Feature", {"en": "Feature", "de": "Feature", "fr": "Fonctionnalité"}, { "code": {"en": "Code", "de": "Code", "fr": "Code"}, "label": {"en": "Label", "de": "Bezeichnung", "fr": "Libellé"}, "icon": {"en": "Icon", "de": "Symbol", "fr": "Icône"}, }, ) class FeatureInstance(BaseModel): """ Instanz eines Features in einem Mandanten. Ein Mandant kann mehrere Instanzen desselben Features haben. """ id: str = Field( default_factory=lambda: str(uuid.uuid4()), description="Unique ID of the feature instance", json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": False} ) featureCode: str = Field( description="FK → Feature.code", json_schema_extra={"frontend_type": "select", "frontend_readonly": True, "frontend_required": True} ) mandateId: str = Field( description="FK → Mandate.id (CASCADE DELETE)", json_schema_extra={"frontend_type": "text", "frontend_readonly": True, "frontend_required": True} ) label: str = Field( default="", description="Instance label, z.B. 'Buchhaltung 2025'", json_schema_extra={"frontend_type": "text", "frontend_readonly": False, "frontend_required": True} ) enabled: bool = Field( default=True, description="Whether this feature instance is enabled", json_schema_extra={"frontend_type": "checkbox", "frontend_readonly": False, "frontend_required": False} ) config: Optional[Dict[str, Any]] = Field( default=None, description="Instance-specific configuration (JSONB). Structure depends on featureCode.", json_schema_extra={"frontend_type": "json", "frontend_readonly": False, "frontend_required": False} ) registerModelLabels( "FeatureInstance", {"en": "Feature Instance", "de": "Feature-Instanz", "fr": "Instance de fonctionnalité"}, { "id": {"en": "ID", "de": "ID", "fr": "ID"}, "featureCode": {"en": "Feature", "de": "Feature", "fr": "Fonctionnalité"}, "mandateId": {"en": "Mandate", "de": "Mandant", "fr": "Mandat"}, "label": {"en": "Label", "de": "Bezeichnung", "fr": "Libellé"}, "enabled": {"en": "Enabled", "de": "Aktiviert", "fr": "Activé"}, "config": {"en": "Configuration", "de": "Konfiguration", "fr": "Configuration"}, }, )