"""Subscribers API endpoints.""" from uuid import UUID from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.dependencies import get_db, verify_api_key from app.models.models import Subscriber router = APIRouter() @router.get("/") async def list_subscribers(db: AsyncSession = Depends(get_db)): """List all subscribers.""" result = await db.execute(select(Subscriber)) subscribers = result.scalars().all() return [ { "id": s.id, "email": s.email, "is_confirmed": s.is_confirmed, "created_at": s.created_at.isoformat() if s.created_at else None, } for s in subscribers ] @router.post("/", status_code=status.HTTP_201_CREATED) async def create_subscriber( email: str, db: AsyncSession = Depends(get_db), api_key: str = Depends(verify_api_key), ): """Add a new subscriber.""" import uuid subscriber = Subscriber( email=email, confirm_token=str(uuid.uuid4()), ) db.add(subscriber) await db.flush() await db.refresh(subscriber) return { "id": subscriber.id, "email": subscriber.email, "confirm_token": subscriber.confirm_token, } @router.delete("/{subscriber_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_subscriber( subscriber_id: UUID, db: AsyncSession = Depends(get_db), api_key: str = Depends(verify_api_key), ): """Remove a subscriber.""" result = await db.execute(select(Subscriber).where(Subscriber.id == str(subscriber_id))) subscriber = result.scalar_one_or_none() if not subscriber: raise HTTPException(status_code=404, detail="Subscriber not found") await db.delete(subscriber) @router.post("/{subscriber_id}/confirm") async def confirm_subscriber( subscriber_id: UUID, token: str, db: AsyncSession = Depends(get_db), ): """Confirm a subscriber's email address.""" result = await db.execute(select(Subscriber).where(Subscriber.id == str(subscriber_id))) subscriber = result.scalar_one_or_none() if not subscriber: raise HTTPException(status_code=404, detail="Subscriber not found") if subscriber.confirm_token != token: raise HTTPException(status_code=400, detail="Invalid confirmation token") subscriber.is_confirmed = True subscriber.confirm_token = None await db.flush() return {"message": "Subscriber confirmed", "email": subscriber.email}