Invitación individual del jugador (legacy)
hop o dir abren el perfil del jugador en /dashboard/plantel/[id],
click “Invitar” e ingresan el email. La acción
invitePlayer(playerId, email) genera un link de invitación con
Supabase Auth y lo manda por Resend. El jugador cae en
/auth/set-password?next=/player.
Es el flujo legacy: el preferido para clubes nuevos es el self-onboarding masivo. Esta ruta queda para casos puntuales (un jugador que se incorpora después, un email viejo que rebotó, refuerzos a mitad de temporada).
Para comercial
Sección titulada «Para comercial»- Problema que resuelve: dar de alta a un jugador puntual sin necesidad de rotar el token grupal ni reenviar el link a todo el plantel.
- Casos de uso típicos: un refuerzo que llega después del arranque, un jugador que volvió de cesión, recuperación de cuenta tras un cambio de email.
- Planes que lo incluyen: todos.
Cómo lo usa el staff
Sección titulada «Cómo lo usa el staff»Acceso y permisos
Sección titulada «Acceso y permisos»Solo hop y dir ven el botón “Invitar” en el perfil del jugador.
Flujos paso a paso
Sección titulada «Flujos paso a paso»- Plantel → click en el jugador → tab “Perfil”.
- Botón “Invitar” → modal pide el email.
- La server action
invitePlayer(playerId, email)ejecuta:admin.auth.admin.generateLink({ type: 'invite', redirectTo: '/auth/set-password?next=/player' }).- Si
generateLinkfalla contype: 'invite'(usuario ya existe), reintenta contype: 'magiclink'como fallback. - Manda el mail con
sendEmail()y el templateinviteEmailHtml({ forPlayer: true }).
- El jugador recibe el mail, abre el link, fija contraseña en
/auth/set-password, y queda linkeado víalinkPlayerAfterPasswordSet(leeplayer_iddel metadata del invite).
Configuración relacionada
Sección titulada «Configuración relacionada»- El email del invite usa
RESEND_FROMcomo remitente. - El subject por defecto es “Tu acceso al App — [Org]”.
- Branding del mail (logo y nombre) sale de
organizations.logo_urlyorganizations.name.
FAQ / casos límite
Sección titulada «FAQ / casos límite»RESEND_API_KEYno configurada: la action devuelve{ ok: true, data: { emailSent: false, inviteLink } }— loguea warning en Sentry pero no rompe el flow. La UI recibe elinviteLinkcomo fallback y el staff puede copiarlo manualmente. Verificar Workers Secrets para que el jugador reciba el mail automáticamente.- Email ya en uso: Supabase Auth reusa el
auth.usersrow; el handler igual reescribe metadata y manda link nuevo. - El jugador no recibe el mail: revisar spam y
RESEND_FROM(debe ser un dominio verificado en Resend).
Cómo lo ve el jugador
Sección titulada «Cómo lo ve el jugador»- Recibe un mail con asunto “Acceso al AMS — [Org]” y un botón con el link de activación.
- Tras setear contraseña, cae directo en
/player(su portal).
Integraciones
Sección titulada «Integraciones»- Supabase Auth vía
admin.auth.admin.generateLink. - Resend envía el mail final via
sendEmaildelib/send-email.ts. - Tabla
playersse actualiza conauth_user_idyonboarding_consumed_atsolo después de que el jugador termine/auth/set-password.
Limitaciones / roadmap
Sección titulada «Limitaciones / roadmap»- Sin retry visible en UI cuando el mail no se envía — el staff tiene que verificar manualmente en Sentry o reintentar.
- Para alta del plantel completo, este flow es ~30× más lento que el link grupal. Mantenido por retrocompatibilidad con Nacional y casos puntuales.