"""Kommunikation plugin — unified messaging: chat, AI, system, messenger.""" from __future__ import annotations import logging from typing import Any from app.plugins.base import BasePlugin from app.plugins.manifest import FrontendMenuItem, FrontendPageRoute, PluginManifest, PluginRouteDef logger = logging.getLogger(__name__) class KommunikationPlugin(BasePlugin): """Unified messaging plugin: conversations, messages, participants, WebSocket, rich content.""" manifest = PluginManifest( name="kommunikation", version="1.0.0", display_name="Kommunikation", description=( "Unified Messaging: Chat, KI, System, Messenger — " "alles ist ein Teilnehmer." ), dependencies=["permissions", "dms"], routes=[ PluginRouteDef( path="/api/v1/comm", module="app.plugins.builtins.kommunikation.routes", router_attr="router", ), ], events=[ "message.received", "message.sent", "conversation.created", "conversation.updated", "participant.joined", "participant.left", "reaction.added", ], migrations=["0001_initial.sql", "0002_system_channel_folders.sql"], permissions=[ "comm:read", "comm:write", "comm:create", "comm:manage", "comm:admin", "comm:delete", ], is_core=True, menu_items=[ FrontendMenuItem(label_key='nav.communication', label='Kommunikation', path='/communication', icon='MessageSquare', order=80, permission='comm:read'), ], page_routes=[ FrontendPageRoute(path='/communication', component='@/pages/Communication', protected=True, permission='comm:read'), ], author="LeoCRM Team", min_app_version="1.0.0", contract_version="1.0.0", ) def get_entity_models(self) -> dict[str, type]: from app.plugins.builtins.kommunikation.models import CommConversation return {"comm_conversation": CommConversation} async def on_activate(self, db, service_container, event_bus) -> None: """Register participant registry and WebSocket manager.""" await super().on_activate(db, service_container, event_bus) # Register WebSocket manager as a shared service from app.plugins.builtins.kommunikation.websocket_manager import WebSocketManager ws_manager = WebSocketManager() service_container.register("comm_websocket", ws_manager) # Register Mini-App registry as a shared service from app.plugins.builtins.kommunikation.miniapp_registry import get_miniapp_registry miniapp_registry = get_miniapp_registry() service_container.register("comm_miniapps", miniapp_registry) # Register built-in mini-apps miniapp_registry.register( app_id="contact_picker", name="Kontakt wählen", icon="👤", description="Kontakt aus dem CRM im Chat teilen", plugin_name="kommunikation", render_schema={"type": "object", "properties": {"contact_id": {"type": "string"}}}, ) miniapp_registry.register( app_id="file_share", name="Datei teilen", icon="📎", description="Datei aus dem DMS im Chat teilen", plugin_name="kommunikation", render_schema={"type": "object", "properties": {"file_id": {"type": "string"}}}, ) miniapp_registry.register( app_id="calendar_invite", name="Termin teilen", icon="📅", description="Kalender-Termin im Chat teilen", plugin_name="kommunikation", render_schema={"type": "object", "properties": {"event_id": {"type": "string"}}}, ) miniapp_registry.register( app_id="mail_forward", name="E-Mail weiterleiten", icon="✉️", description="E-Mail im Chat weiterleiten", plugin_name="kommunikation", render_schema={"type": "object", "properties": {"mail_id": {"type": "string"}}}, ) miniapp_registry.register( app_id="ai_search", name="KI Suche", icon="🔍", description="KI-gestützte Suche im CRM starten", plugin_name="kommunikation", render_schema={"type": "object", "properties": {"query": {"type": "string"}}}, ) miniapp_registry.register( app_id="task_create", name="Aufgabe erstellen", icon="✅", description="Aufgabe aus dem Chat erstellen", plugin_name="kommunikation", render_schema={"type": "object", "properties": {"title": {"type": "string"}, "due_date": {"type": "string"}}}, ) logger.info("Kommunikation plugin activated — WebSocket + MiniApp registries ready (6 mini-apps registered)") async def on_deactivate(self, db, service_container, event_bus) -> None: """Clean up registries.""" # Contract abmelden from app.plugins.builtins.contracts import get_contract_registry get_contract_registry().unregister(self.manifest.name) # Remove services registered in on_activate BEFORE super() so that # event handlers being unsubscribed can no longer reach them (ARCH-033). for service_name in ("comm_websocket", "comm_miniapps"): if service_container.has(service_name): service_container.remove(service_name) logger.info("Removed '%s' from service container", service_name) await super().on_deactivate(db, service_container, event_bus) logger.info("Kommunikation plugin deactivated") def get_notification_types(self) -> list[dict[str, Any]]: return [ { "type_key": "comm_message", "category": "communication", "label": "Neue Nachricht", "description": "Neue Nachricht in einer Konversation", "is_enabled_by_default": True, }, { "type_key": "comm_mention", "category": "communication", "label": "Erwähnung", "description": "Du wurdest in einer Nachricht erwähnt", "is_enabled_by_default": True, }, ]