docs: actualiza CAMBIOS-2026-05-04.md y commitea fixes pendientes
- Monitor de sincronización SAT (sat-sync-monitor.job + alerta por correo). - Scraper de CSF más robusto (iframes, blobs, popups, validación PDF). - Reactivación de contribuyentes desactivados y limpieza al desactivar. - Timeout de constancia aumentado a 5 min. - Variables de entorno SAT en .env.example y env.ts.
This commit is contained in:
@@ -331,8 +331,306 @@ La tabla `cat_clave_prod_serv` de la BD central estaba vacía; el catálogo nunc
|
||||
| `apps/web/lib/api/catalogos.ts` | `searchClaveProdServ` acepta `AbortSignal` |
|
||||
| `apps/web/app/(dashboard)/facturacion/page.tsx` | `handleSearchProduct` con `AbortController`, try/catch y `autoComplete="off"` |
|
||||
|
||||
## 16. Fix: CSF retry, backoff, delays entre tenants y timeouts aumentados
|
||||
|
||||
**Fecha:** 2026-06-01
|
||||
|
||||
### Cambios
|
||||
- Se agregó **retry con backoff** en la descarga de Constancias de Situación Fiscal.
|
||||
- Se agregaron **delays entre tenants** para no saturar el portal del SAT.
|
||||
- Se aumentaron los timeouts del proceso de constancia.
|
||||
|
||||
### Archivos modificados
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/api/src/services/constancia.service.ts` | Retry con backoff y manejo de errores |
|
||||
| `apps/api/src/services/sat/sat-csf-login.ts` | Timeouts y delays ajustados |
|
||||
| `apps/api/src/jobs/sat-sync.job.ts` | Delay entre ejecuciones de CSF por tenant |
|
||||
|
||||
---
|
||||
|
||||
## 17. Fix: múltiples fixes de producción en SAT, pagos y admin
|
||||
|
||||
**Fecha:** 2026-06-10
|
||||
|
||||
### Cambios
|
||||
- Ajustes en el pool de conexiones a tenants (`database.ts`).
|
||||
- Webhooks de MercadoPago más robustos ante eventos inesperados.
|
||||
- Mejoras en `admin-clientes.service.ts` e `invoicing.service.ts`.
|
||||
- Sweep de jobs SAT stale ajustado.
|
||||
|
||||
### Archivos modificados
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/api/src/config/database.ts` | Configuración de pool |
|
||||
| `apps/api/src/controllers/webhook.controller.ts` | Robustez en webhooks MP |
|
||||
| `apps/api/src/jobs/sat-sync.job.ts` | Fixes en recovery y scheduling |
|
||||
| `apps/api/src/services/admin-clientes.service.ts` | Fixes de admin |
|
||||
| `apps/api/src/services/payment/invoicing.service.ts` | Fixes de facturación |
|
||||
| `apps/api/src/services/sat/sat-client.service.ts` | Fixes de cliente SAT |
|
||||
| `apps/api/src/services/sat/sweep-stale-jobs.service.ts` | Ajuste de stale jobs |
|
||||
|
||||
---
|
||||
|
||||
## 18. Feat: scorecards de notas de crédito en dashboard
|
||||
|
||||
**Fecha:** 2026-06-13
|
||||
|
||||
### Cambios
|
||||
- Se agregaron scorecards de **notas de crédito emitidas** y **recibidas**.
|
||||
- Se reordenaron las tarjetas del dashboard.
|
||||
- Se ajustó el cálculo de **utilidad neta** considerando notas de crédito.
|
||||
|
||||
### Archivos modificados
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/api/src/services/dashboard.service.ts` | Nuevos campos de notas de crédito |
|
||||
| `apps/web/app/(dashboard)/dashboard/page.tsx` | Scorecards y utilidad ajustada |
|
||||
| `packages/shared/src/types/dashboard.ts` | Tipos actualizados |
|
||||
|
||||
---
|
||||
|
||||
## 19. Feat: cron de recuperación SAT diario a las 10:00 AM
|
||||
|
||||
**Fecha:** 2026-06-14
|
||||
|
||||
### Cambio
|
||||
Se agregó un cron diario a las 10:00 AM (`America/Mexico_City`) que ejecuta el **recovery sync** para contribuyentes con FIEL activa y sync incompleto.
|
||||
|
||||
### Archivo modificado
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/api/src/jobs/sat-sync.job.ts` | Nuevo `runRecoverySyncJob` y scheduling |
|
||||
|
||||
---
|
||||
|
||||
## 20. Fix: pagar plan actual en trial_expired y planes > $10k
|
||||
|
||||
**Fecha:** 2026-06-16
|
||||
|
||||
### Problema
|
||||
- Los tenants con suscripción `trial_expired` no podían pagar el plan actual.
|
||||
- Planes Business Control/Enterprise superiores a $10,000 no podían usar preapproval de MercadoPago.
|
||||
|
||||
### Solución
|
||||
- Se permite pagar el plan actual incluso en estado `trial_expired`.
|
||||
- Planes caros usan una **Preference one-off anual** de MercadoPago en lugar de preapproval.
|
||||
- Se agregó el campo `mpPreferenceId` a `subscriptions` para trackear la preference.
|
||||
- El webhook de MP maneja tanto preapproval como preference.
|
||||
|
||||
### Archivos modificados
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/api/src/controllers/despacho.controller.ts` | Lógica de pago de plan actual |
|
||||
| `apps/api/src/controllers/subscription.controller.ts` | Soporte de preference |
|
||||
| `apps/api/src/controllers/webhook.controller.ts` | Webhook para preference |
|
||||
| `apps/api/src/services/payment/mercadopago.service.ts` | Creación de preference anual |
|
||||
| `apps/api/src/services/payment/subscription.service.ts` | Pago de plan actual trial_expired |
|
||||
| `apps/web/app/(dashboard)/configuracion/planes-despacho/page.tsx` | UI para pagar plan actual vencido |
|
||||
| `apps/api/prisma/schema.prisma` | Campo `mpPreferenceId` |
|
||||
|
||||
---
|
||||
|
||||
## 21. Feat: configuración de notificaciones por rol
|
||||
|
||||
**Fecha:** 2026-06-17
|
||||
|
||||
### Cambio
|
||||
Se reemplazó el sistema de preferencias de notificación por contribuyente por uno por **rol**:
|
||||
- `owner`, `supervisor`, `auxiliar` y `cliente` pueden activar/desactivar tipos de correo.
|
||||
- Tipos: `documento_subido`, `weekly_update`, `subscription_expiring`, `recordatorio_fiscal`, `alertas_nuevas`, `recordatorio_proximo`.
|
||||
- La tabla `notification_role_preferences` almacena la configuración por tenant.
|
||||
|
||||
### Archivos creados
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/api/src/migrations/tenant/051_notification_role_preferences.sql` | Tabla de preferencias por rol |
|
||||
|
||||
### Archivos modificados
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/api/src/services/notification-preferences.service.ts` | Nuevo modelo por rol |
|
||||
| `apps/api/src/controllers/notification-preferences.controller.ts` | CRUD por rol |
|
||||
| `apps/api/src/services/notifications.service.ts` | Filtrado por rol |
|
||||
| `apps/api/src/services/notify-upload.service.ts` | Usa preferencias por rol |
|
||||
| `apps/api/src/services/payment/subscription.service.ts` | Usa preferencias por rol |
|
||||
| `apps/api/src/jobs/weekly-update.job.ts` | Filtrado por rol |
|
||||
| `apps/web/app/(dashboard)/configuracion/notificaciones/page.tsx` | UI de configuración |
|
||||
|
||||
---
|
||||
|
||||
## 22. Fix: quitar badge "Próximamente" de notificaciones ya existentes
|
||||
|
||||
**Fecha:** 2026-06-16
|
||||
|
||||
### Cambio
|
||||
Se quitó el badge "Próximamente" de los tipos de notificación que ya estaban implementados.
|
||||
|
||||
### Archivos modificados
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/api/src/services/notification-preferences.service.ts` | Marcado de implementados |
|
||||
| `apps/web/app/(dashboard)/configuracion/notificaciones/page.tsx` | Badges actualizados |
|
||||
|
||||
---
|
||||
|
||||
## 23. Feat: drill-down en pestaña nueva, rol Vendedor y scripts demo
|
||||
|
||||
**Fecha:** 2026-06-22
|
||||
|
||||
### Cambios
|
||||
- El **drill-down de impuestos** ahora se abre en una pestaña nueva (`/drill-down`).
|
||||
- Se agregó el rol **Vendedor** con acceso limitado a invitaciones trial y dashboard.
|
||||
- Se crearon scripts de soporte para demos:
|
||||
- `add-demo-cfdis.ts`
|
||||
- `add-demo-notas-credito.ts`
|
||||
- `create-vendedor-fernando.ts`
|
||||
|
||||
### Archivos creados
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/api/scripts/add-demo-cfdis.ts` | CFDIs de demo |
|
||||
| `apps/api/scripts/add-demo-notas-credito.ts` | Notas de crédito de demo |
|
||||
| `apps/api/scripts/create-vendedor-fernando.ts` | Crea usuario vendedor de demo |
|
||||
|
||||
### Archivos modificados
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/web/app/(dashboard)/drill-down/page.tsx` | Página de drill-down |
|
||||
| `apps/web/app/(dashboard)/impuestos/page.tsx` | Link a drill-down en pestaña nueva |
|
||||
| `apps/web/app/(dashboard)/dashboard/page.tsx` | Integración con drill-down |
|
||||
| `apps/web/app/(dashboard)/admin/staff/page.tsx` | Rol Vendedor en staff |
|
||||
| `apps/web/components/layouts/sidebar.tsx` | Menú para Vendedor |
|
||||
| `packages/shared-ui/src/charts/kpi-card.tsx` | Soporte de link externo |
|
||||
|
||||
---
|
||||
|
||||
## 24. Fix: evita logout al cambiar de tenant
|
||||
|
||||
**Fecha:** 2026-06-22
|
||||
|
||||
### Problema
|
||||
Al cambiar de empresa con el selector de tenants, múltiples requests en vuelo con el token viejo intentaban refrescar simultáneamente, causando logout o 401.
|
||||
|
||||
### Solución
|
||||
- Se agregó un **mutex de refresh token** en el interceptor de Axios.
|
||||
- Se marca el estado `isSwitching` en `membership-switcher` y `mis-empresas` para evitar clicks múltiples.
|
||||
- El backend invalida el refresh token anterior al hacer switch.
|
||||
|
||||
### Archivos modificados
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/web/lib/api/client.ts` | Mutex de refresh |
|
||||
| `apps/web/components/membership-switcher.tsx` | Flag `isSwitching` |
|
||||
| `apps/web/app/(dashboard)/mis-empresas/page.tsx` | Flag `isSwitching` |
|
||||
| `apps/api/src/services/auth.service.ts` | Invalidación de refresh token anterior |
|
||||
|
||||
---
|
||||
|
||||
## 25. Fix: Vendedor accede a invitaciones trial
|
||||
|
||||
**Fecha:** 2026-06-22
|
||||
|
||||
### Cambio
|
||||
El rol **Vendedor** puede ver y compartir invitaciones **trial**, pero no puede invitar clientes directamente.
|
||||
|
||||
### Archivos modificados
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/api/src/controllers/client-invitations.controller.ts` | Permisos para vendedor |
|
||||
| `apps/api/src/controllers/tenants.controller.ts` | Permisos para vendedor |
|
||||
| `apps/web/app/(dashboard)/admin/staff/page.tsx` | UI de permisos |
|
||||
| `apps/web/components/layouts/sidebar.tsx` | Menú visible para vendedor |
|
||||
|
||||
---
|
||||
|
||||
## 26. Feat: monitor de sincronización SAT
|
||||
|
||||
**Fecha:** 2026-06-22
|
||||
|
||||
### Cambio
|
||||
Se agregó un cron de monitoreo de sincronizaciones SAT (cada 2 horas por defecto). Detecta:
|
||||
- Jobs fallidos en las últimas N horas.
|
||||
- Jobs pending sin atender.
|
||||
- Jobs running atascados.
|
||||
- Contribuyentes con FIEL activa pero sin sync inicial.
|
||||
|
||||
Envía un correo de alerta a `SAT_ALERT_EMAIL` (o `ADMIN_EMAIL` si no está configurado).
|
||||
|
||||
### Variables de entorno
|
||||
| Variable | Default | Descripción |
|
||||
|---|---|---|
|
||||
| `SAT_ALERT_EMAIL` | `ADMIN_EMAIL` | Destino de alertas SAT |
|
||||
| `SAT_MONITOR_SCHEDULE` | `0 */2 * * *` | Cron del monitor |
|
||||
| `SAT_STUCK_RUNNING_HOURS` | `2` | Horas para considerar un job running como atorado |
|
||||
| `SAT_FAILED_LOOKBACK_HOURS` | `24` | Ventana hacia atrás para reportar jobs fallidos |
|
||||
|
||||
### Archivos creados
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/api/src/jobs/sat-sync-monitor.job.ts` | Lógica del monitor |
|
||||
| `apps/api/src/services/email/templates/sat-sync-alert.ts` | Template de alerta |
|
||||
|
||||
### Archivos modificados
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/api/src/index.ts` | Arranca el monitor |
|
||||
| `apps/api/src/config/env.ts` | Validación de variables |
|
||||
| `apps/api/.env.example` | Documentación de variables |
|
||||
| `apps/api/src/services/email/email.service.ts` | `sendSatSyncAlert` |
|
||||
|
||||
---
|
||||
|
||||
## 27. Feat: reactivación de contribuyentes y limpieza al desactivar
|
||||
|
||||
**Fecha:** 2026-06-22
|
||||
|
||||
### Cambios
|
||||
- Al crear un contribuyente cuyo RFC ya existía desactivado, se **reactiva** la entidad, se actualizan sus datos y se recupera su historial (CFDIs, FIEL, tareas, etc.).
|
||||
- Al desactivar un contribuyente, se limpia de `cartera_entidades`, `cliente_accesos` y se desactiva su FIEL para que no siga sincronizándose.
|
||||
- El timeout del proceso de constancia se aumentó a **5 minutos**.
|
||||
|
||||
### Archivos modificados
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/api/src/services/contribuyente.service.ts` | Reactivación y limpieza al desactivar |
|
||||
| `apps/api/src/controllers/contribuyente.controller.ts` | Retorna `reactivated` y status 200/201 |
|
||||
| `apps/api/src/services/constancia.service.ts` | Timeout 5 min |
|
||||
| `apps/web/app/(dashboard)/contribuyentes/page.tsx` | Alerta al reactivar |
|
||||
| `apps/web/lib/api/contribuyentes.ts` | Tipo `reactivated` |
|
||||
|
||||
---
|
||||
|
||||
## 28. Fix: scraper de Constancia de Situación Fiscal más robusto
|
||||
|
||||
**Fecha:** 2026-06-22
|
||||
|
||||
### Cambio
|
||||
Se reescribió el scraper de CSF para soportar los múltiples flujos del portal SAT:
|
||||
- Búsqueda de PDF en frames, iframes, embeds, links `blob:`/`data:` y popups.
|
||||
- Validación de que el buffer descargado comienza con `%PDF-`.
|
||||
- Fallback de click por `dispatchEvent` si el primer click no dispara el handler JSF.
|
||||
|
||||
### Archivo modificado
|
||||
| Archivo | Cambio |
|
||||
|---|---|
|
||||
| `apps/api/src/services/sat/sat-csf-scraper.ts` | Reescritura del scraper |
|
||||
|
||||
## Deploy
|
||||
|
||||
### Preparación
|
||||
|
||||
1. Asegurarse de que `apps/api/.env` tenga las nuevas variables (tienen defaults, pero conviene declararlas):
|
||||
```bash
|
||||
SAT_ALERT_EMAIL=carlos@horuxfin.com
|
||||
SAT_MONITOR_SCHEDULE=0 */2 * * *
|
||||
SAT_STUCK_RUNNING_HOURS=2
|
||||
SAT_FAILED_LOOKBACK_HOURS=24
|
||||
```
|
||||
2. Si hay scripts de debug antiguos en `apps/api/scripts/`, limpiar los que no sean necesarios antes de commitear.
|
||||
|
||||
### Comandos
|
||||
|
||||
```bash
|
||||
cd /root/HoruxDespachosNuevo
|
||||
pnpm --filter @horux/core build
|
||||
|
||||
Reference in New Issue
Block a user