Files
AgendaPro/AUDIT.md
AgendaPro DevandClaude Opus 5 6d67b23e55 feat(platform): multi-tenancy con credenciales por negocio y sincronización por id
El backend Postgres de `platform/` asumía un solo negocio con un solo token del
CRM. Este cambio lo convierte en una plataforma multi-cuenta y añade la
sincronización selectiva de las cinco entidades del encargo.

## Multi-tenancy

El `locationId` ya era por negocio, pero el token vivía en la variable de entorno
`CRM_TOKEN`, una sola para todo el proceso. Con dos negocios eso usaba el token
del primero contra la subcuenta del segundo: 401 en el mejor caso, escritura en
la subcuenta equivocada en el peor.

- `lib/crypto.ts` — AES-256-GCM para los tokens. Autenticado a propósito: una
  fila manipulada hace que el descifrado FALLE, en vez de devolver basura que
  acabaríamos mandando como credencial al CRM. La clave maestra vive en
  `CRM_MASTER_KEY`, fuera de la base.
- `crm/ctx.ts` — `CrmCtx { businessId, locationId, token }` sustituye al
  `locationId: string` suelto que viajaba por once firmas. Es un objeto y no dos
  parámetros porque dos `string` seguidos se cruzan sin que el compilador diga
  nada, y cruzarlos aquí manda el token de un cliente a la subcuenta de otro. Es
  el único sitio donde el token existe descifrado, y solo en memoria.
- `crm/client.ts` — `CrmOptions.token` pasa a ser OBLIGATORIO, sin valor por
  defecto: olvidarlo es ahora un error de compilación. El estrangulador pasa a
  ser por token y aprende la cuota de las cabeceras `x-ratelimit-*`, que declaran
  100 peticiones por 10 s — el cliente iba 6,5x por debajo con una estimación.
- Migración 003: credencial cifrada, calendario y la red de seguridad de mensajes
  POR NEGOCIO. Como variable global decidía por todas las cuentas a la vez.

Lo único de la credencial que sale del servidor es la huella de 6 caracteres.

## Consola de superadministración

`/api/admin`, solo para el rol `admin`: alta de cuentas con su dueña en una
transacción, vínculo, desvínculo y suspensión. Las credenciales se COMPRUEBAN
contra el CRM antes de guardarse — un token sin validar traslada el fallo al
primer intento de sincronizar, lejos de donde se cometió. El error distingue
«token inválido» de «subcuenta inexistente» de «token de otra subcuenta».

Pantalla en `/admin/cuentas`, verificada en navegador: el campo del token es de
contraseña y viene vacío, porque no hay valor que traer.

## Sincronización por identificador

`POST /api/crm/sync/:entidad/:id` para contacto, conversación, mensaje, cita y
servicio. La dirección la decide la entidad: las tres primeras se TRAEN porque el
CRM es su dueño; las dos últimas se EMPUJAN, porque el calendario del CRM tiene
una sola cita en dos años y su catálogo de servicios está vacío.

- `crm/conversations.ts` — lectura por id de conversaciones y mensajes sueltos.
- `crm/syncConversations.ts` — el espejo persistido. Las tablas existían desde
  002_crm.sql y nadie escribía en ellas: la bandeja consultaba el CRM en vivo.
- `crm/calendars.ts` — escritura de citas al calendario. `isoConDesplazamiento`
  escribe la hora de pared del negocio con su desplazamiento; `toISOString()`
  habría movido la hora que el CRM enseña en su interfaz.
- `crm/services.ts` — publicación de servicios al catálogo.

## Verificado contra la subcuenta real, no deducido

Las cinco entidades se ejercieron contra el CRM del cliente. Las escrituras van
en un ciclo crear → releer → borrar → confirmar borrado, con la limpieza en un
`finally`, y antes se comprobó que el borrado existe: preguntar si se puede
deshacer ANTES de escribir en el CRM de un cliente, no después. La subcuenta
quedó como estaba.

47 hallazgos medidos en `crm/HALLAZGOS.md`, y la referencia de endpoints en
`crm/API.md`, con la lista explícita de dónde la documentación oficial falla.

110 pruebas de plataforma en verde, typecheck limpio, build correcto. El backend
de demo de `server/` no se ha tocado y sigue con sus 43 pruebas.

## Deuda conocida, dicha sin rodeos

