                        {"email": v["email"]}, request.client.host if request else None)
        return {"ok": True, "recipient": _rec_out(rec)}
    return {"ok": False, "summary": rpt.summary(),
            "invalid": rpt.invalid[:3], "duplicates": rpt.duplicates[:3],
            "suppressed": rpt.suppressed[:3]}


@router.get("")
async def list_recipients(list_id: int = 0, q: str = "", page: int = 1, limit: int = 50,
                          user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
    limit = min(max(1, limit), 500)
    stmt = select(Recipient).join(RecipientList).where(RecipientList.user_id == user.id)
    if list_id:
        stmt = stmt.where(Recipient.list_id == list_id)
    if q:
        stmt = stmt.where(Recipient.email.ilike(f"%{q}%"))
    total = (await db.execute(select(func.count()).select_from(stmt.subquery()))).scalar()
    rows = (await db.execute(stmt.order_by(Recipient.id).offset((page - 1) * limit).limit(limit))).scalars().all()
    return {"total": total, "page": page, "recipients": [_rec_out(r) for r in rows]}


=== subjects ===
class SubjectIn(BaseModel):
    subject: str


@router.get("")
async def list_subjects(q: str = "", page: int = 1, limit: int = 100,
                        user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
    stmt = select(SubjectLine).where(SubjectLine.user_id == user.id)
    if q:
        stmt = stmt.where(SubjectLine.subject.ilike(f"%{q}%"))
    total = (await db.execute(select(func.count()).select_from(stmt.subquery()))).scalar()
    rows = (await db.execute(stmt.order_by(SubjectLine.id).offset((page - 1) * limit).limit(limit))).scalars().all()
    return {"total": total, "subjects": [{"id": s.id, "subject": s.subject,
=== templates ===
    body_text: str = ""
    subject_hint: str = ""


@router.get("")
async def list_templates(user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
    rows = (await db.execute(select(EmailTemplate).where(EmailTemplate.user_id == user.id)
                             .order_by(EmailTemplate.id))).scalars().all()
    out = []
    for t in rows:
        analysis = analyze_template_variables(t.body_html)
        out.append({"id": t.id, "name": t.name, "subject_hint": t.subject_hint,
                    "source": t.source, "sequence_order": t.sequence_order,
