- Matriz de roles (vendedor, administracion_venta, director_ventas, escrituracion, direccion_general, admin) con modulos visibles por rol; auth/me y login incluyen 'modulos'; PATCH /usuarios/:id/rol (admin). - Landing: Cobranza -> Clientes, Chat IA -> Chat Hermes, nuevo modulo Contactos (vista interna leyendo el tablero Contactos), grid filtrado por rol, rol visible en Configuracion de cuenta. - Dashboards: tab 'Tablero comercial' y tabs filtrados por rol. - Boton '<- Menu' en el header de todas las apps. - Mi dia: cada lead muestra el ultimo cambio (que, quien, cuando) desde el activity log de Monday (normalizacion de created_at 100ns/us/ms). - Descarte: el motivo se crea en el grupo de su categoria en el tablero Motivos No Compra.
169 lines
6.2 KiB
TypeScript
169 lines
6.2 KiB
TypeScript
import { Router } from 'express'
|
|
import { health } from '../controllers/health.controller.js'
|
|
import { listarUnidades, obtenerUnidad } from '../controllers/unidades.controller.js'
|
|
import {
|
|
alertasInventarioEndpoint,
|
|
crearCotizacion,
|
|
listarCotizaciones,
|
|
listarMisCotizaciones,
|
|
obtenerCotizacion,
|
|
obtenerCotizacionPublica,
|
|
} from '../controllers/cotizaciones.controller.js'
|
|
import {
|
|
actualizarProgreso,
|
|
completarProgreso,
|
|
crearCliente,
|
|
iniciarProgreso,
|
|
listarDocumentos,
|
|
obtenerCliente,
|
|
subirDocumentos,
|
|
uploadDocumentos,
|
|
} from '../controllers/clientes.controller.js'
|
|
import {
|
|
eliminarBorrador,
|
|
guardarBorrador,
|
|
listarBorradores,
|
|
obtenerBorrador,
|
|
} from '../controllers/borradores.controller.js'
|
|
import {
|
|
firmarRemoto,
|
|
generarLiga,
|
|
limitadorLiga,
|
|
obtenerClientePublico,
|
|
subirDocumentosPublico,
|
|
uploadDocumentosPublico,
|
|
} from '../controllers/liga.controller.js'
|
|
import {
|
|
agregarNota,
|
|
cancelarPlan,
|
|
cobranzaHoy,
|
|
crearPlan,
|
|
ligarMondayItem,
|
|
listarPlanes,
|
|
obtenerPlan,
|
|
registrarAbonoEndpoint,
|
|
} from '../controllers/planes.controller.js'
|
|
import { perderOportunidadEndpoint } from '../controllers/oportunidades.controller.js'
|
|
import { correrRecordatorios, listarRecordatorios } from '../controllers/recordatorios.controller.js'
|
|
import {
|
|
cambiarEstadoLeadEndpoint,
|
|
crearAfluenciaEndpoint,
|
|
crearLeadEndpoint,
|
|
buscarLeadsEndpoint,
|
|
descartarLeadEndpoint,
|
|
} from '../controllers/leads.controller.js'
|
|
import {
|
|
actualizarRolEndpoint,
|
|
actualizarVinculoMondayEndpoint,
|
|
listarUsuariosMondayEndpoint,
|
|
} from '../controllers/usuarios.controller.js'
|
|
import { resumenMiDiaEndpoint } from '../controllers/mi-dia.controller.js'
|
|
import { listarContactosEndpoint } from '../controllers/contactos.controller.js'
|
|
import { webhookMonday } from '../controllers/webhooks.controller.js'
|
|
import {
|
|
correrRoundRobin,
|
|
estadoAutomatizaciones,
|
|
previewInactividad,
|
|
} from '../controllers/automatizaciones.controller.js'
|
|
import {
|
|
chatIA,
|
|
eliminarDocumento,
|
|
listarConversaciones,
|
|
listarDocumentosIA,
|
|
obtenerConversacion,
|
|
subirDocumento,
|
|
} from '../controllers/ai.controller.js'
|
|
import { loginEndpoint, meEndpoint, cambiarPasswordEndpoint } from '../controllers/auth.controller.js'
|
|
import { resumenReportes } from '../controllers/reportes.controller.js'
|
|
|
|
export const apiRouter = Router()
|
|
|
|
apiRouter.get('/health', health)
|
|
|
|
apiRouter.post('/auth/login', loginEndpoint)
|
|
apiRouter.get('/auth/me', meEndpoint)
|
|
apiRouter.post('/auth/cambiar-password', cambiarPasswordEndpoint)
|
|
|
|
apiRouter.get('/unidades', listarUnidades)
|
|
apiRouter.get('/unidades/:codigo', obtenerUnidad)
|
|
|
|
apiRouter.post('/cotizaciones', crearCotizacion)
|
|
apiRouter.get('/cotizaciones', listarCotizaciones)
|
|
apiRouter.get('/cotizaciones/mias', listarMisCotizaciones)
|
|
apiRouter.post('/cotizaciones/alertas-inventario', alertasInventarioEndpoint)
|
|
// Público (sin auth): destino del QR del PDF; ver RUTAS_PUBLICAS/PATRONES_PUBLICOS
|
|
apiRouter.get('/cotizaciones/:id/publico', obtenerCotizacionPublica)
|
|
apiRouter.get('/cotizaciones/:id', obtenerCotizacion)
|
|
|
|
apiRouter.post('/clientes', crearCliente)
|
|
// Alta progresiva: guardado etapa por etapa del wizard (Contacto PROSPECTO → CLIENTE).
|
|
// Van ANTES de /clientes/:id para no colisionar con el parámetro.
|
|
apiRouter.post('/clientes/progreso/iniciar', iniciarProgreso)
|
|
apiRouter.patch('/clientes/progreso/:id', actualizarProgreso)
|
|
apiRouter.post('/clientes/progreso/:id/completar', completarProgreso)
|
|
// Liga remota: endpoints públicos con token propio (scope 'firma-remota'); el
|
|
// scope se verifica dentro de cada controlador. Van ANTES de /clientes/:id.
|
|
apiRouter.get('/clientes/publico/:token', limitadorLiga, obtenerClientePublico)
|
|
apiRouter.post('/clientes/publico/:token/firma', limitadorLiga, firmarRemoto)
|
|
apiRouter.post(
|
|
'/clientes/publico/:token/documentos',
|
|
limitadorLiga,
|
|
uploadDocumentosPublico.array('archivos', 10),
|
|
subirDocumentosPublico,
|
|
)
|
|
apiRouter.post('/clientes/:id/liga', generarLiga)
|
|
apiRouter.get('/clientes/:id', obtenerCliente)
|
|
apiRouter.post('/clientes/:id/documentos', uploadDocumentos.array('archivos', 10), subirDocumentos)
|
|
apiRouter.get('/clientes/:id/documentos', listarDocumentos)
|
|
|
|
apiRouter.get('/borradores', listarBorradores)
|
|
apiRouter.post('/borradores', guardarBorrador)
|
|
apiRouter.get('/borradores/:id', obtenerBorrador)
|
|
apiRouter.delete('/borradores/:id', eliminarBorrador)
|
|
|
|
apiRouter.post('/planes', crearPlan)
|
|
apiRouter.get('/planes', listarPlanes)
|
|
apiRouter.get('/planes/cobranza-del-dia', cobranzaHoy)
|
|
apiRouter.get('/planes/:id', obtenerPlan)
|
|
apiRouter.post('/planes/:id/abonos', registrarAbonoEndpoint)
|
|
apiRouter.post('/planes/:id/notas', agregarNota)
|
|
apiRouter.post('/planes/:id/cancelar', cancelarPlan)
|
|
apiRouter.patch('/planes/:id/monday', ligarMondayItem)
|
|
|
|
apiRouter.get('/cobranza/recordatorios', listarRecordatorios)
|
|
apiRouter.post('/cobranza/recordatorios/run', correrRecordatorios)
|
|
|
|
apiRouter.post('/oportunidades/:mondayItemId/perder', perderOportunidadEndpoint)
|
|
|
|
apiRouter.get('/mi-dia/resumen', resumenMiDiaEndpoint)
|
|
|
|
apiRouter.get('/contactos', listarContactosEndpoint)
|
|
|
|
// GET estático: va ANTES de /leads/:itemId para no colisionar con el parámetro
|
|
apiRouter.get('/leads/buscar', buscarLeadsEndpoint)
|
|
apiRouter.post('/leads', crearLeadEndpoint)
|
|
apiRouter.post('/leads/:itemId/estado', cambiarEstadoLeadEndpoint)
|
|
apiRouter.post('/leads/:itemId/descartar', descartarLeadEndpoint)
|
|
|
|
// Alta Afluencia (forma completa de /client): vive en el tablero Oportunidades
|
|
apiRouter.post('/afluencias', crearAfluenciaEndpoint)
|
|
|
|
apiRouter.get('/monday/usuarios', listarUsuariosMondayEndpoint)
|
|
apiRouter.patch('/usuarios/me/monday', actualizarVinculoMondayEndpoint)
|
|
apiRouter.patch('/usuarios/:id/rol', actualizarRolEndpoint)
|
|
|
|
apiRouter.get('/reportes/resumen', resumenReportes)
|
|
|
|
apiRouter.post('/webhooks/monday', webhookMonday)
|
|
|
|
apiRouter.get('/automatizaciones/estado', estadoAutomatizaciones)
|
|
apiRouter.post('/automatizaciones/round-robin/run', correrRoundRobin)
|
|
apiRouter.get('/automatizaciones/inactividad/preview', previewInactividad)
|
|
|
|
apiRouter.post('/ai/chat', chatIA)
|
|
apiRouter.get('/ai/conversations', listarConversaciones)
|
|
apiRouter.get('/ai/conversations/:id', obtenerConversacion)
|
|
apiRouter.post('/ai/documents', subirDocumento)
|
|
apiRouter.get('/ai/documents', listarDocumentosIA)
|
|
apiRouter.delete('/ai/documents/:id', eliminarDocumento)
|