# app/modules/prospecting/routes/api/admin_campaigns.py """ Admin API routes for campaign management. """ import logging from fastapi import APIRouter, Depends, Path, Query from sqlalchemy.orm import Session from app.api.deps import get_current_admin_api from app.core.database import get_db from app.modules.prospecting.schemas.campaign import ( CampaignPreviewRequest, CampaignPreviewResponse, CampaignSendCreate, CampaignSendListResponse, CampaignSendResponse, CampaignTemplateCreate, CampaignTemplateDeleteResponse, CampaignTemplateResponse, CampaignTemplateUpdate, ) from app.modules.prospecting.services.campaign_service import campaign_service from app.modules.tenancy.schemas.auth import UserContext router = APIRouter(prefix="/campaigns") logger = logging.getLogger(__name__) @router.get("/templates", response_model=list[CampaignTemplateResponse]) def list_templates( lead_type: str | None = Query(None), active_only: bool = Query(False), db: Session = Depends(get_db), current_admin: UserContext = Depends(get_current_admin_api), ): """List campaign templates with optional filters.""" templates = campaign_service.get_templates(db, lead_type=lead_type, active_only=active_only) return [CampaignTemplateResponse.model_validate(t) for t in templates] @router.post("/templates", response_model=CampaignTemplateResponse) def create_template( data: CampaignTemplateCreate, db: Session = Depends(get_db), current_admin: UserContext = Depends(get_current_admin_api), ): """Create a new campaign template.""" template = campaign_service.create_template(db, data.model_dump()) db.commit() return CampaignTemplateResponse.model_validate(template) @router.put("/templates/{template_id}", response_model=CampaignTemplateResponse) def update_template( data: CampaignTemplateUpdate, template_id: int = Path(...), db: Session = Depends(get_db), current_admin: UserContext = Depends(get_current_admin_api), ): """Update a campaign template.""" template = campaign_service.update_template(db, template_id, data.model_dump(exclude_none=True)) db.commit() return CampaignTemplateResponse.model_validate(template) @router.delete("/templates/{template_id}", response_model=CampaignTemplateDeleteResponse) def delete_template( template_id: int = Path(...), db: Session = Depends(get_db), current_admin: UserContext = Depends(get_current_admin_api), ): """Delete a campaign template.""" campaign_service.delete_template(db, template_id) db.commit() return CampaignTemplateDeleteResponse(message="Template deleted") @router.post("/preview", response_model=CampaignPreviewResponse) def preview_campaign( data: CampaignPreviewRequest, db: Session = Depends(get_db), current_admin: UserContext = Depends(get_current_admin_api), ): """Preview a rendered campaign for a specific prospect.""" result = campaign_service.render_campaign(db, data.template_id, data.prospect_id) return CampaignPreviewResponse(**result) @router.post("/send", response_model=list[CampaignSendResponse]) def send_campaign( data: CampaignSendCreate, db: Session = Depends(get_db), current_admin: UserContext = Depends(get_current_admin_api), ): """Send a campaign to one or more prospects.""" sends = campaign_service.send_campaign( db, template_id=data.template_id, prospect_ids=data.prospect_ids, sent_by_user_id=current_admin.id, ) db.commit() return [CampaignSendResponse.model_validate(s) for s in sends] @router.get("/sends", response_model=CampaignSendListResponse) def list_sends( prospect_id: int | None = Query(None), template_id: int | None = Query(None), db: Session = Depends(get_db), current_admin: UserContext = Depends(get_current_admin_api), ): """List sent campaigns with optional filters.""" sends = campaign_service.get_sends(db, prospect_id=prospect_id, template_id=template_id) return CampaignSendListResponse( items=[CampaignSendResponse.model_validate(s) for s in sends], total=len(sends), )