feat: asignaciones obligaciones/tareas + fixes backend

- Migracion 046: tablas obligacion_asignaciones y tarea_asignaciones
- Servicio y controller de asignaciones (CRUD + listados)
- Fix: enviar correo welcome al invitar usuario nuevo
- Fix: quitar JOIN users de queries tenant (usar Prisma en BD central)
- Fix: req.params.obligacionId correcto en asignaciones controller
- Fix: orden rutas estaticas antes de dinamicas en cartera.routes
- Fix: owner/cfo ven todas las asignaciones en getAsignacionesPorSupervisor
- Fix: validar que entidad pertenezca a cartera padre en subcartera
- Nuevo endpoint GET /carteras/asignaciones/sin-asignar
- Nuevo endpoint GET /tareas/mis-tareas
This commit is contained in:
Horux Dev
2026-05-23 23:40:12 +00:00
parent 0c7580aa44
commit f43cb165c6
11 changed files with 596 additions and 14 deletions

View File

@@ -2,6 +2,7 @@ import { prisma } from '../config/database.js';
import bcrypt from 'bcryptjs';
import { randomBytes } from 'crypto';
import { getDespachoPlanLimits } from './plan-catalogo.service.js';
import { emailService } from './email/email.service.js';
import type { UserListItem, UserInvite, UserUpdate, Role } from '@horux/shared';
/**
@@ -99,6 +100,13 @@ export async function inviteUsuario(tenantId: string, data: UserInvite): Promise
lastTenantId: tenantId,
},
});
// Enviar correo de bienvenida con credenciales (non-blocking)
emailService.sendWelcome(data.email, {
nombre: data.nombre,
email: data.email,
tempPassword,
}).catch(err => console.error('[EMAIL] Welcome email failed:', err));
}
const rolId = await getRolId(data.role);
@@ -224,8 +232,9 @@ export async function createUsuarioGlobal(
// Si el email ya existe como user global, agregamos membership en este tenant
let user = await prisma.user.findUnique({ where: { email: data.email } });
let tempPassword: string | null = null;
if (!user) {
const tempPassword = randomBytes(4).toString('hex');
tempPassword = randomBytes(4).toString('hex');
const passwordHash = await bcrypt.hash(tempPassword, 12);
user = await prisma.user.create({
data: {
@@ -235,6 +244,13 @@ export async function createUsuarioGlobal(
lastTenantId: tenantId,
},
});
// Enviar correo de bienvenida con credenciales (non-blocking)
emailService.sendWelcome(data.email, {
nombre: data.nombre,
email: data.email,
tempPassword,
}).catch(err => console.error('[EMAIL] Welcome email failed:', err));
}
const rolId = await getRolId(data.role);