failed
perm_failed
sent
suppressed
unsubscribed
=== events endpoint filter ===
@router.get("/events")
async def list_events(campaign_id: int = Query(0),
                      event_type: str = Query(""),
                      page: int = Query(1, ge=1),
                      page_size: int = Query(50, ge=1, le=200),
                      db: AsyncSession = Depends(get_db),
                      user: User = Depends(get_current_user)):
    q = (select(EmailEvent, CampaignRecipient)
         .join(CampaignRecipient, EmailEvent.campaign_recipient_id == CampaignRecipient.id)
         .join(Campaign, Campaign.id == EmailEvent.campaign_id)
         .where(Campaign.user_id == user.id))
    if campaign_id:
        q = q.where(EmailEvent.campaign_id == campaign_id)
    if event_type:
        q = q.where(EmailEvent.event_type == event_type)
    total = (await db.execute(
        select(func.count()).select_from(q.subquery()))).scalar() or 0
    rows = (await db.execute(
        q.order_by(EmailEvent.id.desc()).offset((page - 1) * page_size).limit(page_size)
    )).all()
    out = []
    for e, cr in rows:
        out.append({
            "id": e.id,
            "campaign_id": e.campaign_id,
