21 — Sistema de invitaciones pre-launch¶
Por qué está incluido¶
Este feature es value-add real del SaaS framework. Permite al comprador lanzar con beta cerrada (waitlist) y pasar a registro abierto con un toggle — sin escribir código.
"Lanza con waitlist o abre registro público cambiando un switch. Códigos de invitación, panel de aprobación, 3 emails en 5 idiomas — built-in."
Costo si el comprador lo tuviera que construir: 1-2 semanas. Aquí ya está.
Modos de operación¶
| Modo | Comportamiento |
|---|---|
| Pre-launch OFF (default) | Registro abierto en /signup (solo requiere código prelaunch si lo configuras en el gate) |
| Pre-launch ON | Formulario de solicitud de invitación; superadmin aprueba/rechaza |
Toggle: POST /api/sa/prelaunch-mode/ (superadmin) o SystemSetting(key='prelaunch_mode').
Flujo completo¶
Visitante → /signup (prelaunch ON)
│
├─ Ve formulario "Solicitar invitación"
│ POST /api/auth/invitation-request/
│ { email, full_name, company, locale, ... }
│
├─ Email #1: "Recibimos tu solicitud" (idioma del formulario)
│
▼
Superadmin → /superadmin/prelaunch
│
├─ Aprueba → genera código + Email #2: "Tu código: XXXX" (locale de la solicitud)
│
└─ Rechaza → Email #3: "Solicitud no aprobada" (locale de la solicitud)
│
▼
Visitante → /signup?invitation_code=XXXX
│
└─ Registro normal → Email verificación (locale del signup)
Endpoints¶
Públicos¶
| Método | Endpoint | Descripción |
|---|---|---|
| POST | /api/auth/invitation-request/ |
Enviar solicitud (rate limit: 3/h por IP) |
| GET | /api/auth/prelaunch-status/ |
{ "enabled": true/false } |
Superadmin¶
| Método | Endpoint | Descripción |
|---|---|---|
| GET | /api/sa/invitation-requests/ |
Lista solicitudes pendientes |
| GET | /api/sa/invitation-requests/<id>/ |
Detalle |
| POST | /api/sa/invitation-requests/<id>/action/ |
{ "action": "approve" \| "reject" } |
| POST | /api/sa/prelaunch-mode/ |
Toggle ON/OFF |
| GET | /api/sa/prelaunch-codes/ |
Lista códigos generados |
Modelos de datos¶
invitation_requests¶
id, email, full_name, company_name, locale, status (pending|approved|rejected),
ip_address, user_agent, created_at, reviewed_at, reviewed_by
prelaunch_codes¶
Emails (3)¶
Implementados en authentication/emails_invitation.py. Todos usan el locale de la solicitud (campo del formulario, no el del superadmin).
| Función | Cuándo | |
|---|---|---|
| Confirmación recepción | send_invitation_request_confirmation() |
Tras POST invitation-request |
| Código aprobado | send_invitation_code_email() |
Superadmin approve |
| Rechazo | send_invitation_request_rejected_email() |
Superadmin reject |
El código aprobado incluye link: {FRONTEND_URL}/signup?invitation_code={code}.
Frontend¶
- Dashboard signup:
SignupPage.tsx— envíalocaledesde i18n al registrarse. - Superadmin:
InvitationsPage.tsx— lista, aprueba, rechaza. - El formulario de solicitud de invitación debe incluir campo
locale(usar idioma actual de i18n).
Seguridad¶
- Rate limit: 3 solicitudes/hora por IP en
invitation-request. - Honeypot field en el serializer (bots no pasan).
- Deduplicación: no crea otra solicitud
pendingsi ya existe una para el mismo email.
Cómo activar en tu deploy¶
- Superadmin → Pre-launch → activar modo.
- Opcional: sembrar códigos iniciales en
prelaunch_codes. - El frontend de signup detecta
GET /api/auth/prelaunch-status/y muestra el formulario de waitlist.
Cómo desactivar (registro abierto)¶
- Superadmin → Pre-launch → desactivar.
/signupvuelve al flujo normal de registro.
No hay que tocar código ni redeploy — solo el toggle.
Extender¶
Para añadir campos al formulario de solicitud:
- Añade columna o usa JSON en
invitation_requests. - Actualiza
InvitationRequestCreateSerializer. - Actualiza el frontend del signup/waitlist form.
- Opcional: incluye el dato en el email de confirmación.