Files
leocrm/app/core/event_bus.py
T
Agent Zero 6e7e39d101 fix: Event-bus workflow trigger, RBAC on all routes, search provider, events, cron jobs
Critical fixes:
- Event Bus → Workflow auto-trigger: wildcard subscription starts workflows on matching events
- Kommunikation routes: require_permission on all 30+ endpoints (comm:read/write/delete/manage)
- Permissions routes: require_permission('permissions:admin') on all management endpoints
- CompanySearchProvider registered in auto_register_providers()

Medium fixes:
- system_notif events: 10 event_bus.publish() calls added (lead.created, contact.created/updated,
  task.created/overdue, mail.received, user.created, workflow.completed, notification.created, backup.*)
- Cron jobs: backup_check (daily), search_index_check (daily), workflow_timeout (5min) registered
- AI tool permission: call_crm_api now requires 'ai:write' permission
- New file: automation/jobs.py with backup_check and search_index_check functions
2026-07-25 03:22:55 +02:00

57 lines
1.9 KiB
Python

"""In-process event bus for publish/subscribe."""
from __future__ import annotations
import asyncio
from collections import defaultdict
from collections.abc import Callable, Coroutine
from typing import Any
EventHandler = Callable[[dict[str, Any]], Coroutine[Any, Any, None]]
class EventBus:
"""Simple async event bus for in-process pub/sub."""
def __init__(self) -> None:
self._handlers: dict[str, list[EventHandler]] = defaultdict(list)
def subscribe(self, event_name: str, handler: EventHandler) -> None:
"""Subscribe a handler to an event."""
self._handlers[event_name].append(handler)
def unsubscribe(self, event_name: str, handler: EventHandler) -> None:
"""Unsubscribe a handler from an event."""
if event_name in self._handlers:
self._handlers[event_name] = [h for h in self._handlers[event_name] if h is not handler]
async def publish(self, event_name: str, payload: dict[str, Any]) -> None:
"""Publish an event to all subscribers."""
handlers = self._handlers.get(event_name, [])
# Also notify wildcard subscribers (catch-all '*' handlers)
wildcard_handlers = self._handlers.get('*', [])
all_handlers = handlers + wildcard_handlers
tasks = [asyncio.create_task(h(payload)) for h in all_handlers]
if tasks:
await asyncio.gather(*tasks, return_exceptions=True)
# Global event bus instance
_event_bus = EventBus()
def get_event_bus() -> EventBus:
"""Get the global event bus."""
return _event_bus
def register_workflow_event_handlers() -> None:
"""Register workflow event handlers on the global event bus.
Subscribes to events that can trigger workflows (user.created, etc.).
Should be called during application startup.
"""
from app.workflows.engine import register_workflow_event_handlers as _register
_register()