Files
HoruxDespachosNuevo/docs/sessions/2026-05-23-asignaciones-tareas-admin-ui.md

7.1 KiB

Sesión 2026-05-23: Asignaciones, Tareas, Admin UI y Fixes

Resumen

Sesión extensa con múltiples fixes de bugs críticos descubiertos tras deploy de la feature de asignaciones, más nuevas funcionalidades de UX solicitadas por el usuario.


1. Fixes de build y deploy inicial de Asignaciones

Problemas de build de Next.js

  • Badge no exportado desde @horux/shared-ui: Reemplazado por <span> con clases CSS equivalentes en seguimiento-auxiliares.tsx.
  • Tabs requería defaultValue: Agregado defaultValue="carteras" al componente <Tabs> en carteras/page.tsx.

Migración tenant 046 aplicada

  • Archivo: apps/api/src/migrations/tenant/046_asignaciones_obligaciones_tareas.sql
  • Tablas creadas: obligacion_asignaciones, tarea_asignaciones
  • Aplicada a 7 tenants activos.

2. Fix: Invitación de usuarios no enviaba correo

Root cause: usuarios.service.tsinviteUsuario generaba tempPassword pero nunca llamaba emailService.sendWelcome().

Fix:

  • Importado emailService en usuarios.service.ts
  • Agregada llamada emailService.sendWelcome() cuando se crea un usuario nuevo (tempPassword !== null)
  • Aplicado también a createUsuarioGlobal

Reenvío de correos a usuarios invitados previos

  • Identificados 9 usuarios creados entre jueves 21/05 y hoy sin lastLogin
  • Generadas nuevas contraseñas temporales, hasheadas en BD, y enviados correos de bienvenida

3. Fix: Subcartera mostraba contribuyentes de todo el tenant

Root cause: SubcarteraCard filtraba available solo excluyendo los ya asignados a la subcartera, sin verificar que pertenecieran a la cartera padre.

Fixes:

  • Frontend: SubcarteraCard ahora recibe parentEntidadIds y filtra: (parentEntidadIds ?? []).includes(c.id)
  • Backend: cartera.service.tsaddEntidadToCartera valida que si es subcartera (parentId !== null), la entidad previamente exista en la cartera padre.

4. Fix: Obligaciones y Tareas no se mostraban (error 500)

Root cause: Las queries de obligaciones.service.ts, tareas.service.ts y asignaciones.service.ts hacían LEFT JOIN users en la BD de tenant, pero la tabla users solo existe en la BD central (horux360).

Error: relation "users" does not exist

Fixes:

  • Quitados todos los LEFT JOIN users de queries de tenant
  • En obligaciones.service.ts y tareas.service.ts: se mantiene solo auxiliarAsignadoId (sin nombre)
  • En asignaciones.service.ts: creada función resolveUserNames() que consulta Prisma (BD central) para obtener nombres de usuarios y mapearlos en los resultados
  • Fix adicional: asignaciones.controller.ts usaba req.params.id como obligacionId cuando en realidad req.params.id era contribuyenteId. Corregido a req.params.obligacionId.

5. Fix: Endpoint /carteras/asignaciones devolvía 500

Root cause: Ruta dinámica GET /:id estaba definida antes de GET /asignaciones en cartera.routes.ts. Express interpretaba "asignaciones" como parámetro :id.

Error: invalid input syntax for type uuid: "asignaciones"

Fix: Reordenadas las rutas estáticas (/asignaciones, /asignaciones/mias, /asignaciones/sin-asignar) antes de las rutas dinámicas (/:id).


6. Fix: Owner no veía asignaciones en "Asignadas"

Root cause: getAsignacionesPorSupervisor filtraba por asp.supervisor_user_id = $1. Un owner no aparece en auxiliar_supervisores, por lo que no veía sus propias asignaciones.

Fix: La función ahora recibe role como parámetro. Si es owner/cfo/contador, no filtra por supervisor. Si es supervisor, filtra por auxiliar_supervisores.


7. Fix: Lista "Sin asignar" no se refrescaba tras asignar

