"""Tasks plugin — manage free tasks/activities linked to contacts.""" from __future__ import annotations from app.plugins.base import BasePlugin from app.plugins.manifest import ( CronJobContribution, FrontendMenuItem, FrontendPageRoute, PluginManifest, PluginRouteDef, ) class TasksPlugin(BasePlugin): """Tasks plugin for managing activities (calls, notes, visits) linked to contacts.""" manifest = PluginManifest( name="tasks", version="1.0.0", display_name="Tasks", description="Manage free tasks/activities with status, priority, due dates, and contact links.", dependencies=["permissions"], routes=[ PluginRouteDef( path="/api/v1/tasks", module="app.plugins.builtins.tasks.routes", router_attr="router", ), ], events=[], migrations=["0001_initial.sql", "0002_unified_task_system.sql"], permissions=[ "tasks:read", "tasks:write", "tasks:delete", ], is_core=True, menu_items=[ FrontendMenuItem( label_key="nav.tasks", label="Aufgaben", path="/tasks", icon="CheckSquare", order=30, ), ], page_routes=[ FrontendPageRoute( path="/tasks", component="@/pages/Tasks", protected=True, order=30, ), ], cron_jobs=[ CronJobContribution( name="tasks_due_reminder", cron_expression="0 8 * * *", job_type="custom", target_name="tasks_due_reminder", plugin_name="tasks", ), ], author="LeoCRM Team", min_app_version="1.0.0", hooks=["contact.after_create"], contract_version="1.0.0") def get_job_modules(self) -> list[str]: return ["app.plugins.builtins.tasks.jobs"] def get_entity_models(self) -> dict[str, type]: from app.plugins.builtins.tasks.models import Task return {"task": Task} async def on_activate(self, db, service_container, event_bus) -> None: """Activate plugin: register restore config + history hooks + AI tools.""" await super().on_activate(db, service_container, event_bus) # Register task AI tools (F-TASK-AGENT) try: from app.plugins.builtins.ai_assistant.contracts import get_tool_registry from app.plugins.builtins.tasks.ai_tools import register_task_tools register_task_tools(get_tool_registry()) except Exception: import logging logging.getLogger(__name__).exception("Failed to register task AI tools") # Register restore config for Task entities (P0-7 fix) from app.core.restore_registry import RestoreConfig, get_restore_registry from app.plugins.builtins.tasks.models import Task get_restore_registry().register(RestoreConfig( entity_type="task", model_class=Task, restore_permission="tasks:write", excluded_fields=frozenset({"created_by", "assigned_to", "contact_id"}), )) # Register history hooks for Task entities (P0-8 fix) from app.core.history_hooks import register_history_hooks from app.core.hooks import get_hook_registry register_history_hooks( get_hook_registry(), "task", "task.after_create", "task.after_update", "task.after_delete", owner_tag="tasks", ) async def on_deactivate( self, db, service_container, event_bus ) -> None: """Deactivate plugin: unregister contract, restore, history, events, AI tools.""" # Unregister task AI tools (F-TASK-AGENT) try: from app.plugins.builtins.ai_assistant.contracts import get_tool_registry get_tool_registry().unregister_plugin("tasks") except Exception: import logging logging.getLogger(__name__).exception("Failed to unregister task AI tools") # Contract abmelden from app.plugins.builtins.contracts import get_contract_registry get_contract_registry().unregister(self.manifest.name) # Unregister restore config (P0-7 fix) from app.core.restore_registry import get_restore_registry get_restore_registry().unregister("task") # Unregister history hooks (free functions, not bound methods) from app.core.hooks import get_hook_registry get_hook_registry().unregister_actions_by_owner("task.after_create", "tasks") get_hook_registry().unregister_actions_by_owner("task.after_update", "tasks") get_hook_registry().unregister_actions_by_owner("task.after_delete", "tasks") await super().on_deactivate(db, service_container, event_bus)