- La bandeja de mensajes todavía lee en vivo del CRM, no del espejo.
- La autenticación sigue siendo el id del usuario en texto plano, también para el
  rol admin. Esta consola crea cuentas y guarda credenciales de clientes encima
  de esa base: no debe quedar expuesta a internet hasta endurecerla.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-30 15:07:20 -06:00

14 KiB
Raw Permalink Blame History

AgendaPro — Auditoría de producto e investigación de mercado

Revisión: 2026-07-28. Sustituye la versión anterior de este archivo, que daba por faltantes cinco módulos que ya están construidos (caja, comisiones, recordatorios, booking público y política de cancelación). Cada fila de las tablas de abajo se verificó contra el esquema de server/db.ts, los endpoints montados en server/index.ts y las páginas de src/pages/ — no contra memoria ni contra el documento anterior.


1. El producto que emulamos

AgendaPro es el software de agendamiento líder en Latinoamérica: +20.000 negocios, presencia en +100 países, foco en México, Colombia, Argentina y Chile. Su promesa comercial es «el único software que ordena tu negocio y acelera su crecimiento un 82%».

Verticales: salones de belleza, spas, barberías, peluquerías, centros de estética, clínicas, psicólogos, nutricionistas, fisioterapeutas, podólogos y bienestar en general.

1.1 La escalera de planes (esto es el producto)

El modelo de negocio de AgendaPro es la escalera de planes, y cada módulo está deliberadamente asignado a un escalón. Precios de lista en USD (LatAm) y EUR (España):

Plan USD/mes EUR/mes Profesionales Correos mkt Qué añade sobre el plan anterior
Individual $9 €10 1 500 Agenda ilimitada + presencia en Marketplace, CRM, recordatorios automáticos, sitio de reservas, reportes de gestión, sistema de caja, niveles de acceso, control de ocupación, gestión de presupuesto
Básico $29 €19 hasta 20 1.000 Inventario (control + alertas de stock bajo), Comisiones (cálculo automático)
Premium ★ $59 €59 hasta 20 2.000 Encuestas de satisfacción, Fichas personalizables, Ficha clínica + consentimiento informado, Giftcards, Presupuestos, email automático de cumpleaños, sitio con URL y colores propios
Pro $199 €199 hasta 20 5.000 Acceso a API, soporte personalizado, integración Google Analytics / Meta Pixel

★ = el que ellos marcan como «más popular».

Complementos que se cobran aparte (dato relevante: lo que su marketing presenta como bandera central no viene incluido en ningún plan):

Add-on Precio Detalle
WhatsApp desde $7 USD / €5 al mes 50 mensajes mensuales
Videoconferencia desde $11 USD al mes pack de 2.500 min
Charly (asistente de marketing con IA) desde $55 USD al mes pago por resultados
Facturación electrónica «próximamente» —

Prueba gratuita: 7 días.

1.2 Módulos que anuncian, agrupados como ellos los agrupan

  • Citas: agenda online, sitio de reservas 24/7, recordatorios automáticos por WhatsApp y email, «IA de recordatorios por WhatsApp», administración de horarios.
  • CRM: base de datos de clientes, historial de visitas, control de sesiones y tratamientos, ficha del cliente, promociones personalizadas.
  • Inventario: control de inventario, alertas de inventario bajo, comisiones por venta de productos.
  • Marketing y fidelización: integración con Google Reserve en Google My Business, LinkPro (tarjeta de presentación para redes), campañas de email marketing, programas de lealtad y giftcards, acceso al marketplace de servicios.
  • Pagos: registro y reportes de pagos, pagos con terminal, pagos online y link de pago, facturación / CFDI, pago de sesiones.
  • Control del negocio: control de caja, reportes de ingresos y egresos, reportes de ventas con IA, control de múltiples sucursales, cálculo automático de comisiones.
  • Gimnasios / fitness: agenda de clases grupales, control de membresías, gestión de entrenadores.
  • Multi-sucursal: varias sedes desde una sola cuenta, con reportes consolidados.

1.3 Dónde AgendaPro es débil (según reseñas de usuarios)

Esto importa: son los huecos donde un competidor puede ganar en lugar de empatar.

  1. Fichas clínicas genéricas. No tienen CIE-10 electrónico ni plantillas por especialidad. Es la queja más concreta y sistemática.
  2. Permisos poco granulares por sede. Problema real para clínicas medianas y grandes: no se puede acotar bien qué ve cada persona en cada sucursal.
  3. Precio y alzas periódicas. Usuarios reportan subidas recurrentes y retiro de funcionalidades de planes que ya pagaban.
  4. Prueba de 7 días, contra 14+ de la competencia.
  5. WhatsApp de pago y racionado (50 mensajes/mes desde $7), siendo el canal que su propio marketing pone al frente.
  6. Curva de costo para negocios chicos: los planes intermedios superan los $40–80 USD/mes, lo que los saca de rango para un negocio de 1–3 personas.

