Backend: API y seguridad
Alcance
Este documento describe el estado funcional actual de la API y su modelo de acceso.
Convenciones generales
- no existe prefijo global como
/apio/v1 - la paginacion tipica usa
pageypageSize - el maximo usual de
pageSizees100
Headers importantes
| Header | Para que sirve |
|---|---|
Authorization | Lleva el Firebase ID token de la sesion |
businessId | Define el tenant activo en rutas privadas de negocio |
x-internal-task-token | Protege endpoints internos de automatizacion |
Autenticacion
La API usa Firebase Admin para validar Authorization: Bearer <token>.
Cuando el token es valido:
- se resuelve la identidad del usuario
- se inyecta contexto de autenticacion en la request
GET /auth/me es hoy el endpoint de hidratacion de sesion. Devuelve el usuario interno, membresias de negocio, acceso global y cache de permisos por rol para que el frontend pueda refrescar su estado sin reconstruirlo desde varias llamadas separadas.
Aunque /auth esta como prefijo publico para el middleware, /auth/me requiere un Firebase ID token valido porque el controlador exige el claim document.
Modelo actual de acceso
Roles
BUSINESSCROSS_BUSINESSGLOBAL
Permisos y modulos
BUSINESSGLOBALHYBRID
Membresias
- membresia de negocio:
BusinessMembershipconbusinessId - membresia global:
BusinessMembershipsinbusinessId
Validacion de businessId
En rutas privadas de negocio que no esten exentas, el backend exige businessId.
No se valida solo la presencia del header. Tambien se valida:
- existencia del negocio
- existencia del plan
- suscripcion activa
- plan activo
Cuando esta validacion falla en endpoints privados de negocio, la API hoy intenta responder mensajes mas descriptivos en español segun el caso, por ejemplo plan vencido, plan inactivo o limite alcanzado.
Las rutas globales autenticadas no usan businessId; se autorizan con la membresia global y los permisos correspondientes.
Rate limiting
El sistema incluye un rate limit en memoria con estas caracteristicas documentadas:
- ventana de 1 segundo
- maximo de 10 requests por segundo
- clave basada en origen, metodo y path
Modulos API expuestos
| Base path | Operaciones tipicas |
|---|---|
/health | healthcheck liviano sin autenticacion |
/auth | login, registro e hidratacion de sesion |
/business | CRUD de negocio y reconciliacion de usage |
/branches | CRUD de sedes |
/services | CRUD de servicios |
/modules | catalogo funcional |
/permissions | permisos base |
/roles | roles del sistema |
/business-memberships | membresias, rol, sede, borrado logico y reactivacion admin |
/users | consulta y actualizacion de usuarios |
/appointments | agenda operativa |
/bookings | reserva comercial, gestion publica y pagos |
/reviews | reseñas |
/metrics | metricas agregadas |
/plans | planes de la plataforma |
/push-notifications | registro y baja de dispositivos |
/whatsapp | mensajeria interna automatizada |
/outbox | inspeccion y proceso interno de eventos diferidos |
Estado actual de acceso
Rutas publicas relevantes
Segun la configuracion actual, existen prefijos o endpoints publicos para casos funcionales puntuales, por ejemplo:
/auth/health/branches/services/appointmentsGET /businessGET /business-memberships/publicGET /users/public-lookupGET /bookings*POST /bookingsPUT /bookings/public-manage*GET /reviewsPOST /reviewsGET /plansGET /outbox*POST /outbox*
La gestion publica de bookings ya no abre todo PUT /bookings/:id. El flujo permitido publicamente queda acotado a un endpoint dedicado para editar o cancelar citas existentes y para cancelar el booking completo.
Nota: las rutas de outbox estan exentas de Firebase Auth, pero no son abiertas funcionalmente. El controlador exige x-internal-task-token para listar, procesar o reencolar eventos.
Rutas privadas sin businessId
Varias operaciones privadas quedan exentas del header businessId porque pertenecen al contexto global o al arranque de acceso. Ejemplos:
- mutaciones de negocios
- mutaciones de planes
- CRUD global de roles, permisos y modulos
- consultas globales de usuarios
- operaciones globales sobre membresias
- alta de ciertas memberships por documento
- consulta de negocios restaurables para superadmin global
- reactivacion de membresia admin por superadmin global
- suscripciones push
Reglas de autorizacion
- las rutas globales exigen membresia global activa y permisos globales
- las rutas de negocio exigen membresia del negocio correspondiente
- una membresia global no sustituye la necesidad de membresia de negocio
- mutaciones sensibles de membresias validan el negocio objetivo y el permiso correspondiente
- borrar una membresia es borrado logico con
status = DELETED; tambien limpia su link en la subcoleccion del usuario y, si aplica, efectos de empleado - un superadmin global puede consultar negocios donde su propia membresia admin sea restaurable y reactivarla como admin del negocio
Endpoints internos
Estos flujos documentados dependen de x-internal-task-token:
POST /whatsapp/send-message/:typePOST /business/usage/reconcile-todayGET /outbox*POST /outbox*
Su proteccion real depende de ese token interno.
Endpoints de booking relevantes
El modulo de bookings separa varios contratos:
POST /bookings: crea booking y citasPUT /bookings/public-manage/:id: gestion publica acotada del bookingPOST /bookings/:id/payments: agrega un abono incrementalPUT /bookings/:id/payment-method: cambia metodo de pagoPUT /bookings/:id/paid-amount: sobrescribe el total pagado declaradoPUT /bookings/:id: actualizacion privada completa segun permisosDELETE /bookings/:id: eliminacion logica privada
Riesgos y observaciones
- no existe especificacion formal OpenAPI
- el rate limit es en memoria y no se comparte entre replicas
- seguridad de tareas internas depende de configurar bien el token interno
- cambios en rutas publicas o exenciones de
businessIddeben revisarse con criterio de seguridad - permitir nombres repetidos de negocio no elimina la necesidad de mantener
slugunico como identificador publico