## CU-03-006: Instructor inicia sesión en vivo

**Fecha:** 11 de marzo de 2026  
**Caso de uso:** CU-03-006 – Instructor inicia sesión en vivo  
**Ámbito:** Flujo técnico de inicio de sesión en vivo con BigBlueButton (BBB)

---

## Objetivo del documento

Este documento complementa la especificación funcional del caso de uso **CU-03-006: Instructor inicia sesión en vivo** y se enfoca en:

- **Qué se agregó o modificó en el código** para permitir que el instructor inicie una sesión BBB desde el panel.
- **Cómo es el flujo de trabajo técnico** desde que el instructor ve la sesión programada hasta que entra a la sala BBB como moderador.
- **Cómo se validan las restricciones de tiempo** (inicio máximo 15 minutos antes).
- **Cómo y a quién se notifican los estudiantes** cuando la sesión cambia a estado "En Vivo".

La integración de bajo nivel con BBB (servicio HTTP, configuración y credenciales) se describe en el documento `(CU-03-005) Integración técnica BBB (FS-48).md`. Aquí solo se detalla la lógica específica para iniciar la sesión en vivo.

---

## Archivos agregados y modificados

- **Modificado – Componente Livewire de creación de sesión**
  - `app/Livewire/Instructor/LiveSessions/Create.php`
  - **Cambios clave:**
    - Ajuste de la lógica de `updatedType()` para sesiones **one_to_one**:
      - `max_participants` se fuerza a **2** (instructor + estudiante).
      - La validación asegura que el mínimo de participantes sea **2** en este tipo de sesión.
    - Confirmación de que las opciones avanzadas ya se envían correctamente hacia BBB a través de `BigBlueButtonService::createMeeting()`:
      - `record_session`
      - `duration_minutes`
      - `max_participants`
    - De esta forma, cuando el instructor más adelante inicie la sesión en vivo (CU-03-006), la reunión en BBB ya cuenta con la configuración correcta de grabación, duración y cupos.

- **Agregado – Notificación de inicio de sesión en vivo**
  - `app/Notifications/LiveSessionStarted.php`
  - **Por qué:**
    - Encapsula la notificación que se envía automáticamente a los estudiantes cuando la sesión pasa a estado **live**.
  - **Características principales:**
    - Usa al menos canales **database** e **email** para notificar a los estudiantes.
    - Mensaje estándar:  
      `"La sesión [título] ha iniciado. ¡Únete ahora!"`.
    - Incluye un enlace hacia la pantalla donde el estudiante deberá unirse a la sesión (por ahora se utiliza una ruta de estudiante **placeholder**, ver sección de consideraciones).

- **Modificado – Vista de listado de sesiones del instructor**
  - `resources/views/livewire/instructor/live-sessions/index.blade.php`
  - **Cambios clave en la UI:**
    - Cuando `status === 'scheduled'`:
      - Se muestra un botón **"Iniciar Sesión"** para el instructor.
    - Cuando `status === 'live'`:
      - Se muestra un botón **"Unirse"**, de forma similar al comportamiento descrito en CU-03-005.
    - Ambos botones apuntan a la misma ruta de join del instructor, pero el comportamiento interno cambia según el estado de la sesión (ver siguiente sección).

- **Modificado – Ruta de join del instructor y flujo de inicio**
  - `routes/tenant.php`
  - **Ruta relevante:**
    - `GET /instructor/live-sessions/{liveSession}/join`
  - **Cambios clave en la lógica:**
    - Verifica que el usuario autenticado sea el **instructor asignado** a la sesión.
    - Agrega una restricción de tiempo:
      - Si el instructor intenta iniciar la sesión **más de 15 minutos antes** del `start_at` programado, no se permite el inicio.
      - En ese caso se devuelve un mensaje de error del estilo:  
        `"Puedes iniciar la sesión 15 minutos antes del horario programado"`.
    - Si la sesión está en estado `scheduled` y pasa las validaciones:
      - Actualiza el estado de la sesión a **`live`**.
      - Dispara la notificación `LiveSessionStarted` a los estudiantes inscritos (según la lógica de negocio definida para el curso/sesión).
    - Si la sesión ya está `live`:
      - Solo construye la URL de unión a BBB y redirige al instructor (es decir, actúa como "reunirse" en lugar de "iniciar").
    - Usa `BigBlueButtonService::joinMeeting()` para generar la URL hacia BBB con rol **moderator**, usando `bbb_moderator_password` de la sesión.
    - Redirige con `redirect()->away($joinUrl)` para abrir la sala BBB en una nueva pestaña.

