Initial commit: waitlist microservice
Some checks failed
Test & Deploy Waitlist / test (push) Failing after 44s
Test & Deploy Waitlist / deploy (push) Has been skipped

This commit is contained in:
Roberto Musso
2026-04-11 10:35:53 +02:00
commit 4b2fefcf92
22 changed files with 841 additions and 0 deletions

48
app/routes.py Normal file
View File

@@ -0,0 +1,48 @@
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()