# Limitaciones y pendientes conocidos Lista honesta y priorizada de la deuda técnica y los huecos del producto, con su impacto. Cada punto dice qué pasa, a quién afecta y qué habría que hacer. Se actualiza a medida que se cierran. Prioridad: **Alta** = riesgo o función prometida que no está; **Media** = afecta la operación o la venta de algún cliente; **Baja** = deuda de orden. --- ## Prioridad alta ### 1. Firma de licencias simétrica (HMAC) **Qué pasa:** la clave de licencia se firma con HMAC-SHA256 y la clave del vendedor debe estar presente en la instancia para validarla (parámetro `skeen.licencia.vendor_key`, entorno o `/root/.skeen-licencias/vendor.key`). Al ser simétrica, un cliente con acceso al servidor puede leerla y **generar sus propias licencias** (módulos y límites a su gusto). **A quién afecta:** al negocio (se pierde el control comercial del licenciamiento). **Qué habría que hacer:** migrar a **firma asimétrica** (el vendedor firma con clave privada; la instancia solo lleva la pública para verificar). Mientras tanto, mantener la clave del vendedor fuera de las instancias de cliente en un despliegue real. ### 2. Llaves embebidas en `webhook-bridge.js` **Qué pasa:** `/root/skeen-proyecto/hermes/hermes/webhook-bridge.js` trae llaves como *fallback* embebidas en el código (proveedor de IA, Hermes y WACRM). Cualquiera con acceso al repo las ve. **A quién afecta:** seguridad (las llaves pueden filtrarse y usarse). **Qué habría que hacer:** retirar los valores por defecto, exigir variables de entorno y **rotar** las llaves expuestas. No es tarea de la documentación: es un riesgo a sanear en el código. ### 3. Asistente de IA de WhatsApp (Sofía/Hermes) en reparación **Qué pasa:** la herramienta del asistente para consultar y agendar estaba rota: faltaba `ODOO_API_KEY`, el sandbox de `execute_code` estaba bloqueado y había *rate limit* del proveedor. La bandeja y los leads de WhatsApp sí funcionan. **A quién afecta:** al cliente que espera el bot autónomo de WhatsApp. **Qué habría que hacer:** cerrar el arreglo (clave, sandbox y límite del proveedor) y **actualizar esta sección a "resuelto" con la fecha**. No afirmar que ya funciona mientras no se valide de punta a punta. ### 4. Clave legacy de la API con todos los alcances **Qué pasa:** la API pública acepta la *clave legacy* de Hermes (`skeen.api.legacy_key`, default en el código `skeen_api_key_2026`), que **no tiene restricción de alcances**. Si una instancia conserva el valor por defecto, cualquiera que lo conozca tiene acceso total a la API. **A quién afecta:** seguridad de la API. **Qué habría que hacer:** confirmar que el parámetro se rotó en cada instancia y que no conserva el valor por defecto; usar claves con alcance para las integraciones nuevas. ### 5. Un límite de licencia excedido responde 500 en vez de 400 **Qué pasa:** al superar un límite (`usuarios_max`, `sucursales_max`, `citas_mes_max`, `almacenamiento_mb`) el backend lanza un error de negocio con mensaje claro, pero los controladores lo devuelven como **HTTP 500** en lugar de 400. **A quién afecta:** a los integradores (el código de estado no distingue "te pasaste del límite" de "algo se rompió"). **Qué habría que hacer:** capturar el error de límite en los controladores y responder **400** con el mensaje. --- ## Prioridad media ### 6. Secciones nuevas sin QA visual manual **Qué pasa:** en la instancia de pruebas las secciones Licencia / API / Webhooks, Comisiones y Compras se verificaron por API y por build, pero **no se recorrieron a mano** en el navegador. **A quién afecta:** riesgo de detalles de usabilidad (textos, estados, formatos) no detectados. **Qué habría que hacer:** una pasada manual por esas pestañas de Configuración y sus páginas (Compras, Liquidaciones) en un entorno con datos. ### 7. Precios reales del inventario en $0 **Qué pasa:** los ~170 artículos del inventario histórico siguen con precio de venta `$0` (verificado: 171 de 171 en la base principal). **A quién afecta:** POS (vendería en $0), reportes de margen y de ventas. **Qué habría que hacer:** capturar los precios con el cliente (carga masiva o manual) antes de usar márgenes y de vender productos. ### 8. Huecos del histórico migrado **Qué pasa:** - **799 folios de venta** ($1.29M, 2.5% del cobrado) no se importaron porque sus pacientes nunca se migraron a Odoo (documentado en `docs/migracion-concentrado.md`). - **Citas históricas sin médico:** el import dejó `doctor_id` vacío en las citas que no pudo resolver. `docs/migracion-concentrado.md` cifra en ~8,350 las asociadas a los doctores fantasma (ids legacy 34–39/44/51), pero hoy la base tiene **~27,500 citas con `legacy_id` y sin médico**, así que el total sin resolver es mayor que esa cifra. - **139 filas todo-$0** (sesiones de paquete) también omitidas. **A quién afecta:** a los reportes históricos (por médico, ingresos y comisiones retroactivas) y a la conciliación con el legacy. **Qué habría que hacer:** definir con el cliente si se resuelven los médicos de ese histórico (mapeo manual o heurística), recuperar los 799 folios si aparecen los pacientes, y **actualizar la cifra de citas sin médico** en el doc de migración para que no se contradiga con la base. ### 9. Cobertura de i18n incompleta **Qué pasa:** la internacionalización cubre las superficies principales y las páginas públicas, pero quedan sin traducir varias pantallas secundarias (Visitas, Consultas, Servicios, Médicos, Paquetes, Ventas, Mis ventas, Pagos, Monedero, Tickets, Cortes, Inventario, Compras, Liquidaciones, Membresías, Chat/WACRM y los paneles internos de Configuración) y los textos de impresión. Además el idioma es **por navegador** (no se persiste por clínica ni por usuario): `clinic-settings.idioma_default` no se guarda. **A quién afecta:** a los clientes que trabajan en inglés. **Qué habría que hacer:** ir traduciendo las pantallas secundarias por prioridad y, si se quiere, persistir el idioma por clínica o por usuario. ### 10. Glosario solo en español **Qué pasa:** el glosario (vocabulario de negocio) es por clínica y **solo existe en español**; en inglés se usa un mapa base equivalente, no el término personalizado del cliente. **A quién afecta:** clientes que configuran términos propios y trabajan en inglés. **Qué habría que hacer:** decidir si hace falta glosario por idioma; hoy es una limitación de diseño aceptada. ### 11. El pack demo "dental" siembra servicios de dermatología/estética **Qué pasa:** en `postinstall_clinica.py`, los servicios de demo del pack `dental` son de otro giro ("Consulta dermatológica", "Peeling químico", "Depilación láser"…). Un demo dental muestra el catálogo equivocado. **A quién afecta:** demos y arranques de clientes dentales. **Qué habría que hacer:** reemplazar ese set por servicios dentales reales (y verificar los demás packs). ### 12. Alcanzabilidad de la instancia de pruebas **Qué pasa:** `clinica.consultoria-as.com` puede no ser alcanzable desde fuera hasta que se agregue el *hostname* en el túnel de Cloudflare (el túnel es administrado remotamente). El acceso LAN siempre funciona. **A quién afecta:** demos y QA remotos. **Qué habría que hacer:** agregar el *ingress* en el dashboard de Cloudflare y verificar la URL pública. --- ## Prioridad baja ### 13. Retención de backups frente a más instancias **Qué pasa:** la retención es por instancia (14 diarios / 8 semanales / 6 mensuales); cada cliente nuevo suma un juego de backups y disco. **A quién afecta:** al operador de la VPS. **Qué habría que hacer:** revisar el espacio antes de sumar clientes y ajustar `RETAIN_*` en `backup.env` si es necesario. La verificación de restauración se auto-omite si no hay espacio. ### 14. Rotación del nombre del *manifest* / iconos de la PWA **Qué pasa:** el manifest de la PWA usa nombre e iconos **fijos por build** ("Panel Clínico"); no toman la marca de la instancia. **A quién afecta:** presentación (al instalar la app el icono/nombre no es el del cliente). **Qué habría que hacer:** si se quiere icono por cliente, generar un manifest por instancia en el despliegue; hoy se acepta como limitación (la marca dentro del panel sí es por instancia). --- ## Corregido en esta pasada de documentación Para que no vuelva a citarse como pendiente: - `docs/producto/configuracion-cliente.md` decía "43 permisos por acción agrupados en 9 módulos": el catálogo actual es de **71 permisos en 16 grupos**. - La tabla "Estado del producto por fases" marcaba las fases 2.4–2.6 y 3 como pendientes: **todas están entregadas**. - `docs/nueva-instancia.md` listaba `--pack` con `generico` por defecto y los valores `generico, spa, clinica, derma`: los reales son default `clinica` y `clinica, spa, estetica, dental, custom`. - `docs/producto/api-terceros.md` no listaba el endpoint `/skeen/api/v1/health` (público, sin credencial). Se agregó.