Files
waitlist/app/routes.py
Roberto Musso 4b2fefcf92
Some checks failed
Test & Deploy Waitlist / test (push) Failing after 44s
Test & Deploy Waitlist / deploy (push) Has been skipped
Initial commit: waitlist microservice
2026-04-11 10:35:53 +02:00

49 lines
1.4 KiB
Python

import logging
from fastapi import APIRouter, Depends, Request
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.db import get_db
from app.rate_limit import _get_client_ip
from app.schemas import WaitlistRequest, WaitlistResponse
from app.models import WaitlistEntry
logger = logging.getLogger(__name__)
router = APIRouter()
@router.post("/waitlist", response_model=WaitlistResponse)
async def join_waitlist(
body: WaitlistRequest,
request: Request,
db: AsyncSession = Depends(get_db),
) -> WaitlistResponse:
"""
Add an email to the waitlist.
- Honeypot: if `website` field is non-empty, silently succeed (bot trap).
- Duplicate emails: idempotent — returns success without error.
- Stores the Cloudflare-resolved client IP for analytics (not exposed).
"""
# Honeypot — bots fill hidden fields; silently "succeed"
if body.website:
return WaitlistResponse()
email = body.email.lower().strip()
ip = _get_client_ip(request)
# Check for existing entry — idempotent
existing = await db.execute(
select(WaitlistEntry.id).where(WaitlistEntry.email == email)
)
if existing.scalar_one_or_none() is not None:
return WaitlistResponse()
entry = WaitlistEntry(email=email, ip_address=ip, source="website")
db.add(entry)
await db.commit()
logger.info("New waitlist signup: %s", email[:3] + "***")
return WaitlistResponse()