# Kings & Queens: OTP por WhatsApp y agenda unificada de apoyo escolar

**Fecha:** 2026-06-21

**Estado:** Diseño aprobado

**Sistema productivo:** Kings & Queens (`www.kingsandqueens.com.ar`, PocketBase KQ, Sam en n8n/Chatwoot y Evolution `Kings-and-Queens`)

## 1. Objetivo

Agregar dos capacidades conectadas a la plataforma actual:

1. Inicio de sesión alternativo mediante OTP por WhatsApp, enviado desde el número de Sam, sin eliminar el acceso por email y contraseña.
2. Gestión y reserva de clases de apoyo escolar de inglés desde el calendario existente de Ale, con cupos, seña por transferencia y operación conversacional mediante Sam.

El cambio debe conservar la identidad visual actual, los datos existentes y el funcionamiento de las clases normales.

## 2. Decisiones aprobadas

- PocketBase será la fuente de verdad para autenticación, relaciones familiares, agenda, cupos, pre-reservas, comprobantes y confirmaciones.
- No habrá autorregistro por OTP. Solo podrán usarlo las cuentas activas ya cargadas por Ale.
- El OTP también estará disponible para Ale.
- Un responsable tendrá cuenta propia y podrá estar vinculado a varios alumnos.
- Los alumnos menores conservarán su cuenta individual y su acceso a la plataforma.
- El WhatsApp propio del alumno será opcional. Si un menor no tiene número propio, el OTP se enviará al responsable.
- El calendario actual será el único calendario operativo. Las clases normales y el apoyo escolar aparecerán juntos.
- El apoyo escolar será únicamente de inglés para nivel primario y secundario.
- Cada horario de apoyo tendrá duración fija, cupo configurable con valor predeterminado de 2 y seña configurable con valor predeterminado de ARS 5.000.
- Cualquier persona podrá reservar por WhatsApp aunque no sea usuaria registrada.
- Sam mostrará los tres próximos horarios compatibles con la preferencia informada.
- La pre-reserva retendrá el cupo durante 12 horas.
- La seña se pagará por transferencia y Ale aprobará o rechazará el comprobante desde la app.
- Por ahora, Sam enviará únicamente la confirmación de la seña. No habrá recordatorios automáticos.
- Cancelando con más de 24 horas, la seña queda como crédito para una única reprogramación. Con menos de 24 horas, se pierde.
- Por ahora, suspender un horario desde el panel no disparará avisos ni reprogramaciones automáticas.

## 3. Arquitectura

### 3.1 Fuente de verdad

PocketBase KQ concentrará las reglas transaccionales. El frontend estático y los workflows de Sam consumirán rutas de backend; ninguna regla crítica de cupos, OTP o confirmación dependerá del navegador o del prompt del agente.

### 3.2 Componentes

- **Frontend K&Q:** amplía `login.html` y `teacher.html`, manteniendo estilos y navegación actuales.
- **PocketBase hooks:** implementan OTP, selección de identidad, disponibilidad, retención de cupos, vencimientos, comprobantes y aprobación.
- **Sam / n8n:** incorpora herramientas para buscar horarios, crear pre-reservas, registrar comprobantes, cancelar y reprogramar.
- **Evolution API:** envía OTP y confirmaciones usando la instancia `Kings-and-Queens`.
- **Chatwoot:** mantiene la conversación y aporta teléfono, nombre, `conversation_id` y adjuntos.

### 3.3 Límites de responsabilidad

- PocketBase decide si un horario tiene cupo y si una reserva puede cambiar de estado.
- n8n orquesta la conversación, pero no calcula cupos ni aprueba pagos.
- El frontend presenta y administra datos autorizados; no contiene credenciales de Evolution ni secretos administrativos.

## 4. Modelo de identidad y responsables

### 4.1 Roles

La colección auth `users` conservará el campo productivo `rol` y admitirá:

- `teacher`
- `student`
- `guardian`

No se renombrará `rol` a `role` porque el frontend productivo ya depende del nombre actual.

### 4.2 Perfiles y vínculos

