feat(cotizador): historial, compartir WhatsApp, folio+QR, comparador de unidades, alertas de inventario
- Mis cotizaciones (guardar con cliente, retomar, nueva) asociadas al vendedor del token - Compartir: resumen copiable + deep link wa.me; PDF con folio, vigencia y QR - GET /api/cotizaciones/:id/publico (público, datos mínimos sin PII del cliente) - Comparador lado a lado de 2 unidades (mismo o distinto desarrollo) - POST /api/cotizaciones/alertas-inventario: avisa al vendedor si una unidad cotizada cambia de estatus (dedup; wire con syncs documentado) - Fix: labels de propuesta mapeados a los reales del board Oportunidades - Tests: api 201, cotizador 82
This commit is contained in:
@@ -12,6 +12,13 @@ const RUTAS_PUBLICAS: ReadonlyArray<{ metodo: string; ruta: string }> = [
|
||||
{ metodo: 'POST', ruta: '/webhooks/monday' },
|
||||
]
|
||||
|
||||
// Rutas públicas con parámetros (se comparan contra req.path relativo a /api).
|
||||
// El endpoint público de cotización es el destino del QR del PDF: el cliente
|
||||
// final lo abre sin sesión; devuelve solo datos comerciales, nunca del cliente.
|
||||
const PATRONES_PUBLICOS: ReadonlyArray<{ metodo: string; patron: RegExp }> = [
|
||||
{ metodo: 'GET', patron: /^\/cotizaciones\/[^/]+\/publico$/ },
|
||||
]
|
||||
|
||||
declare module 'express-serve-static-core' {
|
||||
interface Request {
|
||||
usuarioToken?: TokenPayload
|
||||
@@ -28,7 +35,9 @@ export function authMiddleware(req: Request, res: Response, next: NextFunction):
|
||||
return
|
||||
}
|
||||
|
||||
const publica = RUTAS_PUBLICAS.some((r) => r.metodo === req.method && req.path === r.ruta)
|
||||
const publica =
|
||||
RUTAS_PUBLICAS.some((r) => r.metodo === req.method && req.path === r.ruta) ||
|
||||
PATRONES_PUBLICOS.some((r) => r.metodo === req.method && r.patron.test(req.path))
|
||||
if (publica) {
|
||||
next()
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user