--- asset_id: MIN-EL-Gustavo-20260703-v01 tipo: MIN — Minuta del día owner: Gustavo sherpa: GusX ratificador: Gustavo fecha: 2026-07-03 intellibank: IB-EL-EmpowerLabs subbank: EQ-EL-Equipo proyecto: RCH — Rebelocity Club --- ## Qué se hizo ### Triage del backlog — 5 puntos revisados con el usuario - **B04** (bug case-sensitive `ped.rol='coach'`) — **eliminado del backlog**, decisión del usuario de no tocar ese bug. - **B06** (relay buscando/completo) — confirmado que sigue pendiente hasta tener el chat grupal completo (dependencia de B09). - **B09** — el usuario decide retomar la conexión al backend real directamente, **ya no se espera a Jesús**. - **B10** (gap `currentAthleteContext`) — implementado: `athlete-directory.component.ts` ahora cachea el perfil extendido (`myProfile`, vía `loadMyProfile()` llamado desde `sessionActive()`) usando `UserService.getProfile(session.puesto, 'puesto', true)`, y `currentAthleteContext` mapea `nombre`/`nivel`/`disciplinas`/`eventoObjetivo` desde ahí con fallback a la cookie. `memberSince` queda sin poblar (no existe esa columna en `profileUser()`). Verificado con `tsc --noEmit`. - **B11** ("Ver perfil completo" no conecta) — explorado a fondo. Decisión del usuario: construir un endpoint nuevo que devuelva el perfil de un solo atleta (mismo shape que `getListAtletas()`, filtrado por id) para alimentar `athlete-profile-modal` sin adaptarlo. Documentado, no implementado todavía. **Fix aparte:** bug de z-index del panel `coach-message-panel` — quedaba tapado por el top-bar (`z-index: 10000` vs `900`/`901` del panel). Subido a `10500`/`10501`. --- ### B09 — Conexión al backend real (de mock/localStorage a producción) **Análisis del chat legado** (`controllers/general/chat.php`, 5022 líneas) antes de tocar código, para decidir qué reciclar: - Son 2 sistemas paralelos: privado/actividad (`pap_sub_eje` + `comentario`) y grupal (`grupo`+`miembro`+`mensaje`). - **Se recicla:** la tabla `comentario` (sin FK real a `pap_sub_eje`, `activity_id` es solo un entero de referencia), usando el campo `acceso` (hoy siempre `NULL` en el uso legado) como namespace propio para no mezclarse con comentarios de tareas/tickets/foros. - **No se recicla** `pap_sub_eje` como "conversación" (tabla de tareas, sin concepto de pendiente/aceptada/rechazada) ni los endpoints legados tal cual (SQL concatenado sin parametrizar, y `autor` ahí es `wikiname`, no `puesto`). - El patrón `grupo`+`miembro`+`mensaje` queda anotado como candidato para B06 (relay), no para B09. **Construido:** 1. Tabla nueva `coach_solicitud` (`id, atleta_id, coach_id, mensaje_inicial, estado, fecha`) — DDL entregado al usuario para ejecutar (sin acceso a ninguna BD desde este entorno). 2. `controllers/general/coach_solicitud.php` — clase `CoachSolicitud` con los 8 métodos (enviar/estado/pendientes/aceptar/rechazar/cancelar/enviar mensaje/historial), prepared statements reales. La mensajería reusa `comentario`, namespaced con `acceso`. 3. Rutas registradas en `api/index.php` bajo `/coach/solicitud/*`. 4. `coach-request.service.ts` reemplazado — de `localStorage` a `HttpClient` real, mismas interfaces públicas (`CoachRequest`/`ChatMessage`), ningún componente necesitó tocarse. **Ronda de bugs encontrados y corregidos durante las pruebas end-to-end (todo vía análisis estático — sin acceso a BD ni logs de producción):** 1. **DDL en la base equivocada** — primer intento de `enviarSolicitud` dio 500; el usuario había creado `coach_solicitud` en la BD incorrecta. Corregido (debe ir en `genniux_board`, la misma de `comentario`/`profileUser`). 2. **`coach.id` vs `coach.puesto`** — bug real, no de datos de prueba. `getListCoaches()` devolvía `id` = `perfil.id`, pero el resto del sistema (incluida la sesión del propio coach al revisar su inbox) identifica usuarios por `puesto`. La solicitud se guardaba con un `coach_id` que nunca iba a coincidir. Fix: `getListCoaches()` ahora hace join a `puesto` y expone ambos campos; `coach-message-panel.component.ts` usa `coach.puesto` (no `coach.id`) solo en las llamadas a la solicitud, sin tocar los demás usos de `coach.id` (avatar, nombre, modal). 3. **`enviarMensaje` 500 — INSERT con columnas nombradas omitía columnas ajenas** de `comentario` que podían ser `NOT NULL` sin default. Corregido replicando el INSERT posicional exacto del código legado (13 columnas, mismo orden), parametrizado. 4. **`acceso` es `varchar(8)`** — el namespace elegido (`'coach_solicitud'`, 15 caracteres) no cabía, causando el mismo tipo de 500. Acortado a `'coachreq'` (8 caracteres), tras el usuario compartir el `CREATE TABLE` real de `comentario`. 5. **Inbox del coach solo mostraba `pendiente`** — al aceptar una solicitud y recargar el navegador, el coach se quedaba sin forma de reentrar al chat (el panel es solo estado en memoria). Ampliado `listarSolicitudesPendientes()` para incluir también `aceptada`, con etiqueta visual por ítem ("Pendiente" naranja / "Chat activo" verde, mismos tokens de B06). **Resultado: ciclo completo verificado end-to-end por el usuario** — enviar solicitud, verla en el inbox del coach, aceptar, mandar mensaje, reabrir y ver el historial correcto, y continuar la conversación desde el lado del atleta (entra directo al chat activo, ve el mensaje del coach). **Rechazar y cancelar quedan sin probar** — el usuario va a limpiar los datos de prueba primero (se le dio un script de `DELETE` para `comentario`/`coach_solicitud` filtrado por `acceso='coachreq'`). **Aclaración de arquitectura de chats (resuelta con el usuario, cierre del día):** Coach = 1:1 (B09, confirmado). Atleta (caso general) = 1:1, sigue en el sistema legado. Atleta-Relay (B06) = única excepción que se vuelve grupal, y solo tras confirmarse el equipo. Club = **no es grupal** — "contactar al club" ya significa contactar al capitán/coach responsable (1:1), pero ese botón (`club-profile-modal.component.ts::sendMessage()`) sigue apuntando al chat legado (`/chat?to=capitan.id`), nunca se migró al mecanismo de B09. Documentado como **B12**, nuevo en el backlog. --- ## Decisiones - **B04 se elimina del backlog** — decisión explícita del usuario de no invertir en ese bug. - **B09 ya no depende de Jesús** — Gustavo construye el backend real directamente, decisión del usuario. - **B10 se implementa de inmediato** (la solución ya estaba identificada desde el 2026-07-02) — no había ambigüedad que resolver. - **B11 se resuelve con endpoint nuevo** (no snapshot congelado en la solicitud) — mismo shape que `getListAtletas()`/`getListCoaches()`, filtrado a un solo atleta, para que `athlete-profile-modal` no necesite adaptarse. Documentado, no construido — es trabajo futuro. - **Mensajería de B09 reusa la tabla `comentario` existente**, no una tabla nueva — namespaced por `acceso` para aislarse del resto del sistema (Ticket/Document/Forum/etc.), evitando construir un sistema de mensajes desde cero. - **INSERT a `comentario` debe replicar la forma posicional del código legado**, no columnas nombradas — lección de esta sesión: sin ver el `CREATE TABLE` real, cualquier omisión de columna es una apuesta a ciegas sobre constraints `NOT NULL`/tamaños de `varchar` que no se pueden inferir solo leyendo el código que las usa. - **El inbox del coach se amplía a `pendiente`+`aceptada`**, pero sigue sin ser el inbox completo del mockup — cambio mínimo para no perder acceso a chats activos tras un refresh, no una decisión de construir la vista completa. - **Debugging estrictamente por análisis estático** — sin acceso a BD ni a logs de producción (`genniux.net` resuelve a IPs de Cloudflare, es servidor remoto, no el docker local). Cada bug de esta sesión se diagnosticó pidiendo evidencia puntual al usuario (payload de red, estructura real de tabla) en vez de adivinar y aplicar cambios especulativos repetidos. --- ## NEXTs Ver backlog vivo para el detalle completo: 📋 [`BCK-EL-Gustavo-RCH-v01.md`](../BCK-EL-Gustavo-RCH-v01.md) **B09 — backend real construido y verificado end-to-end para el flujo principal:** - ✅ Análisis de reciclaje del chat legado. - ✅ Tabla `coach_solicitud` + `coach_solicitud.php` (8 métodos) + rutas en `api/index.php`. - ✅ `coach-request.service.ts` conectado a HTTP real. - ✅ 5 bugs encontrados y corregidos durante las pruebas (BD equivocada, `coach.id` vs `puesto`, INSERT posicional, `varchar(8)` de `acceso`, inbox solo-pendientes). - ✅ Verificado: enviar solicitud, inbox del coach, aceptar, mensaje, historial, continuar como atleta. - ⬜ Falta probar: rechazar, cancelar (usuario limpiará datos de prueba primero). - ⬜ Gap conocido sin resolver: `atletaContext` incompleto al leer una solicitud existente (depende de B11). **Otros abiertos:** - **B06** — relay buscando/completo, bloqueado hasta tener el chat grupal (dependencia de B09, sección grupal aún no tocada). - **B11** — endpoint de perfil de un solo atleta, decisión tomada, no construido. - **B12** (nuevo hoy) — migrar "Contactar al coach" del modal de Club del chat legado al mecanismo de B09. --- ## Estado de git al cierre - **Frontend** (`rebelocity-club`, rama `gustavo`): el usuario ya commiteó la mayor parte del trabajo del día durante la sesión: - `3ca1a35 integracion de chat para coach` (2026-07-02) — build original de B09 como mock (paso 1-5 de la minuta anterior). - `5ffcb7c enviar y aceptar mensaje` (2026-07-03, 14:16) — incluye B10 (`athlete-directory.component.ts`/`myProfile`), el fix de `coach.puesto` (`coach-message-panel.component.ts`), el fix de z-index (`coach-message-panel.component.less`), y `coach-request.service.ts` completo (mock → HTTP real). - **Sin commitear al cierre:** `coach-inbox-badge.component.html`/`.less` — la ampliación a `pendiente`+`aceptada` con la etiqueta visual (el último cambio de la sesión, hecho después del commit `5ffcb7c`). - **Backend** (`archivos-server`, fuera de git de este repo): `api/controllers/general/coach_solicitud.php` (nuevo), `api/index.php` (rutas nuevas), `api_rch/controllers/rebelocity/general.php` (join a `puesto` en `getListCoaches()`) — subidos al servidor por el usuario durante la sesión, en varias iteraciones conforme se corrigieron los bugs. - **Manual del usuario, ejecutado durante la sesión:** DDL de `coach_solicitud` (corregido de BD equivocada a `genniux_board`). - **Manual del usuario, pendiente:** commitear `coach-inbox-badge.component.html`/`.less`; limpiar datos de prueba (`comentario`/`coach_solicitud`, script de `DELETE` ya entregado) antes de probar rechazar/cancelar.