"""Webhook CRUD endpoints (ROADMAP #85, tranche 2). Handlers déplacés depuis :mod:`backend.main` sans changement de comportement : mêmes chemins (``/api/webhooks``), même modèle de réponse (:class:`backend.schemas.WebhookModel`), même dépendance admin. La logique métier vit déjà dans :mod:`backend.webhooks` (validation d'URL anti-SSRF, store ``webhook_secrets.json`` — BUG-026). """ from fastapi import APIRouter, Body, Depends, HTTPException from backend.auth.middleware import require_admin from backend.schemas import StatusResponse, WebhookModel from backend.webhooks import ( create_webhook, delete_webhook, get_webhooks, update_webhook, ) router = APIRouter(prefix="/api/webhooks", tags=["webhooks"]) @router.get("", response_model=list[WebhookModel]) async def api_webhooks_list(current_user=Depends(require_admin)): return get_webhooks() @router.post("", response_model=WebhookModel) async def api_webhooks_create(body: dict = Body(...), current_user=Depends(require_admin)): name = body.get("name", "Unnamed") url = body.get("url", "") events = body.get("events", []) secret = body.get("secret") if not url: raise HTTPException(400, "URL is required") # #198 : filtres optionnels vault / path_prefix (None = tout recevoir). return create_webhook(name, url, events, secret, vault=body.get("vault"), path_prefix=body.get("path_prefix")) @router.patch("/{webhook_id}", response_model=WebhookModel) async def api_webhooks_update( webhook_id: str, body: dict = Body(...), current_user=Depends(require_admin) ): result = update_webhook(webhook_id, body) if not result: raise HTTPException(404, "Webhook not found") return result @router.delete("/{webhook_id}", response_model=StatusResponse) async def api_webhooks_delete(webhook_id: str, current_user=Depends(require_admin)): if not delete_webhook(webhook_id): raise HTTPException(404, "Webhook not found") return {"status": "deleted"}