Transfer report tokenizado
hop o dir generan un informe de transferencia desde el perfil
del jugador (/dashboard/plantel/[id]) eligiendo nota, links de
video y días de expiración. El sistema crea un row en
transfer_reports con token opaco. El destinatario abre
/transfer/[token] sin login, ve los datos del jugador, y cada
visita incrementa atómicamente view_count.
Para comercial
Sección titulada «Para comercial»- Problema que resuelve: mandar a representantes y clubes interesados un informe profesional del jugador (datos físicos, posición, métricas, video) sin tener que generar un PDF manualmente ni darle login al destinatario.
- Casos de uso típicos: scouting outbound (mostrar un jugador propio a un club interesado), gestión de representantes (compartir performance sin abrir el dashboard).
- Planes que lo incluyen: la UI de
/upgradelista “Informes de transferencias” como exclusivo de Profesional y Enterprise (Esencial muestra el feature conok: false). No hay un feature flagtransfer_reportsenlib/plans.ts— el gating es visual en la página de planes, no enforzado en código. Ver Planes para la matriz real. - Diferenciador: link tokenizado con expiración configurable y contador de vistas atómico — el club ve cuántos viewers abrieron el link.
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 pueden generar y revocar informes desde la
server action createTransferReport. Hay validación de rol
server-side en actions-transfer.ts.
Flujos paso a paso
Sección titulada «Flujos paso a paso»Generar un informe
Sección titulada «Generar un informe»- Plantel → click en el jugador → tab “Transferencia”.
- Modal pide:
- Nota (texto libre, opcional).
- Links de video (array de URLs, opcional).
- Días de expiración (1-365, default 30).
createTransferReport(playerId, { note, videoLinks, expiryDays })inserta una row entransfer_reportscontokenopaco (generado por trigger de DB) yexpires_atcalculado.- La UI muestra el link absoluto
${origin}/transfer/${token}con botón “Copiar”.
Lo que ve el destinatario
Sección titulada «Lo que ve el destinatario»- Abre
/transfer/[token]en cualquier dispositivo, sin login. - Si el report fue revocado (
is_active = false) o está expirado (expires_at < now), ve un 404. - Si está válido, ve:
- Foto, nombre, posición, dorsal, nacionalidad, fecha de nacimiento, altura, peso, pie preferido.
- Nota libre del cuerpo técnico.
- Links de video clickeables.
- El
view_countse incrementa atómicamente vía RPCincrement_transfer_view_count(fire-and-forget). Antes del fix, dos viewers concurrentes perdían visitas — el RPC ahora usaSET view_count = view_count + 1.
Revisar y revocar
Sección titulada «Revisar y revocar»- Plantel → jugador → tab “Transferencia” lista los últimos 5 reports activos del jugador con: token, fecha de creación, contador de vistas, fecha de expiración.
- Botón “Revocar” baja
is_active = false→ el link devuelve 404 inmediatamente.
Configuración relacionada
Sección titulada «Configuración relacionada»expiryDaysclampea a[1, 365]server-side.- El
tokense genera por trigger de DB — el cliente nunca lo fabrica.
FAQ / casos límite
Sección titulada «FAQ / casos límite»- Token inválido o report inactivo: la página devuelve 404 y no expone datos del jugador.
robots: 'noindex, nofollow'está hardcodeado en el metadata de la página → los buscadores no indexan los links.- Sin sesión: la página usa cliente admin (service role) para bypassear RLS, ya que el visitante no está autenticado.
Cómo lo ve el jugador
Sección titulada «Cómo lo ve el jugador»Player surface: N/A. El informe es para terceros (clubes, representantes). El jugador no ve los informes generados sobre él desde el portal.
Datos y métricas
Sección titulada «Datos y métricas»Tablas DB / RPCs / vistas materializadas
Sección titulada «Tablas DB / RPCs / vistas materializadas»transfer_reports:id, token, player_id, created_by, note, video_links (text[]), expires_at, view_count, is_active, created_at.players: lectura de campos del jugador para renderizar el informe.- RPC
increment_transfer_view_count(p_token text): incremento atómico del contador.
Integraciones
Sección titulada «Integraciones»- Supabase admin client (service role) para bypassear RLS en la ruta pública.
- Sentry captura errores de la action de creación.
Limitaciones / roadmap
Sección titulada «Limitaciones / roadmap»- No hay export PDF del informe — el link es web-only. El staff puede usar la captura del navegador para un PDF estático.
- Sin watermarking del viewer — no se rastrea quién abrió el link, solo cuántas veces se abrió. Para identificar viewers, habría que generar tokens distintos por destinatario.
- Sin auto-renovación de la expiración. Una vez vencido, el staff tiene que generar un report nuevo (queda token distinto).