"""Webhooks router.""" import json from typing import List from fastapi import APIRouter, Depends, HTTPException, status, BackgroundTasks from sqlalchemy.orm import Session from app.core.config import get_db from app.models.webhook import Webhook, WebhookLog from app.schemas.webhook import WebhookCreate, WebhookUpdate, WebhookResponse, WebhookLogResponse from app.services.webhook import fire_webhooks_sync router = APIRouter(prefix="/webhooks", tags=["Webhooks"]) @router.post("", response_model=WebhookResponse, status_code=status.HTTP_201_CREATED) def create_webhook(wh: WebhookCreate, db: Session = Depends(get_db)): db_wh = Webhook(**wh.model_dump()) db.add(db_wh) db.commit() db.refresh(db_wh) return db_wh @router.get("", response_model=List[WebhookResponse]) def list_webhooks(project_id: int = None, db: Session = Depends(get_db)): query = db.query(Webhook) if project_id is not None: query = query.filter(Webhook.project_id == project_id) return query.all() @router.get("/{webhook_id}", response_model=WebhookResponse) def get_webhook(webhook_id: int, db: Session = Depends(get_db)): wh = db.query(Webhook).filter(Webhook.id == webhook_id).first() if not wh: raise HTTPException(status_code=404, detail="Webhook not found") return wh @router.patch("/{webhook_id}", response_model=WebhookResponse) def update_webhook(webhook_id: int, wh_update: WebhookUpdate, db: Session = Depends(get_db)): wh = db.query(Webhook).filter(Webhook.id == webhook_id).first() if not wh: raise HTTPException(status_code=404, detail="Webhook not found") for field, value in wh_update.model_dump(exclude_unset=True).items(): setattr(wh, field, value) db.commit() db.refresh(wh) return wh @router.delete("/{webhook_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_webhook(webhook_id: int, db: Session = Depends(get_db)): wh = db.query(Webhook).filter(Webhook.id == webhook_id).first() if not wh: raise HTTPException(status_code=404, detail="Webhook not found") db.delete(wh) db.commit() return None @router.get("/{webhook_id}/logs", response_model=List[WebhookLogResponse]) def list_webhook_logs(webhook_id: int, limit: int = 50, db: Session = Depends(get_db)): return db.query(WebhookLog).filter( WebhookLog.webhook_id == webhook_id ).order_by(WebhookLog.created_at.desc()).limit(limit).all() @router.post("/{webhook_id}/retry/{log_id}") def retry_webhook(webhook_id: int, log_id: int, bg: BackgroundTasks, db: Session = Depends(get_db)): log_entry = db.query(WebhookLog).filter(WebhookLog.id == log_id, WebhookLog.webhook_id == webhook_id).first() if not log_entry: raise HTTPException(status_code=404, detail="Webhook log not found") wh = db.query(Webhook).filter(Webhook.id == webhook_id).first() if not wh: raise HTTPException(status_code=404, detail="Webhook not found") bg.add_task(fire_webhooks_sync, log_entry.event, json.loads(log_entry.payload), wh.project_id, db) return {"status": "retry_queued", "log_id": log_id}