1.4 El marco competitivo, y la parte que no se resuelve con features

Modelo Implicación
AgendaPro Suscripción por escalones + add-ons Ingreso predecible; el cliente paga antes de ver valor
Fresha $0 de mensualidad; comisión sobre clientes nuevos del marketplace + ~2,19% + $0,20 USD por transacción Sin barrera de entrada; monetiza adquisición y pagos

La conclusión honesta de la investigación: el foso de los dos líderes no es el software, es el marketplace. Fresha y AgendaPro traen clientes nuevos al negocio; eso no se replica implementando módulos. Cualquier plan de equivalencia funcional debe asumir que empata en producto y no en distribución.

1.5 Datos de industria (con su fuente, y una corrección)

  • No-shows: 10%–30% según sector; 15%–25% en belleza y estética. En clínicas de bienestar (España) 12%–19%, hasta 23% en odontología y masajes.
  • Recordatorios por WhatsApp a 3 días y 24 h antes reducen las ausencias entre 30% y 50%.
  • Depósitos recomendados: 20%–30% del valor del servicio, y el depósito debe abonarse al costo final, no ser un cargo extra.
  • Ventana de cancelación estándar: 24–48 h; 72–96 h en sectores de alta demanda.
  • Escala de penalización de ejemplo: gratis con más de 48 h; 25% entre 48 y 24 h; 50% entre 24 y 12 h; 100% el mismo día.
  • Coste ilustrativo: 5 citas perdidas por semana a 60 € ≈ 18.000 €/año de ingreso perdido.

Corrección al documento anterior: la versión previa de este archivo afirmaba «en MX la inasistencia es 15–35%» sin fuente. No encontré respaldo para el techo del 35%. Los rangos de arriba sí están sostenidos. Además, el artículo de política de cancelaciones de AgendaPro —citado antes como fuente de cifras— no contiene estadísticas de no-show: solo recomendaciones. Las cifras de arriba vienen de fuentes de industria independientes.


2. Auditoría: qué tiene hoy AgendaMax

Verificado contra esquema, endpoints y páginas.

2.1 Construido y funcionando

