En varios equipos de backend, el problema no es aceptar un registro nuevo. El problema aparece despues, cuando analitica, soporte y automatizacion terminan mezclando cuentas reales con cuentas creadas para pruebas, demos o revisiones rapidas. En proyectos con FastAPI me ha servido poner una validacion muy pequena antes de persistir el usuario, para que ese ruido no se cuele por todo el sistema.
Esto se nota mucho cuando alguien usa un email temporal para Facebook o para validar un flujo de onboarding que aun esta verde. No siempre quieres bloquear ese caso. A veces solo quieres marcarlo, enrutarlo distinto o evitar que active automatizaciones costosas. Si no haces esa clasificacion pronto, luego el cleanup es bastante mas molesto, y aveces nadie sabe de donde salio el dato raro.
Por que validar correos temporales antes de persistir
Hay dos razones practicas. La primera es operativa: si guardas todo igual, tus jobs de bienvenida, scoring o recordatorios trabajan con la misma prioridad sobre cuentas reales y cuentas de prueba. La segunda es de calidad: cuando revisas conversion o soporte, el ruido te puede torcer decisiones sencillas.
Tambien conviene separar este caso de las validaciones clasicas de formato. Que un correo sea sintacticamente correcto no significa que deba entrar al mismo camino que un usuario real. En una API de signup, esa diferencia vale oro.
Cuando he revisado funnels internos, los falsos positivos suelen venir de dominios temporales, aliases cortos o notas pegadas desde listas como temp gamil com. No es un problema grave por si solo, pero si se acumula, ensucia reportes y pruebas end-to-end. Por eso me gusta tratarlo como una señal de negocio, no solo como regex.
Que revisar en FastAPI antes de crear el usuario
Mi regla es simple: normalizar, clasificar y decidir. No hago veinte pasos. En Python queda facil de leer si lo dejas cerca del endpoint o en un servicio pequeño.
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, EmailStr
router = APIRouter()
class SignupInput(BaseModel):
email: EmailStr
def classify_signup_email(email: str) -> dict:
normalized = email.strip().lower()
suspicious_domains = {"mailinator.com", "tempmail.ninja", "guerrillamail.com"}
domain = normalized.split("@", 1)[1]
return {
"normalized": normalized,
"is_test_like": domain in suspicious_domains,
"needs_review": domain in suspicious_domains,
}
@router.post("/signup")
async def signup(payload: SignupInput):
email_state = classify_signup_email(payload.email)
if email_state["needs_review"]:
raise HTTPException(status_code=202, detail="signup queued for review")
return {"ok": True, "email": email_state["normalized"]}
No hace falta empezar bloqueando dominios a lo loco. Muchas veces basta con etiquetar is_test_like, guardar esa decision y dejar que otros procesos reaccionen mejor. Eso evita respuestas bruscas al usuario y te deja margen para ajustar criterios sin romper el endpoint.
Si luego necesitas un flujo mas fino, puedes derivar tres estados: aceptado, aceptado con bandera, o revisión manual. Es un patrón chico, pero ordena bastante bien la API.
Un patron pequeno para clasificar emails de prueba
Lo importante no es la lista de dominios, sino el contrato. Yo suelo guardar:
- email normalizado
- motivo de clasificacion
- fuente de la regla
- timestamp de decision
Con eso ya puedes depurar casi todo. Si mañana QA pega algo como temp org mail en una planilla, veras rapido por que cierta cuenta quedo marcada y no tendras que adivinar.
Tambien me gusta separar las reglas tecnicas de las comerciales. Por ejemplo:
- regla tecnica: dominio temporal conocido
- regla de producto: signup de demo interna
- regla de riesgo: demasiados intentos desde el mismo origen
Ese corte ayuda mucho cuando conectas el backend con alertas de soporte o con procesos de trial. De hecho, este enfoque combina bien con alertas de trial con mejor contexto, porque la cuenta ya nace con una señal util y no con una sospecha difusa.
Como conectar esto con tus pruebas y alertas
Una ventaja poco comentada es que tus pruebas de APIs se vuelven menos ambiguas. Puedes escribir casos que demuestren si el sistema aceptó, marcó o frenó un correo, y eso deja un rastro claro para soporte, data y producto.
Cuando el equipo usa automatizacion con cron, colas o agentes, tener esta clasificacion desde el principio evita que cada ejecutor vuelva a decidir por su cuenta. Esa idea se parece a los runbooks de email que no se rompen: una sola decision bien escrita es mejor que cinco decisiones reconstruidas tarde.
Si quieres ir un paso mas alla, añade contadores por dominio y revisa tendencias. Un estudio de la Federal Trade Commission recuerda que la higiene temprana de datos reduce errores operativos posteriores, y en backend eso se siente aunque el articulo no hable de FastAPI en concreto. No necesitas una plataforma enorme para aprovecharlo; solo necesitas ser consistente.
Preguntas rapidas
Debo bloquear todos los correos temporales?
No necesariamente. Para muchos productos, marcar y enrutar ya resuelve el 80% del problema sin castigar flujos legitimos.
Esto va en el endpoint o en un worker?
Mi preferencia es clasificar en el endpoint y dejar acciones mas pesadas para un worker. Asi la decision queda cerca del input original y es mas facil de auditar.
Que pasa si la lista de dominios cambia mucho?
Mueve esa lista a configuracion y versiona las reglas. Lo importante no es memorizar dominios; es mantener estable el contrato de salida.
Si tu signup empieza a mezclar cuentas reales, demos y pruebas rapidas, esta pequeña capa en FastAPI suele pagar su costo muy pronto. Es una mejora modesta, si, pero de esas que luego evitan bastante ruido feo en Python, en soporte y en tus APIs.
Top comments (0)