AgendaPro v1.0 - multi-tenant SaaS, mobile calendar, public booking

Multi-tenant scheduling SaaS (AgendaPro-equivalent):
- Backend: Node + Express + node:sqlite, multi-tenant (admin/owner/employee),
  versioned migrations, 4 templates (estetica-spa, barberia, clinica, blank).
- Frontend: React 18 + TS + Vite + Tailwind, FullCalendar drag-and-drop,
  Recharts dashboard, mobile-first (day/list views on mobile).
- Features: calendar+services+employees+clients+tickets, dashboard with
  best employee/service, top tickets, top/frequent clients, commissions,
  cancellation policy + no-show tracking, public online booking (/b/:slug),
  cash register (cierre de caja), reminders/notifications center.
- Verification: 65/65 e2e API, 58/58 visual (0 overflow, 0 console errors),
  typecheck clean, vite build OK.
This commit is contained in:
AgendaPro Dev
2026-07-25 13:45:53 -06:00
commit e8d2435cc2
63 changed files with 16539 additions and 0 deletions
+164
View File
@@ -0,0 +1,164 @@
# AgendaPro
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
```bash
npm install
```
La base de datos se **siembra automáticamente** con datos demo la primera vez que arranca el servidor.
Para regenerarla desde cero:
```bash
# 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
```bash
npm run dev
```
Abre http://localhost:5173 (el frontend proxya `/api` al backend en el puerto 3000).
## Producción
```bash
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
```
## Tests y auditoría visual
```bash
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 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/
```
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`**.
| Rol | Email | Nombre |
|----------|----------------------------------|------------------|
| **Admin**| `[email protected]` | Administrador |
| Dueño | `[email protected]` | Daniela Reyes |
| Empleado | `[email protected]` | Valentina Cruz |
| Empleado | `[email protected]` | Mateo Herrera |
| Empleado | `[email protected]` | Sofía Ramírez |
| Empleado | `[email protected]` | Diego Castillo |
| Empleado | `[email protected]` | Isabela Torres |
| Empleado | `[email protected]` | 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
AgendaPro 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.