185 lines
7.3 KiB
Markdown
185 lines
7.3 KiB
Markdown
# 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_contribuyente` del contribuyente seleccionado
|
|
- Respeta frecuencia, `created_at` y 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:
|
|
1. Se matchean los impuestos seleccionados (IVA, ISR, IEPS, etc.) contra las obligaciones del contribuyente por keywords
|
|
2. Se marcan como completadas en `obligacion_periodos`
|
|
3. Se resuelven las alertas `ob-{id}-{periodo}` correspondientes
|
|
4. 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 en `cartera_entidades` de sus carteras
|
|
- `listContribuyentes`: 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`
|