- **Modificado – .gitignore**
  - `.gitignore`
  - Pequeños ajustes de exclusiones de archivos (no relacionados directamente con la lógica de CU-03-006).

---

## Flujo de trabajo técnico: Instructor inicia sesión en vivo

### 1. Instructor ve la sesión programada

1. El instructor accede a la pantalla de **"Mis Sesiones"**:
   - Ruta: `/instructor/live-sessions`
   - Componente: `App\Livewire\Instructor\LiveSessions\Index`
2. Para cada sesión, la vista muestra:
   - Estado actual (`scheduled`, `live`, etc.).
   - Botón contextual:
     - **"Iniciar Sesión"** si la sesión está `scheduled`.
     - **"Unirse"** si la sesión ya está `live`.

### 2. Click en "Iniciar Sesión"

1. El instructor hace clic en el botón **"Iniciar Sesión"**:
   - URL: `route('instructor.live-sessions.join', $liveSession)`
   - Target: normalmente `_blank` (para que la sala BBB se abra en pestaña nueva mientras el panel sigue abierto).
2. La petición llega a la ruta definida en `routes/tenant.php`:
   - Se recupera la instancia de `LiveSession` según el `{liveSession}` de la URL.
   - Se verifica:
     - Que el usuario autenticado es el `instructor_id` de la sesión.
     - Que la sesión no está en un estado incompatible (por ejemplo, completada o cancelada).

### 3. Validación de ventana de tiempo (15 minutos antes)

1. Se calcula la diferencia entre la hora actual y la hora de inicio programada (`start_at`).
2. Si la hora actual es:
   - **Más de 15 minutos antes** del inicio:
     - No se permite iniciar la sesión.
     - Se devuelve un mensaje de error al instructor indicando que solo puede iniciar **15 minutos antes** del horario programado.
   - Dentro de los **15 minutos previos** o después de la hora programada:
     - Se permite continuar con el flujo.

### 4. Cambio de estado y notificaciones

Si la sesión está en estado `scheduled` y pasa las validaciones anteriores:

1. Se actualiza el estado de la sesión a **`live`** (por ejemplo, `status = 'live'`).
2. Se despacha la notificación `LiveSessionStarted` a los estudiantes con reserva/inscripción al curso:
   - Canal **database** (in-app).
   - Canal **email**.
3. El contenido base de la notificación es:
   - Asunto/mensaje: `"La sesión [título] ha iniciado. ¡Únete ahora!"`.
   - Enlace: ruta de estudiante para unirse a la sesión (actualmente un **placeholder**, ver consideraciones).

Si la sesión ya estaba `live`, esta parte se omite y se pasa directamente a la generación de la URL de unión.

### 5. Generación de URL BBB y redirección

1. La ruta invoca `BigBlueButtonService::joinMeeting()` usando:
   - `meetingID` → `bbb_meeting_id` de la sesión.
   - `fullName` → nombre del instructor autenticado.
   - `password` → `bbb_moderator_password`.
   - Rol → `MODERATOR`, para asegurar permisos completos (compartir pantalla, administrar usuarios, finalizar sesión, etc.).
2. El servicio construye la URL de unión a BBB (detalles del checksum y firma están documentados en CU-03-005).
3. La aplicación redirige al instructor con `redirect()->away($joinUrl)`, abriendo la sala BBB en una nueva pestaña.

### 6. Flujo dentro de BBB

Una vez dentro de la sala BBB (fuera del alcance directo de Laravel), el instructor puede:

- Compartir pantalla.
- Activar/desactivar cámaras y micrófonos.
- Usar pizarra.
- Grabar la sesión, si `record_session` fue activado al momento de programar la sesión.
- Finalizar la sesión desde la UI de BBB.

