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
This commit is contained in:
Agent Zero
2026-07-25 03:22:55 +02:00
parent b01c798739
commit 6e7e39d101
14 changed files with 266 additions and 22 deletions
+15 -15
View File
@@ -11,7 +11,7 @@ from fastapi import APIRouter, Depends, HTTPException, Query, UploadFile, File,
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.db import get_db
from app.deps import get_current_user
from app.deps import get_current_user, require_permission
from app.plugins.builtins.kommunikation.rbac import CommRBAC
from app.plugins.builtins.kommunikation.schemas import (
ConversationCreate,
@@ -200,7 +200,7 @@ async def unmute_conv(
# ─── Participants ───
@router.post("/conversations/{conversation_id}/participants")
@router.post("/conversations/{conversation_id}/participants", dependencies=[Depends(require_permission("comm:manage"))])
async def add_participant_endpoint(
conversation_id: str,
body: ParticipantAdd,
@@ -218,7 +218,7 @@ async def add_participant_endpoint(
return result
@router.delete("/conversations/{conversation_id}/participants/{participant_id}")
@router.delete("/conversations/{conversation_id}/participants/{participant_id}", dependencies=[Depends(require_permission("comm:manage"))])
async def remove_participant_endpoint(
conversation_id: str,
participant_id: str,
@@ -238,7 +238,7 @@ async def remove_participant_endpoint(
return {"success": True}
@router.patch("/conversations/{conversation_id}/participants/{participant_id}")
@router.patch("/conversations/{conversation_id}/participants/{participant_id}", dependencies=[Depends(require_permission("comm:manage"))])
async def change_participant_role(
conversation_id: str,
participant_id: str,
@@ -259,7 +259,7 @@ async def change_participant_role(
# ─── Messages ───
@router.get("/conversations/{conversation_id}/messages")
@router.get("/conversations/{conversation_id}/messages", dependencies=[Depends(require_permission("comm:read"))])
async def get_conv_messages(
conversation_id: str,
page: int = Query(1, ge=1),
@@ -278,7 +278,7 @@ async def get_conv_messages(
return await get_messages(db, tenant_id, conv_id, page, page_size, before_id)
@router.post("/conversations/{conversation_id}/messages")
@router.post("/conversations/{conversation_id}/messages", dependencies=[Depends(require_permission("comm:write"))])
async def send_conv_message(
conversation_id: str,
body: MessageCreate,
@@ -303,7 +303,7 @@ async def send_conv_message(
)
@router.patch("/messages/{message_id}")
@router.patch("/messages/{message_id}", dependencies=[Depends(require_permission("comm:write"))])
async def update_msg(
message_id: str,
body: MessageUpdate,
@@ -322,7 +322,7 @@ async def update_msg(
return {"success": True}
@router.delete("/messages/{message_id}")
@router.delete("/messages/{message_id}", dependencies=[Depends(require_permission("comm:delete"))])
async def delete_msg(
message_id: str,
current_user: dict = Depends(get_current_user),
@@ -338,7 +338,7 @@ async def delete_msg(
# ─── Attachments ───
@router.post("/messages/{message_id}/attachments")
@router.post("/messages/{message_id}/attachments", dependencies=[Depends(require_permission("comm:write"))])
async def upload_attachment(
message_id: str,
file: UploadFile = File(...),
@@ -364,7 +364,7 @@ async def upload_attachment(
# ─── Reactions ───
@router.post("/messages/{message_id}/reactions")
@router.post("/messages/{message_id}/reactions", dependencies=[Depends(require_permission("comm:write"))])
async def add_msg_reaction(
message_id: str,
body: ReactionCreate,
@@ -381,7 +381,7 @@ async def add_msg_reaction(
return result
@router.delete("/messages/{message_id}/reactions/{emoji}")
@router.delete("/messages/{message_id}/reactions/{emoji}", dependencies=[Depends(require_permission("comm:write"))])
async def remove_msg_reaction(
message_id: str,
emoji: str,
@@ -399,7 +399,7 @@ async def remove_msg_reaction(
# ─── Read State ───
@router.post("/conversations/{conversation_id}/read")
@router.post("/conversations/{conversation_id}/read", dependencies=[Depends(require_permission("comm:write"))])
async def mark_conv_read(
conversation_id: str,
body: ReadStateUpdate,
@@ -416,7 +416,7 @@ async def mark_conv_read(
# ─── Mini-Apps ───
@router.get("/miniapps")
@router.get("/miniapps", dependencies=[Depends(require_permission("comm:read"))])
async def list_miniapps(
current_user: dict = Depends(get_current_user),
):
@@ -429,7 +429,7 @@ async def list_miniapps(
return {"items": registry.list_apps()}
@router.post("/conversations/{conversation_id}/miniapps")
@router.post("/conversations/{conversation_id}/miniapps", dependencies=[Depends(require_permission("comm:write"))])
async def start_miniapp(
conversation_id: str,
body: MiniAppStartRequest,
@@ -455,7 +455,7 @@ async def start_miniapp(
# ─── Content Types ───
@router.get("/block-types")
@router.get("/block-types", dependencies=[Depends(require_permission("comm:read"))])
async def get_block_types():
"""List all known content block types."""
return {"items": list_block_types()}