- `guardian_profiles`: datos del adulto responsable, incluido WhatsApp obligatorio.
- `student_profiles`: conserva los datos actuales y agrega la condición de menor/adulto y teléfono propio opcional.
- `student_guardians`: relación entre responsables y alumnos. Permitirá varios alumnos por responsable y dejará preparada la relación inversa sin duplicar datos.

Para alumnos adultos no será obligatorio asociar un responsable.

### 4.3 Migración

- Los alumnos actuales conservarán usuario, contraseña, perfil, clases y facturación.
- Los teléfonos existentes se normalizarán al formato internacional usado por Evolution.
- Ale podrá completar responsable y teléfono desde el formulario de alumno.
- La migración no creará responsables ficticios ni bloqueará alumnos existentes con datos incompletos; la app mostrará qué registros necesitan completarse para usar OTP.

## 5. Inicio de sesión por OTP

### 5.1 Interfaz

`login.html` conservará email/contraseña y agregará “Ingresar con WhatsApp”. El flujo tendrá tres estados:

1. Ingreso del número.
2. Ingreso del código de 6 dígitos.
3. Selección de identidad cuando el mismo WhatsApp habilite más de una cuenta.

La selección se mostrará únicamente después de validar el código para no exponer nombres asociados a un número.

### 5.2 Reglas de entrega

- Profesora y responsables: se usa el WhatsApp de su perfil.
- Alumno con WhatsApp propio: se usa su número.
- Alumno menor sin WhatsApp propio: se usa el WhatsApp de su responsable.
- Un responsable con varios hijos podrá elegir entre su cuenta y las cuentas de los alumnos habilitados por ese número.

### 5.3 Seguridad

- Código numérico de 6 dígitos.
- Vigencia de 5 minutos.
- Máximo de 5 intentos.
- Reenvío permitido cada 60 segundos.
- Código de un solo uso y almacenamiento con hash.
- Respuesta genérica al solicitar OTP, exista o no el número.
- Solo cuentas activas y previamente registradas.
- Límite por teléfono e IP para reducir abuso.
- Los eventos de seguridad se registrarán sin guardar el código en logs.

### 5.4 Rutas propuestas

- `POST /api/kq/auth/request-otp`
- `POST /api/kq/auth/verify-otp`
- `POST /api/kq/auth/select-identity`

La verificación emitirá un desafío temporal. La sesión normal de PocketBase se entregará después de elegir una identidad válida.

## 6. Calendario unificado

### 6.1 Experiencia de Ale

El calendario actual será la única vista de agenda. Mostrará:

- clases normales existentes;
- horarios de apoyo escolar;
- cupos ocupados y disponibles;
- pre-reservas pendientes de seña;
- reservas confirmadas.

Los tipos se distinguirán mediante color y etiqueta, con filtros opcionales. Desde una misma celda o fecha Ale podrá crear una clase normal o un horario de apoyo.

### 6.2 Separación técnica sin separación visual

Las clases normales seguirán en `classes` para no migrar ni arriesgar el flujo actual. Los horarios de apoyo usarán colecciones específicas y el frontend combinará ambos orígenes en una única agenda.

El backend comprobará conflictos contra ambos conjuntos: una clase normal bloqueará un horario de apoyo incompatible y viceversa. No se permitirá solapamiento para Ale.

### 6.3 Planificación anual

- Ale podrá navegar y planificar todo el año.
- Cada fecha será independiente; modificar una semana no alterará las demás.
- Se podrá copiar una semana a otras fechas como acelerador de carga.
- La copia generará registros por fecha que luego podrán editarse o suspenderse individualmente.

## 7. Modelo de apoyo escolar

### 7.1 Colecciones

#### `support_slots`

- fecha;
- hora de inicio y fin;
- estado `open` o `suspended`; la condición de cupo completo se calculará desde las reservas vigentes;
- capacidad, predeterminada en 2;
- importe de seña, predeterminado en ARS 5.000;
- notas internas;
- datos de auditoría.

#### `support_bookings`

