feat: facturación primer pago, fixes SAT/MP, autocompletado RFCs/conceptos
Backend: - Notificación email al admin cuando llega primer pago aprobado (sin factura auto) - Endpoints GET /pagos-sin-factura y POST /emitir-factura-pago para admin global - Fix vinculación org Facturapi Horux 360 (69f23a5a242e0af47a41fa0d) - Fix webhook MP: validación defensiva de x-signature header - Fix autocompleto RFCs: eliminado filtro por contribuyenteId - Fix autocompleto conceptos: eliminado filtro por contribuyenteId - SAT fixes: anti-bot CSF scraper, request reuse, date range fix, stale job thresholds - SAT sync request reuse across jobs para evitar agotar cuota diaria - Typo fix MP_ACCESS_TOKEN en .env - Trial invitations system backend Frontend: - Nueva página /admin/facturas-pendientes con tabla y emisión manual - Métrica 'Facturas pendientes' en /clientes (clickable) - Navegación onboarding FIEL/CSD corregida - Sidebar themes sincronizados - Fix SAT portal migration scraper (NetIQ) - Trial invitation acceptance pages
This commit is contained in:
@@ -5,11 +5,8 @@ import * as ctrl from '../controllers/despacho-stats.controller.js';
|
||||
|
||||
const router: IRouter = Router();
|
||||
|
||||
router.use(authenticate);
|
||||
router.use(tenantMiddleware);
|
||||
|
||||
router.get('/contribuyentes-stats', ctrl.getContribuyentesStats);
|
||||
router.get('/mis-asignados', ctrl.getMisAsignados);
|
||||
router.get('/equipo-stats', ctrl.getEquipoStats);
|
||||
router.get('/contribuyentes-stats', authenticate, tenantMiddleware, ctrl.getContribuyentesStats);
|
||||
router.get('/mis-asignados', authenticate, tenantMiddleware, ctrl.getMisAsignados);
|
||||
router.get('/equipo-stats', authenticate, tenantMiddleware, ctrl.getEquipoStats);
|
||||
|
||||
export { router as despachoStatsRoutes };
|
||||
|
||||
@@ -61,4 +61,8 @@ router.get('/cfdis-ppd', facturacionController.getCfdisPpdPendientes);
|
||||
// CFDIs emitidos por el contribuyente al receptor (para sección "CFDIs relacionados")
|
||||
router.get('/cfdis-relacionables', facturacionController.getCfdisRelacionables);
|
||||
|
||||
// Admin global: pagos de suscripción sin factura + emisión manual
|
||||
router.get('/pagos-sin-factura', facturacionController.getPagosSinFactura);
|
||||
router.post('/emitir-factura-pago/:paymentId', strictLimit, facturacionController.emitirFacturaPago);
|
||||
|
||||
export { router as facturacionRoutes };
|
||||
|
||||
22
apps/api/src/routes/trial-invitations.routes.ts
Normal file
22
apps/api/src/routes/trial-invitations.routes.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Router, type IRouter } from 'express';
|
||||
import { authenticate } from '../middlewares/auth.middleware.js';
|
||||
import * as trialInvitationsController from '../controllers/trial-invitations.controller.js';
|
||||
|
||||
const router: IRouter = Router();
|
||||
|
||||
// Public endpoint: anyone can view invitation details by token (no auth required)
|
||||
router.get('/token/:token', trialInvitationsController.getInvitationByToken);
|
||||
|
||||
// Authenticated endpoints
|
||||
router.use(authenticate);
|
||||
|
||||
// Global admin endpoints
|
||||
router.post('/', trialInvitationsController.createInvitation);
|
||||
router.get('/', trialInvitationsController.getAllInvitations);
|
||||
router.post('/:id/cancel', trialInvitationsController.cancelInvitation);
|
||||
|
||||
// Self-serve endpoints (autenticado, owner validation in controller)
|
||||
router.get('/pending', trialInvitationsController.getMyPendingInvitation);
|
||||
router.post('/:token/accept', trialInvitationsController.acceptInvitation);
|
||||
|
||||
export { router as trialInvitationRoutes };
|
||||
Reference in New Issue
Block a user