Ir al contenido

Onboarding link grupal

Un único link grupal que el club distribuye por WhatsApp o el canal que sea. El jugador lo abre, ve la grilla de fotos del plantel, hace click en “Soy yo” sobre su foto y dispara un email a su dirección pre-cargada por el cuerpo técnico. Anti-spoofing 100%: aunque otro jugador haga clic en una foto que no es la propia, el mail no le llega. Ruta en código: /dashboard/onboarding-link.

  • Problema que resuelve: invitar un plantel completo uno por uno por email es lento y termina en spam o emails desactualizados. El link grupal pasa por WhatsApp (canal que el plantel usa de verdad) y el jugador confirma identidad visualmente.
  • Casos de uso típicos: primera vez que el club activa CÉNIT — el HoP carga los emails del plantel en Plantel, genera el link, lo pega en el grupo de WhatsApp y al día siguiente la mayoría ya está adentro.
  • Planes que lo incluyen: todos.
  • Diferenciador: identidad por foto, no por email tipeado. Y el email se manda al address pre-cargado — un bromista no puede cosechar mails ajenos.
  • Roles permitidos: hop, dir, sc. Cualquier otro queda redirigido a /dashboard.
  • La URL del link contiene organizations.org_onboarding_token (un token UUID generado a nivel org, no por jugador).
  • Pre-requisito. El cuerpo técnico carga emails en players.email desde Plantel. Si un jugador no tiene email pre-cargado, igual puede usar el link — la pantalla de confirmación le pide tipear su email manualmente (fallback PR 90dabd9).
  • Generar / copiar el link. En /dashboard/onboarding-link el HoP ve la URL https://cenitams.com/onboarding/{token} con tres contadores:
    1. Elegibles — jugadores activos sin auth_user_id y sin onboarding_consumed_at.
    2. Sin email — elegibles que además no tienen players.email cargado (van a tener que tipearlo).
    3. Linkeados — ya tienen cuenta activa (auth_user_id != null).
  • Distribuir. Copiar la URL y pegarla en WhatsApp / canal del plantel.
  • Flujo del jugador (lado público).
    1. Abre /onboarding/{token} → ve la grilla de fotos del plantel de su org.
    2. Click en “Soy yo” sobre su propia foto → pantalla de confirmación.
    3. Sistema dispara mail a players.email con un link de set-password. Si no había email pre-cargado, el jugador lo escribe acá.
    4. Jugador setea password.
    5. El handler linkPlayerAfterPasswordSet lee user_metadata .player_id del JWT y hace UPDATE players SET auth_user_id = user.id, onboarding_consumed_at = now() de forma race-safe.
  • ¿Puedo regenerar el token? El org_onboarding_token se genera al crear la org. Hoy no hay UI para regenerarlo — [NEEDS_USER: ROADMAP validar si interesa rotación periódica del token.]
  • ¿Qué pasa si el jugador hace click dos veces? El UPDATE es race-safe y onboarding_consumed_at queda con el primero. La segunda iteración no rompe nada pero queda como consumed_unlinked si algo falla en el medio (ver Onboarding status).
  • Cambiar el email después: si el jugador ya activó cuenta, el cambio de players.email no afecta su login (que vive en auth.users).

Sí — esta sub-página describe el flujo del jugador. Pantallas:

  • /onboarding/[token] — grilla de fotos.
  • /onboarding/[token]/[player_id]/confirm — confirmación de identidad (+ tipeo de email si falta).
  • Email con link a /auth/set-password?next=/player.
  • Primer login → /player.
  • organizations.org_onboarding_token — token UUID grupal.
  • players.email — email pre-cargado (anti-spoofing).
  • players.auth_user_id — se setea con el linkPlayerAfterPassword Set handler post-set-password.
  • players.onboarding_consumed_at — timestamp del claim.
  • Plantel — la carga previa de players.email es requisito funcional.
  • Resend — envío del email con set-password.
  • Supabase Admin SDKadmin.auth.admin.generateLink({ type: 'invite' }) con user_metadata.player_id en el JWT.
  • No hay deep-link directo a la app del store; el flow es web → PWA.
  • No hay reporte de “cuántos vieron el link pero no completaron”.
  • [NEEDS_USER: ROADMAP validar si en algún plan querés expirar el link después de X días sin uso.]