83 lines
2.7 KiB
Python
83 lines
2.7 KiB
Python
"""Admin endpoints for managing survey invites."""
|
|
import logging
|
|
from typing import Annotated
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.api.deps import require_admin
|
|
from app.core.config import settings
|
|
from app.core.database import get_db
|
|
from app.core.email import EmailService
|
|
from app.models.survey_invite import SurveyInvite
|
|
from app.models.user import User
|
|
from app.schemas.survey import SurveyInviteCreate, SurveyInviteResponse
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter(prefix="/admin", tags=["admin-survey"])
|
|
|
|
FRONTEND_URL = "https://resolutionflow.com"
|
|
|
|
|
|
def _build_invite_response(invite: SurveyInvite) -> SurveyInviteResponse:
|
|
base_url = FRONTEND_URL if not settings.DEBUG else "http://localhost:5173"
|
|
return SurveyInviteResponse(
|
|
id=str(invite.id),
|
|
token=invite.token,
|
|
recipient_name=invite.recipient_name,
|
|
recipient_email=invite.recipient_email,
|
|
status=invite.status,
|
|
email_sent=invite.email_sent,
|
|
created_at=invite.created_at,
|
|
completed_at=invite.completed_at,
|
|
survey_url=f"{base_url}/survey?t={invite.token}",
|
|
)
|
|
|
|
|
|
@router.post("/survey-invites", response_model=SurveyInviteResponse)
|
|
async def create_survey_invite(
|
|
data: SurveyInviteCreate,
|
|
db: Annotated[AsyncSession, Depends(get_db)],
|
|
current_user: Annotated[User, Depends(require_admin)],
|
|
):
|
|
"""Create a survey invite. Optionally sends email."""
|
|
invite = SurveyInvite(
|
|
recipient_name=data.recipient_name,
|
|
recipient_email=data.recipient_email,
|
|
)
|
|
db.add(invite)
|
|
await db.flush()
|
|
|
|
if data.send_email and data.recipient_email:
|
|
try:
|
|
base_url = FRONTEND_URL if not settings.DEBUG else "http://localhost:5173"
|
|
survey_url = f"{base_url}/survey?t={invite.token}"
|
|
sent = await EmailService.send_survey_invite_email(
|
|
to_email=data.recipient_email,
|
|
recipient_name=data.recipient_name,
|
|
survey_url=survey_url,
|
|
)
|
|
if sent:
|
|
invite.email_sent = True
|
|
except Exception:
|
|
logger.exception("Failed to send survey invite email")
|
|
|
|
await db.commit()
|
|
await db.refresh(invite)
|
|
return _build_invite_response(invite)
|
|
|
|
|
|
@router.get("/survey-invites", response_model=list[SurveyInviteResponse])
|
|
async def list_survey_invites(
|
|
db: Annotated[AsyncSession, Depends(get_db)],
|
|
current_user: Annotated[User, Depends(require_admin)],
|
|
):
|
|
"""List all survey invites."""
|
|
result = await db.execute(
|
|
select(SurveyInvite).order_by(SurveyInvite.created_at.desc())
|
|
)
|
|
invites = result.scalars().all()
|
|
return [_build_invite_response(i) for i in invites]
|