---

## Flujo alternativo y manejo de errores

- **Intento de iniciar más de 15 minutos antes:**
  - La ruta de join detecta que la hora actual está fuera de la ventana permitida.
  - Devuelve un mensaje indicando que solo es posible iniciar **15 minutos antes** del horario programado.
  - No se cambia el estado de la sesión ni se llama a BBB.

- **Error de conexión con BBB al generar la URL de join:**
  - Si `BigBlueButtonService::joinMeeting()` lanza una excepción o devuelve un error:
    - Se muestra un mensaje de error técnico al instructor.
    - Se puede reintentar nuevamente desde el botón en la UI.
    - Según la configuración del proyecto, se puede ofrecer una opción para contactar soporte o loguear el incidente de forma detallada.

---

## Consideraciones y limitaciones actuales

- **Ruta de estudiante para unirse a la sesión:**
  - La notificación `LiveSessionStarted` incluye una llamada a `route('student.live-sessions.join', $liveSession)` o similar como **placeholder**.
  - Esa ruta aún no existe en el proyecto (probablemente será implementada en otro caso de uso, por ejemplo CU-04-005 o relacionado).
  - Hasta que dicha ruta exista, los estudiantes podrán recibir la notificación, pero el enlace directo deberá ajustarse cuando se implemente el flujo del lado del estudiante.

- **Notificaciones por WhatsApp:**
  - El flujo funcional menciona notificaciones por **WhatsApp**, pero la implementación actual solo cubre:
    - Notificación **in-app** (database).
    - Notificación **email**.
  - El envío por WhatsApp requerirá una integración externa adicional (proveedor de mensajería) y no forma parte de esta tarea.

- **Grabación automática:**
  - La capacidad de grabar está ligada al campo `record_session` y a cómo se creó la reunión en BBB en CU-03-005.
  - Al iniciar la sesión en vivo, si la reunión BBB se creó con grabación habilitada, la grabación se gestionará según las reglas del servidor BBB.

---

## Testing recomendado para CU-03-006

Aunque los tests existentes del proyecto pasan (salvo un error de Filament no relacionado con estos cambios), se recomienda agregar pruebas específicas para este caso de uso, idealmente con Pest, por ejemplo:

- **Actualización de estado a live al iniciar:**
  - Verificar que, al llamar a la ruta `instructor.live-sessions.join` para una sesión `scheduled` dentro de la ventana válida, el `status` cambie a `live`.

- **Envío de notificaciones a estudiantes:**
  - Mockear `LiveSessionStarted` o el sistema de notificaciones.
  - Verificar que se envía la notificación a los estudiantes inscritos cuando la sesión pasa a `live`.

- **Validación de ventana de tiempo (15 minutos):**
  - Probar que, si se intenta iniciar más de 15 minutos antes, la ruta:
    - No cambia el estado de la sesión.
    - Devuelve el mensaje de error adecuado o un código de estado apropiado.

## Pendientes, riesgos y limitaciones

- **Ruta de estudiante para unirse**: La ruta `student.live-sessions.join` aún no existe. Cuando se implemente, hay que:
  - Actualizar `LiveSessionStarted` para usar la ruta real.
  - Probar end‑to‑end el flujo estudiante (notificación → click → join BBB).

- **Notificaciones por WhatsApp**: No implementadas. Requiere:
  - Seleccionar proveedor (API externa).
  - Definir canal de notificación y mapping con la preferencia del usuario.

- **Dependencia de BBB**:
  - Si BBB está caído o lento, el instructor verá errores al iniciar/unirse.
  - Se recomienda monitoreo/logs específicos para detectar fallos recurrentes en `joinMeeting`.

- **Control de concurrencia/estado**:
  - No se bloquea explícitamente que se intente poner `live` una sesión ya completada/cancelada desde otro flujo.
  - Si se agregan nuevos estados, revisar esta ruta para evitar estados inconsistentes.
  
Estas pruebas asegurarán que el flujo de inicio de sesión en vivo para el instructor se mantiene estable frente a cambios futuros y que la lógica de negocio (tiempos, estados y notificaciones) se respeta correctamente.

