AgendaPro DevandClaude Opus 5 0069d23744 docs: record the production verification of both fixes
Adds the production evidence for commit 4281567 (`test:pwa` passing against the HTTPS
domain, the install button present with the chunk delayed, the chart running as a
CSSAnimation, smoke 16/16) and what this deploy taught about the setup:

- Auto-deploy webhooks are active on BOTH remotes, so pushing to gitea and github in
  sequence queues two concurrent deploys of the same commit.
- `force=true` is never needed after a push; it stops the container before building and
  adds avoidable downtime.
- Measured 241s of unavailability for this deploy — explicitly not attributed to cold
  start, since a second deploy was building concurrently.
- This Coolify instance only answers on collection endpoints; everything per-resource
  404s, so container env vars and logs are not readable over the API.

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

AgendaMax

Aplicación web multi-tenant (SaaS) para la gestión de negocios de servicios (estética, spa, barbería, clínicas, etc.): calendario de citas con arrastrar y soltar, gestión de empleados, servicios, clientes y tickets, y un tablero con ingresos, mejores empleados, servicios más rentables y clientes top.

Tres roles: Administrador de plataforma (crea y gestiona todos los negocios desde la consola admin), Dueño (ve su negocio y el tablero) y Empleado (agenda citas que se auto-asignan a él).

Stack

  • Frontend: React 18 + TypeScript + Vite + Tailwind CSS
  • Calendario: FullCalendar (drag & drop, resize, day/time grid)
  • Gráficas: Recharts
  • Backend: Node.js + Express
  • Base de datos: SQLite (vía node:sqlite, nativo de Node — sin compilación nativa)

Requisitos

  • Node.js 22.5+ (recomendado 24+). Este proyecto usa el módulo nativo node:sqlite.

Instalación

npm install

La base de datos se siembra automáticamente con datos demo la primera vez que arranca el servidor. Para regenerarla desde cero:

# Borra la DB y vuelve a sembrar
npm run seed
# o, forzando reset desde el servidor:
$env:RESET_DB="1"; npm run dev:server   # PowerShell
RESET_DB=1 npm run dev:server           # bash

Desarrollo

npm run dev

Abre http://localhost:5173 (el frontend proxya /api al backend en el puerto 3000).

Ruta Qué es
/ Landing pública. Con sesión abierta redirige al panel según el rol.
/login Acceso. En fase demo ofrece entrar de un clic con las cuentas de abajo.
/b/:slug Reserva pública del negocio, sin sesión.

Producción

npm run build     # compila TS y empaqueta el frontend en dist/
npm start         # sirve la API y el frontend estático en http://localhost:3000

El acceso de un clic y el selector «Ver como…» del panel viven detrás de la constante de build DEMO, que en un build de producción solo se enciende con VITE_DEMO_UI=1. El Dockerfile la declara con ese valor por defecto porque el despliegue es la demostración; pasar --build-arg VITE_DEMO_UI=0 los elimina del bundle.

Instalar AgendaMax como app

  • Android/Chrome: abre la URL HTTPS y selecciona la acción de instalación mostrada por AgendaMax o por la barra de direcciones del navegador.
  • iPhone/iPad Safari: usa Compartir -> Añadir a pantalla de inicio; iOS no expone el aviso de instalación dentro de la página de Android.
  • La app instalada puede abrirse sin la interfaz del navegador, pero los datos del negocio siguen requiriendo conexión a internet.
  • Validación local: ejecuta npm.cmd run build, inicia producción con npm.cmd start y después ejecuta npm.cmd run test:pwa.
  • La validación de producción requiere el dominio HTTPS de Coolify, no una dirección IP HTTP.

npm.cmd run test:pwa usa estas variables opcionales para los flujos autenticados; si no se definen, usa las cuentas demo locales:

[email protected]
[email protected]
PWA_PASSWORD=demo1234

Tests y auditoría visual

npm run test:e2e         # 22 pruebas end-to-end de la API (login, CRUD, dashboard, auto-asignación, roles, multi-tenant)
npm run test:admin       # 17 pruebas del admin (crear negocio + plantilla, aislamiento, reset-demo, delete cascade)
npm run test:landing     # WebKit: ruteo landing/login, acceso de un clic y prefers-reduced-motion
npm run audit:visual     # Playwright: navega 10 páginas × 4 viewports (móvil/tablet/desktop/wide),
                         # mide overflow horizontal, captura errores de consola y guarda capturas en screenshots/
npm run audit:responsive # WebKit: iPhone/iPad reales — auto-zoom, safe areas, objetivos táctiles y canaletas

La auditoría visual verifica responsividad en 375 / 768 / 1280 / 1536 px, detecta overflow, errores de consola y confirma que el calendario, el modal de cita y el cambio de sesión funcionan en cada tamaño.

Cuentas demo

Todas usan la contraseña demo1234. En /login se puede entrar con un clic, sin escribirlas.

