Backend:
- Nuevo modelo Prisma ClientInvitation con token unico, expiracion
y estados (pending/accepted/expired).
- Migracion: 20260511213955_add_client_invitations
- Service client-invitations.service.ts: crear invitacion,
validar token, registrar desde invitacion (reutiliza logica
de creacion de tenant + usuario de despacho.service).
- Controller + routes: POST /invitations/client (admin),
GET /invitations/client/validate/:token (publico),
POST /invitations/client/register/:token (publico),
GET /invitations/client (admin).
- Email template client-invitation.ts con link a
/invitacion/registro/{token}.
- Agregado sendClientInvitation a email.service.
Frontend:
- Pagina /invitacion/registro/[token] para que el invitado
complete registro (nombre, password, despacho, RFC, perfil).
- Pagina /admin/invitar-cliente para que admin global envie
invitaciones y vea el historial.
- Hooks useCreateInvitation, useValidateInvitationToken,
useRegisterFromInvitation, useClientInvitations.
- API client lib/api/client-invitations.ts.
Infra:
- PM2 ecosystem.config.js: usa node --import tsx con
kill_timeout aumentado a 15s para evitar EADDRINUSE.
- React Query retry=2 con delay exponencial para resiliencia.
Refs: docs/CAMBIOS-2026-05-09.md
- ecosystem.config.js: cambiado de tsx CLI a que es
mas estable. Aumentado kill_timeout de 5s a 15s para evitar
EADDRINUSE cuando PM2 reinicia el API.
- query-provider.tsx: agregado retry=2 con delay exponencial a las
queries de React Query para que sean mas resilientes a caidas
breves del API.
Refs: docs/CAMBIOS-2026-05-09.md
La condicion SQL NOT (metodo_pago = 'PPD' AND ...) producia NULL
cuando metodo_pago era NULL (como en complementos de pago tipo P),
lo que excluia silenciosamente todos los tipo P del listado de
emitidos en conciliacion.
Cambiada a: metodo_pago IS NULL OR metodo_pago != 'PPD' OR
regimen_fiscal_emisor IN ('605','616')
Esto mantiene la intencion original (excluir PPD de regimenes
que no son 605/616) sin afectar a tipo P ni otros sin metodo de pago.
Refs: docs/CAMBIOS-2026-05-09.md seccion 8
- conciliacion.service.ts: filtros y ordenamiento ahora usan
COALESCE(fecha_pago_p, fecha_emision). Los CFDIs tipo P
(complementos de pago) aparecen en el periodo del pago real,
no de la emision del CFDI.
- conciliacion.service.ts: agrega fechaPagoP al SELECT y a la
interfaz ConciliacionCfdi.
- conciliacion/page.tsx: tablas y export Excel usan
fechaPagoP || fechaEmision para mostrar la fecha.
- cfdi-invoice.tsx: para tipo P con fechaPagoP, muestra
'Pago: {fecha}' en el encabezado.
- conciliacion.ts: actualiza interfaz ConciliacionCfdi con
todos los campos que ya devuelve el backend.
Refs: docs/CAMBIOS-2026-05-09.md secciones 7 y 8
- sat-sync.job.ts: cron diario e incremental ahora iteran contribuyentes
por tenant y pasan contribuyenteId a startSync(). Evita que CFDIs
importados del SAT queden con contribuyente_id = NULL.
- sat.service.ts: retryJob() ahora reintenta con job.contribuyenteId.
- conciliacion.service.ts: agrega campos faltantes al SELECT de CFDIs:
status, formaPago, serie, folio, usoCfdi, subtotal, descuento,
moneda, tipoCambio, ivaTraslado, ivaRetencion, isrRetencion,
fechaCertSat. Antes el visor mostraba 'CANCELADO' para todos los
CFDIs (status era undefined) y faltaban datos de forma de pago,
impuestos, serie/folio, etc.
Refs: docs/CAMBIOS-2026-05-09.md secciones 6 y 7
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