Ir al contenido

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).

  • 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.

Solo hop y dir ven el botón “Invitar” en el perfil del jugador.

  1. Plantel → click en el jugador → tab “Perfil”.
  2. Botón “Invitar” → modal pide el email.
  3. La server action invitePlayer(playerId, email) ejecuta:
    • admin.auth.admin.generateLink({ type: 'invite', redirectTo: '/auth/set-password?next=/player' }).
    • Si generateLink falla con type: 'invite' (usuario ya existe), reintenta con type: 'magiclink' como fallback.
    • Manda el mail con sendEmail() y el template inviteEmailHtml({ forPlayer: true }).
  4. El jugador recibe el mail, abre el link, fija contraseña en /auth/set-password, y queda linkeado vía linkPlayerAfterPasswordSet (lee player_id del metadata del invite).
  • El email del invite usa RESEND_FROM como remitente.
  • El subject por defecto es “Tu acceso al App — [Org]”.
  • Branding del mail (logo y nombre) sale de organizations.logo_url y organizations.name.
  • RESEND_API_KEY no configurada: la action devuelve { ok: true, data: { emailSent: false, inviteLink } } — loguea warning en Sentry pero no rompe el flow. La UI recibe el inviteLink como 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.users row; 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).
  • 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).
  • Supabase Auth vía admin.auth.admin.generateLink.
  • Resend envía el mail final via sendEmail de lib/send-email.ts.
  • Tabla players se actualiza con auth_user_id y onboarding_consumed_at solo después de que el jugador termine /auth/set-password.
  • 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.