This reverts commit d3b326e.
The deployment caused reports of blank screens and 400 errors. Reverting to restore stable state while investigating root cause.
- Add Sheet primitive component for mobile drawers
- Add MobileNav with hamburger menu for dashboard layout
- Hide desktop sidebars on mobile; show mobile header
- Make dashboard header responsive with stacked layout on small screens
- Hide selector text on mobile, show icons only
- Convert fixed-width filters to responsive widths (CFDI, Clientes, Admin, Documentos, Alertas)
- Cap dialog widths to 95vw on mobile (CFDI viewer, Documentos, Reportes, Contribuyentes, Facturación)
- Make calendar grid smaller and use single-letter weekdays on mobile
- Update viewport to include viewport-fit=cover for Samsung safe areas
- Agrega migración 050 con columnas de aprobación de cliente
(requiere_aprobacion_cliente, estado_cliente, aprobado_por_cliente, etc.)
- Backend: endpoints /aprobar-cliente y /rechazar-cliente con validación de permisos
- Backend: list/download permiten acceso a clientes filtrando por entidades visibles
- Backend: notificación por email a clientes cuando se les solicita aprobación
- Frontend: checkbox independiente para solicitar aprobación del cliente
- Frontend: badge de estado combinado (owner + cliente)
- Frontend: botones de aprobar/rechazar para clientes en su propio flujo
- La página /despachos/contribuyentes solo permite owner/cfo/platform_staff.
- La pestaña en el subnav ahora solo se muestra a esos roles, evitando que
supervisor, contador, visor y auxiliar vean un link que lleva a mensaje
de 'solo disponible para owner'.
- Sidebars/topnav: agrega 'auxiliar' y 'cliente' a la opción Configuracion
- /configuracion/page.tsx: auxiliar y cliente solo ven Información de Usuario,
Información de Empresa y Seguridad (cambio de contraseña). Todo lo demás
(FIEL, Obligaciones, Notificaciones, Facturación, CSD) queda restringido
a owner/cfo/supervisor
- Quitado Invitaciones Trial del sidebar (4 layouts)
- Agregado tab Invitaciones Trial dentro de /admin/usuarios
- Componente reutilizable invitaciones-trial-tab.tsx
- Agregada nueva opcion Tareas en el sidebar principal
Factura Global & fecha_efectiva:
- Migracion 045_factura_global.sql: periodicidad, meses_global, año_global, fecha_efectiva
- sat-parser.service.ts: extrae InformacionGlobal del XML
- sat.service.ts: calcFechaEfectiva con soporte bimestral (periodicidad 05)
- metricas-compute, dashboard, impuestos, cfdi, export, conciliacion, alertas:
reemplaza fecha_emision-1h por COALESCE(fecha_efectiva, fecha_emision-1h)
- Script recalc-metricas.ts para recalculo manual
Fallback datos fiscales tenant → contribuyente:
- contribuyente.service.ts: fetchTenantFiscalData + mergeContribuyenteWithTenant
rellena regimenFiscal, codigoPostal y domicilio cuando el contribuyente
tiene el mismo RFC que el tenant y sus campos estan vacios
- contribuyente.controller.ts y contribuyente-config.controller.ts:
pasan req.user!.tenantId al servicio
Fix critico SAT sync:
- sat.service.ts: anio_global → año_global en INSERT/UPDATE de CFDIs
(la migracion creo 'año_global' con tilde; el codigo usaba 'anio_global',
causando fallo en 100% de inserciones de CFDI)
- determineChunkMonths: salta sondeo si existe job previo con requestIds
- MAX_POLL_ATTEMPTS: 45 → 500 (~8h) para syncs iniciales grandes
Docs:
- docs/sessions/2026-05-22-factura-global-contribuyente-fallback.md
Para CFDIs tipo P (Pago) el visor ahora muestra:
- Monto pagado
- Fecha de pago
- Número de parcialidad
- UUID relacionado (factura pagada)
- Saldo insoluto
- Impuestos del pago (ISR/IVA/IEPS retenciones y traslados)
Además se ocultan para tipo P:
- Tabla de conceptos (dummy)
- Bloque de totales tradicional (subtotal/IVA/total)
- Sección CFDIs relacionados (reemplazada por UUID pagado)
El complemento de pago se renderiza en una card verde destacada.
Problema: el boton 'Sincronizacion inicial (6 años)' desaparecia cuando
existia CUALQUIER job completado (daily, incremental, etc.). Esto era
inconsistente con el cron incremental del backend, que requiere
especificamente un job de tipo 'initial' completado.
Resultado: usuarios que solo habian hecho sync diaria perdian la opcion
de hacer la extraccion inicial completa, y el cron incremental tampoco
corria porque no habia initial.
Fix:
- Backend getSyncStatus: agrega lastCompletedInitialJob (busca solo
jobs type='initial' status='completed')
- Frontend SyncStatus: muestra el boton de inicial si
!lastCompletedInitialJob (ignora jobs diarios/incrementales)
- SatSyncStatusResponse: agrega campo lastCompletedInitialJob
Problema: isDespachoTenant(user?.tenantRfc) compara contra prefijo
'DESPACHO_' que ningun tenant real usa. Esto hacia que sat/page.tsx
siempre usara el endpoint legacy a nivel tenant, ignorando el contribuyente
seleccionado y mostrando datos del tenant en lugar del contribuyente.
Cambios:
- sat/page.tsx: elimina isDespachoTenant, usa selectedContribuyenteId
directamente para determinar contribId. Muestra banner cuando no hay
contribuyente seleccionado.
- csd/page.tsx: agrega banner de contribuyente seleccionado y oculta
la UI de CSD cuando no hay contribuyente seleccionado.
- tenant-selector.tsx: limpia selectedContribuyenteId al cambiar de
tenant para evitar stale state.
- 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
- 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
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