- horario asociado;
- nombre del alumno;
- teléfono de la conversación;
- nombre del responsable cuando corresponda;
- nivel `primary` o `secondary`;
- grado o año;
- tema de inglés;
- `conversation_id` de Chatwoot;
- estado `held`, `payment_review`, `confirmed`, `rejected`, `cancelled`, `expired` o `credit`;
- vencimiento de la retención;
- importe de seña;
- comprobante;
- crédito y uso de reprogramación;
- datos de auditoría.

#### `support_settings`

Registro único con capacidad predeterminada, seña predeterminada, duración de retención, política de cancelación, alias/instrucciones de transferencia y límites de consulta.

### 7.2 Capacidad y concurrencia

- `held`, `payment_review` y `confirmed` consumen cupo.
- `held` vence a las 12 horas si no se adjunta un comprobante. Al pasar a `payment_review`, deja de vencer automáticamente y conserva el cupo hasta la decisión de Ale.
- `cancelled`, `expired` y créditos no asignados no consumen cupo.
- Crear una retención será una operación transaccional de backend.
- Si dos personas intentan tomar el último cupo, solo una operación podrá confirmarse.
- Un proceso periódico liberará retenciones vencidas.
- Las llamadas repetidas de n8n serán idempotentes mediante una clave derivada de conversación, horario y acción.

## 8. Flujo conversacional de Sam

### 8.1 Información que recopila

1. Nombre del alumno.
2. Nivel primario o secundario.
3. Grado o año.
4. Tema de inglés que necesita reforzar.
5. Preferencias de día y franja horaria.

El teléfono se toma de la conversación. Si quien escribe es responsable, Sam registra también su nombre.

### 8.2 Reserva

1. Sam consulta disponibilidad real en PocketBase.
2. Muestra los tres próximos horarios compatibles con cupo.
3. La persona elige uno.
4. PocketBase crea una pre-reserva por 12 horas y consume temporalmente un cupo.
5. Sam envía importe, alias e instrucciones de transferencia.
6. La persona envía el comprobante.
7. n8n descarga el adjunto desde Chatwoot y lo registra en PocketBase.
8. La pre-reserva pasa a `payment_review`.
9. Ale aprueba o rechaza desde la app.
10. Al aprobar, la reserva pasa a `confirmed` y Sam envía la confirmación desde su número.
11. Al rechazar, la reserva pasa a `rejected`, el cupo se libera y Ale gestiona manualmente la comunicación desde Chatwoot.

### 8.3 Cancelación y reprogramación

- Con más de 24 horas, la reserva pasa a crédito reutilizable una sola vez.
- Con menos de 24 horas, se cancela sin crédito.
- Reprogramar consume el crédito y crea la nueva asignación de forma atómica.
- No se implementarán reembolsos automáticos.

### 8.4 Herramientas n8n

- `search_support_slots`
- `hold_support_slot`
- `attach_support_receipt`
- `cancel_support_booking`
- `reschedule_support_booking`

Las herramientas devolverán resultados estructurados y mensajes aptos para el cliente, sin exponer errores internos.

## 9. Panel de Ale

### 9.1 Calendario

- Vista anual y navegación mensual/semanal dentro del calendario actual.
- Creación y edición de clases normales y horarios de apoyo desde el mismo punto.
- Indicadores de tipo, estado y ocupación.
- Copia de semana con revisión antes de guardar.
- Validación de solapamientos.

### 9.2 Reservas y comprobantes

Al abrir un horario de apoyo, Ale verá:

- capacidad y ocupación;
- reservas confirmadas;
- pre-reservas y vencimiento;
- datos del alumno y responsable;
- tema solicitado;
- comprobante;
- acciones de aprobar, rechazar, cancelar o reprogramar.

La aprobación será la única acción que confirme una seña pagada por transferencia.

### 9.3 Formulario de alumnos

- Indicador de menor/adulto.
- Datos del responsable.
- WhatsApp principal del responsable.
- WhatsApp opcional del alumno.
- Vinculación de hermanos con un responsable existente.
- Estado visible de habilitación para OTP.

