Files
FRASA-CAS/api-gateway/src/routes/index.ts
Consult AS Technology 59944668a8 feat(alta): borrador, pre-llenado desde cotización y liga remota de firma
- Borradores por vendedor (guardar/continuar/eliminar), se limpia al registrar
- Pre-llenado con ?cotizacion=<id> (cliente, contacto, proyecto, montos);
  botón 'Iniciar alta' en Mis cotizaciones del cotizador
- Liga remota pública /client/firma/<token> (JWT scope firma-remota, 72h,
  rate limit, solo datos mínimos sin PLD): firma digital + subida de
  documentos que prende checkboxes en Monday Apartado
- Tokens de liga no sirven como sesión y viceversa
- Tests: api 228, alta 82, cotizador 82
2026-08-28 07:29:22 +00:00

137 lines
4.7 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 {
crearCliente,
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 {
cambiarEstadoLeadEndpoint,
crearLeadEndpoint,
descartarLeadEndpoint,
} from '../controllers/leads.controller.js'
import { resumenMiDiaEndpoint } from '../controllers/mi-dia.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 } 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.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)
// 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.post('/oportunidades/:mondayItemId/perder', perderOportunidadEndpoint)
apiRouter.get('/mi-dia/resumen', resumenMiDiaEndpoint)
apiRouter.post('/leads', crearLeadEndpoint)
apiRouter.post('/leads/:itemId/estado', cambiarEstadoLeadEndpoint)
apiRouter.post('/leads/:itemId/descartar', descartarLeadEndpoint)
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)