8.9 KiB
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_idvacío en las citas que no pudo resolver.docs/migracion-concentrado.mdcifra en ~8,350 las asociadas a los doctores fantasma (ids legacy 34–39/44/51), pero hoy la base tiene ~27,500 citas conlegacy_idy 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.mddecí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.mdlistaba--packcongenericopor defecto y los valoresgenerico, spa, clinica, derma: los reales son defaultclinicayclinica, spa, estetica, dental, custom.docs/producto/api-terceros.mdno listaba el endpoint/skeen/api/v1/health(público, sin credencial). Se agregó.