Capacidad de AgendaPro Estado Evidencia en el repo
Agenda / calendario ✅ CalendarPage.tsx con FullCalendar, 3 breakpoints, drag & drop; /api/appointments
Sitio de reservas público 24/7 ✅ /b/:slug → BookingPage.tsx; /api/public/:slug, /slots, /book
Guard anti doble-reserva ✅ superior runInTransaction + BEGIN IMMEDIATE + isAvailable + INSERT en la misma tx (scheduling.ts)
Auto-asignación de especialista ✅ no lo tiene AgendaPro autoAssign, pickBestSlotEmployee, scoreCandidate con especialidades y efficiency_score
Horarios por negocio y por empleado ✅ businesses.working_hours, employees.working_hours (JSON 1..7, null = hereda)
CRM / ficha e historial de cliente ✅ clients + ClientDetailPage.tsx con no_show_count
Comisiones ✅ services.commission_pct, employees.commission_pct, snapshot en tickets.commission; /api/dashboard/commissions, /api/me/commissions, MyPerformancePage.tsx
Control de caja / cierre diario ✅ cash_sessions (apertura, cierre, expected_amount → descuadre) + cash_entries (income/expense); /api/cash/*; CashPage.tsx
Reportes de gestión ✅ 8 endpoints en /api/dashboard/* + DashboardPage.tsx con recharts
Reseñas / ratings ✅ tabla reviews (AgendaPro no lo vende como módulo)
Multi-tenant + consola de plataforma ✅ superior /api/admin/*, plantillas por vertical, alta de negocio, reset-demo, cascade
Sitio de reservas con marca propia ✅ landing + booking con paleta heredada del panel (AgendaPro lo cobra en Premium)
App instalable ✅ PWA con service worker y prompt de instalación (equivalente funcional a su app nativa)
Aislamiento por tenant verificado ✅ test:e2e y test:admin comprueban 403 y no-visibilidad cruzada

2.2 Construido a medias — el hueco entre «configurable» y «operante»

Estas tres son las más engañosas de la auditoría: existen en el esquema y en la UI, pero no cierran el ciclo. Un demo puede mostrarlas y no hacen nada.

Capacidad Qué hay Qué falta
Política de cancelación y depósito businesses.cancel_window_hours, cancel_penalty_pct, require_deposit, deposit_pct; GET /api/appointments/:id/cancellation-policy; editor en SettingsPage.tsx Nunca se cobra nada. No hay captura de depósito en el booking, ni aplicación de la penalización a un ticket, ni registro del cargo. La política se configura y se consulta; no tiene efecto económico.
Recordatorios automáticos tabla notifications (canales whatsapp/sms/email, tipos confirmation/reminder/cancellation/follow_up/review), /api/notifications con regenerate/send/cancel/stats, NotificationsPage.tsx Es una bandeja simulada: send marca sent sin salir a ningún proveedor. Aceptable para demo, pero no equivale al módulo real.
Niveles de acceso y permisos 3 roles fijos (admin/owner/employee) con autorización real en middlewares y aislamiento probado Sin permisos granulares. Nota: AgendaPro también es débil aquí (§1.3), así que es una oportunidad, no solo una deuda.

2.3 Brechas reales — lo que no existe

Ordenado por el escalón de plan al que pertenece en AgendaPro, porque eso define qué se puede reclamar como «equivalente al plan X».

# Brecha Plan AgendaPro Notas de implementación
1 Inventario de productos + alertas de stock bajo Básico No hay tabla de productos ni movimientos de stock
2 Venta multi-ítem (POS real) Básico/Individual Bloqueo estructural: hoy tickets es 1 ticket = 1 cita = 1 servicio (service_id único). No se puede vender «corte + shampoo + giftcard» en una venta
3 Comisión por venta de productos Básico Depende de 1 y 2
4 Encuestas de satisfacción / NPS Premium reviews cubre la reseña puntual, no la campaña de medición
5 Fichas personalizables + ficha clínica + consentimiento informado Premium Hoy solo clients.notes, texto libre. Aquí AgendaPro es débil (§1.3)
6 Giftcards Premium Depende de 2
7 Presupuestos Premium Depende de 2
8 Paquetes, sesiones y membresías transversal «Control de sesiones y tratamientos», «pago de sesiones», membresías de gimnasio. Nada de saldo prepago
9 Clases grupales (capacidad > 1) fitness appointments es estrictamente 1:1. Toca la invariante de agendado
10 Multi-sucursal con reportes consolidados transversal Tenemos multi-tenant, no multi-branch. Cambio de esquema profundo
11 Email marketing / campañas / cumpleaños Individual+ (con cuotas por plan) notifications es transaccional, no de campañas
12 Pagos en línea / link de pago / cobro anticipado transversal Cero captura de pago. Es lo que bloquea §2.2
13 Facturación electrónica / CFDI add-on En AgendaPro está «próximamente»
14 Google Reserve / Google Calendar Individual+ Integración externa
15 Control de ocupación (% de agenda ocupada) Individual metrics.ts solo tiene cancelRate, noShowRate, completionRate. Barato y visible
16 Gating por plan — businesses.plan existe pero no restringe nada. Sin esto, la escalera de planes —que es el producto de AgendaPro— no se está emulando
17 Videoconferencia add-on
18 API pública documentada Pro
19 Marketplace Individual+ El foso real (§1.4). No es un módulo, es un canal de distribución
20 Reportes con IA add-on (Charly)

3. Lectura de la auditoría

Tres conclusiones que condicionan cualquier plan:

  1. La brecha no es de agenda, es de dinero. Todo lo que falta cuelga de dos cosas que no existen: la venta multi-ítem (brecha 2) y la captura de pago (brecha 12). Inventario, giftcards, presupuestos, paquetes, comisión de producto y el cierre de la política de cancelación dependen de una o de las dos. Atacar módulos sueltos antes de eso produce features que no se pueden conectar.

  2. Ya somos mejores en el núcleo de agendado. Auto-asignación por especialidad y eficiencia, guard transaccional anti doble-reserva y consola de plataforma multi-tenant no están en la oferta de AgendaPro. La equivalencia que falta es comercial y administrativa, no de calendario.

  3. La escalera de planes no se está emulando. Es lo más desalineado del proyecto respecto al producto real: businesses.plan es decorativo. Es además de las cosas más baratas de arreglar y la que más hace que el demo se lea como un SaaS y no como una app.

El backlog priorizado y la descomposición en sub-proyectos viven en el spec de diseño de esta tanda, no en este archivo. Este documento es la línea base de hechos.