Root cause: Las mutations useAsignarObligacion, useDesasignarObligacion, useAsignarTarea, useDesasignarTarea invalidaban ['asignaciones-supervisor'] pero no ['asignaciones-sin-asignar'].

Fix: Agregada invalidación de ['asignaciones-sin-asignar'] a las 4 mutations.


8. Feature: Seguimiento de Auxiliares — pestaña "Sin asignar"

Nuevo endpoint: GET /carteras/asignaciones/sin-asignar

  • Devuelve obligaciones y tareas activas que NO están en las tablas de asignaciones
  • Respeta permisos: owner/cfo ven todo, supervisor solo sus contribuyentes

Frontend:

  • Reestructurado SeguimientoAuxiliares con tabs principales: "Asignadas" | "Sin asignar"
  • Dentro de cada uno, subtabs: Obligaciones | Tareas
  • El modal de asignación funciona en ambas vistas

9. Feature: Nueva página /tareas (Tareas Operativas)

Nuevo endpoint: GET /tareas/mis-tareas

  • Devuelve todas las tareas activas con su periodo actual para los contribuyentes visibles del usuario
  • Usa materializarPeriodos para cada contribuyente y luego listTareasConPeriodoPorContribuyentes para traer todo en batch

Frontend:

  • Nueva ruta: /tareas
  • Agregada al sidebar principal en todos los layouts (icono CheckSquare2)
  • Muestra tareas agrupadas por contribuyente
  • Filtros: Todas / Pendientes / Completadas
  • Permite marcar/desmarcar tareas como completadas
  • Muestra indicadores: atrasada, supervisor-only, recurrencia, fecha límite

10. Feature: Obligaciones Fiscales ya no se pueden marcar como completadas

En /pendientes, se quitó el botón interactivo de check de las obligaciones fiscales. Ahora solo muestra un ícono visual del estado sin acción.


11. Feature: Invitaciones Trial movido a Admin Usuarios

Sidebar: Quitado "Invitaciones Trial" de adminNavigation en los 4 layouts (sidebar.tsx, sidebar-compact.tsx, sidebar-floating.tsx, topnav.tsx).

Admin Usuarios: Agregados tabs con <Tabs>:

  • "Usuarios" — gestión de usuarios global existente
  • "Invitaciones Trial" — formulario de envío + historial (extraído a componente admin/_components/invitaciones-trial-tab.tsx)

Archivos modificados

Backend

  • apps/api/src/services/usuarios.service.ts
  • apps/api/src/services/cartera.service.ts
  • apps/api/src/services/obligaciones.service.ts
  • apps/api/src/services/tareas.service.ts
  • apps/api/src/services/asignaciones.service.ts
  • apps/api/src/controllers/asignaciones.controller.ts
  • apps/api/src/controllers/tareas.controller.ts
  • apps/api/src/routes/cartera.routes.ts
  • apps/api/src/routes/contribuyente.routes.ts
  • apps/api/src/routes/tareas.routes.ts

Frontend

  • apps/web/app/(dashboard)/carteras/page.tsx
  • apps/web/app/(dashboard)/carteras/seguimiento-auxiliares.tsx
  • apps/web/app/(dashboard)/pendientes/page.tsx
  • apps/web/app/(dashboard)/admin/usuarios/page.tsx
  • apps/web/app/(dashboard)/admin/_components/invitaciones-trial-tab.tsx
  • apps/web/app/(dashboard)/tareas/page.tsx
  • apps/web/components/layouts/sidebar.tsx
  • apps/web/components/layouts/sidebar-compact.tsx
  • apps/web/components/layouts/sidebar-floating.tsx
  • apps/web/components/layouts/topnav.tsx
  • apps/web/lib/api/asignaciones.ts
  • apps/web/lib/api/tareas-mis.ts
  • apps/web/lib/hooks/use-asignaciones.ts
  • apps/web/lib/hooks/use-tareas-mis.ts

Migraciones

  • apps/api/src/migrations/tenant/046_asignaciones_obligaciones_tareas.sql