feat(clientes-maestro): importar y exportar clientes del archivo maestro

- Tabla ClienteMaestro (27 campos, unique numCliente)
- Importador Excel: 1535 clientes del Reporte maestro
- API: listar/filtros/exportar/detalle/importar
- Frontend: tabla paginada, filtros, exportar Excel
- Dark mode completo, 52 tests verdes
This commit is contained in:
2026-09-07 09:11:09 +00:00
parent c2a8f4e929
commit 9021733455
18 changed files with 1428 additions and 10 deletions

View File

@@ -0,0 +1,54 @@
import type { Request, Response } from 'express'
import * as clienteMaestroService from '../services/cliente-maestro.service.js'
import { NotFoundError, BadRequestError } from '../utils/errors.js'
import { requireAdmin } from './config.controller.js'
// ── GET /api/clientes-maestro ────────────────────────────────────────
export async function listarEndpoint(req: Request, res: Response): Promise<void> {
const busqueda = (req.query.busqueda as string) ?? undefined
const desarrollo = (req.query.desarrollo as string) ?? undefined
const estatus = (req.query.estatus as string) ?? undefined
const pagina = req.query.pagina ? Number(req.query.pagina) : undefined
const limite = req.query.limite ? Number(req.query.limite) : undefined
const resultado = await clienteMaestroService.listar({ busqueda, desarrollo, estatus, pagina, limite })
res.json(resultado)
}
// ── GET /api/clientes-maestro/exportar ───────────────────────────────
export async function exportarEndpoint(req: Request, res: Response): Promise<void> {
const busqueda = (req.query.busqueda as string) ?? undefined
const desarrollo = (req.query.desarrollo as string) ?? undefined
const estatus = (req.query.estatus as string) ?? undefined
const datos = await clienteMaestroService.exportar({ busqueda, desarrollo, estatus })
res.json(datos)
}
// ── GET /api/clientes-maestro/:numCliente ────────────────────────────
export async function obtenerEndpoint(req: Request, res: Response): Promise<void> {
const numCliente = String(req.params['numCliente'] ?? '')
if (!numCliente) throw new BadRequestError('numCliente requerido')
const cliente = await clienteMaestroService.obtener(numCliente)
if (!cliente) throw new NotFoundError('Cliente no encontrado')
res.json(cliente)
}
// ── POST /api/clientes-maestro/importar ──────────────────────────────
export async function importarEndpoint(req: Request, res: Response): Promise<void> {
const datos = req.body
if (!Array.isArray(datos) || datos.length === 0) {
throw new BadRequestError('Se esperaba un array de clientes')
}
const resultado = await clienteMaestroService.importarDesdeExcel(datos)
res.json(resultado)
}
// Re-exportar requireAdmin para las rutas
export { requireAdmin }