7.3 KiB
Sesión 2026-04-19 (Parte 2) — Fixes, Roles y Features
Resumen
Sesión enfocada en corregir el sistema de alertas/obligaciones, implementar permisos por rol, y enlazar declaraciones con obligaciones.
1. Alertas de obligaciones — generación per-contribuyente (#10)
Problema: sincronizarAlertasManuales generaba alertas desde el calendario fiscal estático (catálogo genérico), mostrando obligaciones que no correspondían al contribuyente.
Fix: Para despachos (isDespachoTenant):
- Genera alertas desde
obligaciones_contribuyentedel contribuyente seleccionado - Respeta frecuencia,
created_aty periodos completados - "Todos los RFCs" no genera alertas nuevas, solo muestra las existentes
- Alertas legacy (
decl-*,pago-*) eliminadas del despacho
Archivos: apps/api/src/services/alertas-manuales.service.ts
2. Calendario — colores por status de obligación (#7)
Fix: generarEventosDesdeObligaciones ahora genera tipos diferenciados:
obligacion-pendiente(amber)obligacion-completada(green)obligacion-atrasada(red)
Frontend: iconos y colores agregados en tipoIcons / tipoColors.
Archivos: apps/api/src/services/calendario-fiscal.service.ts, apps/web/app/(dashboard)/calendario/page.tsx
3. Editar accesos de clientes (#1)
Backend: Endpoints GET/POST /usuarios/:id/accesos para listar y reemplazar accesos de un cliente.
Frontend: Botón "Accesos" en la lista de usuarios para clientes. Modal con checkboxes de RFCs.
Archivos: apps/api/src/controllers/usuarios.controller.ts, apps/api/src/routes/usuarios.routes.ts, apps/web/app/(dashboard)/usuarios/page.tsx
4. Enlazar declaraciones con obligaciones (#6)
Implementación: Al subir una declaración:
- Se matchean los impuestos seleccionados (IVA, ISR, IEPS, etc.) contra las obligaciones del contribuyente por keywords
- Se marcan como completadas en
obligacion_periodos - Se resuelven las alertas
ob-{id}-{periodo}correspondientes - Frontend invalida queries de alertas y calendario
Mapeo: IVA→"iva", ISR→"isr", IEPS→"ieps", DIOT→"proveedores de iva", SUELDOS→"sueldos"/"salarios"
Archivos: apps/api/src/services/declaraciones.service.ts, apps/api/src/controllers/documentos.controller.ts, apps/web/lib/api/declaraciones.ts, apps/web/lib/hooks/use-declaraciones.ts, apps/web/app/(dashboard)/documentos/page.tsx
5. Obligaciones — limpieza al desactivar
Fix: removeObligacion ahora elimina alertas (DELETE FROM alertas WHERE tipo LIKE 'ob-{id}-%') y periodos completados al desactivar. initRecomendaciones limpia alertas y periodos antes de reemplazar.
Prevención: getAlertasManualesPendientes excluye alertas de obligaciones inactivas (activa = false).
Archivos: apps/api/src/services/obligaciones.service.ts, apps/api/src/services/alertas-manuales.service.ts, apps/web/app/(dashboard)/configuracion/obligaciones/page.tsx
6. Filtro alertas por rol (auxiliar, supervisor, cliente)
Fix: getAlertasManualesPendientes ahora filtra por rol:
- Owner: todas las alertas
- Supervisor: solo de contribuyentes en sus carteras
- Auxiliar: solo de contribuyentes en sus subcarteras
- Cliente: solo de contribuyentes en
cliente_accesos
Dashboard (/dashboard/alertas) usa getAlertasManualesPendientes con filtro por rol en lugar de dashboardService.getAlertas sin filtro.
Archivos: apps/api/src/services/alertas-manuales.service.ts, apps/api/src/controllers/dashboard.controller.ts, apps/api/src/controllers/alertas.controller.ts
7. Sidebar — roles de despacho
Cambios:
- Supervisor: agregado a Pendientes, Dashboard, Reportes, Facturación
- Cliente: agregado a Dashboard, Reportes
- Carteras: visible para supervisor y auxiliar
- Onboarding: oculto para cliente; login redirige directo a dashboard para cliente/auxiliar/supervisor
Archivos: apps/web/components/layouts/sidebar.tsx, apps/web/app/(auth)/login/page.tsx
8. Permisos de carteras — niveles por rol
| Acción | Owner | Supervisor | Auxiliar |
|---|---|---|---|
| Ver carteras | Todas | Sus asignadas | Sus subcarteras |
| Crear cartera | Sí | No | No |
| Editar/eliminar cartera | Sí | No | No |
| Agregar/quitar RFCs a cartera | Sí | No | No |
| Crear subcarteras | Sí | Sí | No |
| Agregar RFCs a subcarteras | Sí | Sí | No |
Backend: Lógica de permisos en controller con verificación de parent para subcarteras.
Frontend: Props canEdit y canManageSubcarteras condicionan botones.
Archivos: apps/api/src/controllers/cartera.controller.ts, apps/api/src/routes/cartera.routes.ts, apps/web/app/(dashboard)/carteras/page.tsx
9. Supervisor — visibilidad de contribuyentes
Problema: El supervisor veía todos los contribuyentes porque entidades-visibles.ts buscaba supervisor_user_id (null) y listContribuyentes([]) devolvía todo.
Fix:
entidades-visibles.ts: supervisor busca encartera_entidadesde sus carteraslistContribuyentes: array vacío = lista vacía (no todos)
Archivos: apps/api/src/utils/entidades-visibles.ts, apps/api/src/services/contribuyente.service.ts
10. Pendientes — filtro "Mis asignados"
Problema: Usaba supervisorUserId directo (siempre null en despachos).
Fix: Filtra por contribuyentes visibles del usuario actual (ya filtrados por useContribuyentes según rol).
Archivos: apps/web/app/(dashboard)/pendientes/page.tsx
11. Auto-selección de contribuyente
Fix: Si un usuario solo tiene 1 contribuyente (ej: cliente), se auto-selecciona. No muestra "Todos los RFCs" cuando solo hay 1.
Archivos: apps/web/components/contribuyente-selector.tsx
12. Conciliación — permisos expandidos
Fix: Ahora owner, cfo, contador, auxiliar y supervisor pueden conciliar/desconciliar (antes solo owner+contador).
Archivos: apps/api/src/controllers/conciliacion.controller.ts
13. Calendario — permisos recordatorios
Fix: Ahora owner, cfo, contador, auxiliar y supervisor pueden crear/editar recordatorios (antes solo owner+contador).
Archivos: apps/web/app/(dashboard)/calendario/page.tsx
14. Dropdown regímenes — posición
Fix: Dropdown se despliega left-0 en lugar de right-0 para evitar desbordamiento.
Archivos: packages/shared-ui/src/form/regimen-selector.tsx
15. ISR Base Gravable — KPI fallback
Problema: Al seleccionar un régimen sin datos (605, 621), el KPI mostraba el total global en lugar de $0.
Fix: value={regimenSeleccionado ? (bg?.baseGravable ?? 0) : resumenIsr?.baseGravable || 0}
Archivos: apps/web/app/(dashboard)/impuestos/page.tsx
16. CFDIs — filtro expandido solo para listado
Problema: El filtro OR rfc_emisor/rfc_receptor se aplicó a todos los servicios, causando doble conteo en métricas fiscales.
Fix: Filtro expandido solo en cfdi.service.ts (listado). Dashboard, Impuestos, Reportes, Alertas, Conciliación usan solo contribuyente_id.
Archivos: apps/api/src/utils/contribuyente-context.ts, apps/api/src/services/dashboard.service.ts, apps/api/src/services/alertas-auto.service.ts, apps/api/src/services/reportes.service.ts, apps/api/src/services/conciliacion.service.ts, apps/api/src/controllers/alertas.controller.ts