{"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,