Ir al contenido

Informe HoP

Informe HoP es el reporte ejecutivo semanal del cuerpo técnico: una sola pantalla que cruza plantel, físico, médico, nutrición y mental con KPIs comparados contra la semana / mes / temporada anterior. Incluye injury rate por 1000h, match load por jugador, notas editables persistidas en DB y export a PDF.

  • Problema que resuelve: el HoP arma un PowerPoint cada lunes cruzando 6 planillas distintas. CÉNIT genera ese informe en tiempo real con los datos del sistema, lo deja editar comentarios contextuales y exporta a PDF listo para imprimir o mandar al cuerpo técnico.
  • Casos de uso típicos [NEEDS_USER: CASE_STUDY caso real de Nacional]:
    • Lunes de microciclo: revisar la semana cerrada con KPIs versus la anterior.
    • Mensual: ver injury rate del mes y decidir si hay que ajustar cargas globales.
    • Reunión con dirigencia: PDF de temporada con notas explicativas del HoP.
  • Planes que lo incluyen: esencial, pro y enterprise lo tienen accesible. El feature flag pdf_export está en true para los tres planes.
  • Diferenciador: único informe del mercado que combina injury rate (epidemiología deportiva), match load real (GPS), composición corporal y mental en un solo documento auditable.

Solo hop, dir y coord_form pueden ver /dashboard/informe. El resto de los roles, aunque tengan el link oculto en el nav, son redirigidos server-side a /dashboard si pegan la URL directa. (page.tsx chequea callerRole contra ALLOWED_ROLES antes de renderizar.)

Selector de período en el shell:

  • weekly — semana ISO en curso vs semana anterior (lunes a domingo).
  • monthly — mes calendario vs mes anterior.
  • season — desde organizations.season_start hasta hoy, sin comparativa.

Tabs del informe:

  1. Resumen ejecutivo — KPIs: disponibles / total, compliance wellness, wellness promedio, lesiones nuevas, injury rate /1000h con semáforo. Plantel con observaciones automáticas (leave médico / RTP / carga alta / sin GPS / wellness bajo).
  2. FísicoLoadMetric por jugador (distance / HSR / sprint / HMLD), top performers, MatchSummaryRow con matchLoad por partido jugado en la ventana.
  3. MédicoActiveInjury[] (lesiones en curso), MedConsultation[] (consultas), epidemiología.
  4. NutriciónNutritionAnthroRow (composición corporal última + previa), NutritionTeamKpis (compliance objetivos).
  5. Mental — solo visible para hop, dir, psi. MentalGroupStats + MentalIndividual.
  6. Comparativa semanalWeekComparisonRow[] con delta entre ventanas.

Flujo principal — revisar y exportar:

  1. Abrir /dashboard/informe (default weekly).
  2. Revisar tabs y agregar notas en los bloques EditableNote.
  3. Click Exportar PDF (pdf-export-button.tsx) — render server-side con @react-pdf/renderer.

Flujo secundario — notas editables: cada nota tiene note_type y se persiste en report_notes con clave (week_start, note_type). Solo se ven en el período weekly (las notas están scopeadas a la semana).

  • organizations.season_start — fecha de inicio de temporada, usada para el período season.
  • Roles configurables en user_profiles.role — agregar / sacar usuarios del set ALLOWED_ROLES requiere migration.
  • “El injury rate me da NULL”total_player_hours = 0 en la ventana. Sucede si no hay sesiones GPS cargadas. Fórmula: (lesiones nuevas / total_player_hours) * 1000. Sin GPS no hay denominador.
  • “Vi el módulo y desapareció”coord_form se agregó al set permitido. Si tu rol no es hop / dir / coord_form, el link desaparece y la URL redirige.
  • “El PDF salió en blanco” — verificar Sentry. @react-pdf/ renderer puede fallar silenciosamente en Workers si una sección no tiene datos.

Player surface: N/A. El informe HoP es de uso interno del cuerpo técnico. Los jugadores no acceden ni reciben copia automática.

  • Injury rate /1000h: (newInjuries / totalPlayerHours) * 1000, donde totalPlayerHours = MAX(total_player_hours) entre filas GPS de la ventana. Se usa MAX porque cada fila ya trae el total del equipo (sesión × team_size). Semáforo: < 2.0 verde, < 3.5 amarillo, ≥ 3.5 rojo.
  • Match load por jugador: match_distance_m, match_hsr_m, match_session_count extraídos de weekly_gps_summary (splits match_* agregados por migration-105).
  • Wellness compliance: wellnessSubmitted / totalPlayers.
  • Wellness avg: promedio del último hooper_index por jugador dentro de la ventana.
  • Observaciones automáticas (plantelRows): primer match gana → injuredrecovering → distance NULL → distance > 50km → hooper > 20.
  • No tiene importadores propios. Consume datos de Carga, Wellness, Lesiones, Médico, Nutrición y Mental.
  • Tablas leídas: players, injuries, medical_consultations, physio_sessions, wellness_entries, mental_records, nutrition_targets, report_notes, organizations.
  • Vista: weekly_gps_summary (vía fetchWgsSummary, splits total / training / match).
  • RPC: get_body_composition_latest_and_prior(p_player_ids) para composición corporal con delta.
  • Carga GPS aporta GPS + match load.
  • Plantel aporta status (available / injured / recovering).
  • Wellness aporta Hooper diario.
  • Médico / Fisio aportan lesiones activas + consultas + sesiones.
  • Nutrición aporta composición + objetivos.
  • Psicología aporta mental_records (solo hop/dir/psi).
  • @react-pdf/renderer para export.
  • Sin export Excelexcel_export prometido pero no implementado (gap comercial transversal).
  • Sin notas en monthly / season: report_notes está scopeado a week_start. Las notas en otros períodos requieren schema change.
  • Sin envío automático por email — el HoP exporta y manda manualmente. Roadmap: integración con Resend para envío programado.
  • coord_form en allowlist — rol añadido al set permitido además de hop/dir. Si el ABAC se rediseña, este chequeo hardcoded debería ir a lib/auth-guard.ts.