## 10. Manejo de errores

- Si un horario se completa antes de confirmar la retención, Sam ofrecerá nuevas opciones.
- Si falla la carga del comprobante, la reserva no avanzará a revisión.
- Si una retención vence antes de recibir comprobante, cualquier aprobación posterior será rechazada y Ale deberá crear una nueva reserva.
- Si n8n repite una operación, PocketBase devolverá el resultado existente.
- Si una herramienta falla, Sam responderá de forma humana y derivará internamente sin mencionar infraestructura.
- Los errores operativos quedarán registrados con identificadores de correlación, sin códigos OTP ni secretos.

## 11. Seguridad y secretos

- Evolution y PocketBase administrativo solo se usarán desde backend o n8n.
- Los comprobantes tendrán tipos permitidos, límite de tamaño y acceso autenticado.
- Las reglas de PocketBase impedirán que alumnos o responsables lean reservas ajenas.
- Los nuevos endpoints validarán estado, rol y propiedad en cada operación.
- Las credenciales administrativas de KQ actualmente embebidas en configuración versionada deben migrarse a variables del servidor y rotarse durante el despliegue. Ningún valor secreto se documentará ni se copiará al frontend.

## 12. Pruebas y verificación

### 12.1 OTP

- Email/contraseña sigue funcionando para Ale y alumnos.
- OTP funciona para Ale, responsable y alumno adulto.
- Alumno menor con WhatsApp propio recibe su código.
- Alumno menor sin WhatsApp propio usa el número del responsable.
- Un responsable con hermanos puede elegir la identidad después de validar el código.
- Código vencido, incorrecto, reutilizado o excedido es rechazado.
- Un número no registrado no permite crear sesión.

### 12.2 Calendario

- Clases normales existentes aparecen sin cambios.
- Horarios de apoyo aparecen en la misma agenda.
- No se permiten solapamientos entre ambos tipos.
- Copiar una semana crea fechas independientes.
- Capacidad y seña usan los valores predeterminados y permiten modificación.

### 12.3 Reservas

- Sam ofrece solo horarios reales y muestra como máximo tres.
- La pre-reserva consume cupo por 12 horas.
- Dos solicitudes simultáneas no sobrepasan capacidad.
- El vencimiento libera el cupo.
- El comprobante llega al panel de Ale.
- Aprobar confirma y dispara un único mensaje de Sam.
- Cancelación y crédito respetan el límite de 24 horas y una sola reprogramación.

### 12.4 Verificación productiva

La entrega se considera completa únicamente después de verificar en producción:

1. OTP recibido desde el número de Sam y sesión válida en la app.
2. Calendario unificado con datos existentes intactos.
3. Reserva real de prueba desde WhatsApp hasta `payment_review`.
4. Aprobación desde el panel y confirmación recibida por WhatsApp.
5. Contenedores, PocketBase, n8n, Chatwoot y Evolution saludables después del despliegue.

## 13. Fuera de alcance actual

- Autorregistro mediante OTP.
- Pago automático por Mercado Pago u otro PSP.
- Validación bancaria automática de transferencias.
- Recordatorios de clase.
- Avisos automáticos al suspender un horario.
- Reembolsos automáticos.
- Apoyo de materias distintas de inglés.
- Nivel terciario o universitario para el módulo de apoyo escolar.
- Sustitución del calendario actual por una aplicación nueva.

## 14. Criterios de aceptación

- El login dual funciona sin degradar el acceso actual.
- OTP se envía desde Sam únicamente a identidades registradas y autorizadas.
- Responsables y hermanos quedan representados sin duplicar datos de contacto.
- Ale gestiona clases normales y apoyo desde un calendario visualmente unificado.
- Sam nunca ofrece ni retiene un cupo inexistente.
- Toda pre-reserva vence a las 12 horas si no avanza a revisión.
- Solo Ale confirma la seña por transferencia desde la app.
- La confirmación sale una sola vez desde el número de Sam.
- Los datos existentes permanecen íntegros y el despliegue tiene evidencia de verificación productiva.