Rol Email Contraseña Nombre
Admin [email protected] demo1234 Administrador
Dueño [email protected] demo1234 Daniela Reyes
Empleado [email protected] demo1234 Valentina Cruz
Empleado [email protected] demo1234 Mateo Herrera
Empleado sofía.ramí[email protected] demo1234 Sofía Ramírez
Empleado [email protected] demo1234 Diego Castillo
Empleado [email protected] demo1234 Isabela Torres
Empleado carolina.mé[email protected] demo1234 Carolina Méndez

En la pantalla de login aparecen botones de acceso rápido a las cuentas demo, y desde la barra lateral puedes cambiar de cuenta con “Ver como…”.

Multi-tenant y consola de administrador

AgendaMax es multi-tenant: cada negocio es un tenant aislado (todos los datos llevan business_id y las consultas se filtran por el negocio del usuario). El administrador de plataforma gestiona todos los negocios desde /admin:

  • Resumen: KPIs globales (negocios activos, usuarios, ingresos y citas de toda la plataforma).
  • Negocios: lista buscable con stats por negocio (usuarios, citas, ingresos).
  • Crear negocio (2 pasos): eliges una plantilla → se cargan empleados, servicios y clientes demo con historial de citas/tickets listos para usar; defines los datos del negocio y la cuenta del dueño.
  • Detalle de negocio: editar nombre/industria, cambiar plan (Prueba/Pro/Free) y estado (Activo/Suspendido), recargar datos demo con otra plantilla (preserva las cuentas de usuario) o eliminar el negocio por completo (con cascade de todos sus datos).

Plantillas disponibles: estetica-spa (Lumière), barberia (Urban Cut), clinica (Dental Sonrisa) y blank (vacío, para configurar desde cero). Defínelas en server/lib/templates.ts.

El aislamiento entre tenants se valida: un dueño solo ve los datos de su negocio, y los empleados no pueden acceder al tablero ni a la gestión (403).

Funcionalidades

Calendario (Dueño y Empleado)

  • Vistas de mes / semana / día, con indicador de hora actual.
  • En móvil se abre por defecto en vista Día y se ofrece una vista Lista (agenda) — la vista Semana/Mes queda reservada para tablet/desktop para evitar columnas aplastadas.
  • Arrastra para reagendar y redimensiona para cambiar duración.
  • Clic en un hueco o en Nueva cita para abrir el formulario.
  • Clic en una cita para editarla: cambiar servicio, especialista, cliente, hora, precio, notas.
  • Marcar como completada (genera un ticket con propina y método de pago).
  • Cancelar o eliminar citas.
  • Filtra por empleado y por estado (programada / completada / cancelada).

Formulario de cita

  • Servicio desplegable (menú del negocio), con precio y duración.
  • Especialista: el empleado lo tiene auto-asignado por defecto (filtrado a quienes ofrecen el servicio).
  • Cliente: buscar existente o crear uno nuevo al vuelo.
  • Duración, precio y notas editables.

Tablero (Dueño)

  • KPIs: ingresos del período, citas programadas, ticket promedio, ocupación y % de cancelación.
  • Gráfica de ingresos diarios y distribución por categoría.
  • Mejores empleados por ingreso, con rating y utilización.
  • Servicios más rentables.
  • Tickets más altos recientes.
  • Top clientes (por gasto) y clientes frecuentes (por visitas).
  • Rango de tiempo ajustable (7 / 30 / 60 días).

Gestión (Dueño)

  • Empleados: crear, editar, asignar servicios, ver ingresos/citas/rating.
  • Servicios: catálogo agrupado por categoría, con especialistas asignados.
  • Tickets: historial de ventas con filtros por método de pago.

Clientes (Dueño y Empleado)

  • Buscador por nombre / teléfono / correo.
  • Ficha del cliente con historial de citas, gasto total y visitas.

Estructura

.
├── server/            # API Express + SQLite
│   ├── db.ts          # esquema multi-tenant + sistema de migraciones versionado
│   ├── index.ts       # app Express (auto-siembla admin + negocio demo en primer arranque)
│   ├── lib/auth.ts    # middlewares: authRequired, ownerOnly, adminOnly
│   ├── lib/templates.ts  # plantillas: estetica-spa, barberia, clinica, blank
│   ├── routes/        # auth, business, employees, services, clients, appointments, dashboard, admin
│   └── scripts/seed.ts# seedBusiness(businessId, template) reutilizable + script standalone
├── shared/types.ts    # tipos TS compartidos cliente/servidor
├── src/               # frontend React
│   ├── components/    # AppShell, AdminShell, Modal, AppointmentModal, ui, DemoSwitcher, admin/CreateBusinessModal
│   ├── lib/           # api, auth, format
│   └── pages/         # Login, Dashboard, Calendar, Employees, Services, Clients, Tickets + admin/*
└── data/              # SQLite (generado, .gitignored)

Notas de seguridad

Es una demo. La autenticación usa un token trivial (el id del usuario) sin hashing de contraseña ni sesiones reales — no usar en producción tal cual. Antes de un despliegue real habría que añadir hashing (bcrypt), JWT firmados, validación estricta con zod, rate-limiting y HTTPS.

S
Description
No description provided
Readme
614 KiB
Languages
TypeScript 80.8%
JavaScript 15.4%
CSS 3.4%
HTML 0.2%
Dockerfile 0.2%