/** * Script: create-vendedor-fernando.ts * * Crea la cuenta de Fernando (fernando@horuxfin.com) como Vendedor de Horux 360. * Rol de plataforma: platform_sales (Vendedor). * Membership en el tenant Horux 360 con rol cliente (minimo, solo para login * y acceso a configuracion/cambio de contraseña). * * Si el usuario ya existe, le asigna/actualiza los permisos y envia un correo * de notificacion. Si es nuevo, genera password temporal y envia bienvenida. * * Uso: * cd apps/api && npx tsx scripts/create-vendedor-fernando.ts */ import { randomBytes } from 'crypto'; import { prisma } from '../src/config/database.js'; import { hashPassword } from '../src/auth/passwords.js'; import { emailService } from '../src/services/email/email.service.js'; import { invalidatePlatformRolesCache } from '../src/utils/platform-admin.js'; const EMAIL = 'fernando@horuxfin.com'; const NOMBRE = 'Fernando'; const HORUX_RFC = 'HTS240708LJA'; function generarPassword(): string { return randomBytes(6).toString('hex'); // 12 caracteres hex } async function main() { console.log(`🌱 Creando cuenta de Vendedor para ${EMAIL}...\n`); // 1. Tenant raiz Horux 360 const tenant = await prisma.tenant.findUnique({ where: { rfc: HORUX_RFC } }); if (!tenant) throw new Error(`Tenant Horux 360 (${HORUX_RFC}) no encontrado. Ejecuta primero el bootstrap admin global.`); // 2. Rol "cliente" para la membership (minimo acceso) const clienteRol = await prisma.rol.findUnique({ where: { nombre: 'cliente' } }); if (!clienteRol) throw new Error('Rol "cliente" no encontrado en BD central'); // 3. Buscar o crear usuario let user = await prisma.user.findUnique({ where: { email: EMAIL } }); let tempPassword: string | null = null; let esNuevo = false; if (!user) { tempPassword = generarPassword(); const passwordHash = await hashPassword(tempPassword); user = await prisma.user.create({ data: { email: EMAIL, passwordHash, nombre: NOMBRE, lastTenantId: tenant.id, active: true, }, }); esNuevo = true; console.log(`✅ Usuario creado: ${user.email}`); console.log(` Password temporal: ${tempPassword}`); } else { await prisma.user.update({ where: { id: user.id }, data: { lastTenantId: tenant.id, active: true }, }); console.log(`ℹ️ Usuario ya existia: ${user.email}`); } // 4. Membership en Horux 360 con rol cliente await prisma.tenantMembership.upsert({ where: { userId_tenantId: { userId: user.id, tenantId: tenant.id } }, update: { rolId: clienteRol.id, active: true, isOwner: false }, create: { userId: user.id, tenantId: tenant.id, rolId: clienteRol.id, active: true, isOwner: false, }, }); console.log(`✅ Membership "cliente" en ${tenant.nombre}`); // 5. Rol de plataforma Vendedor (platform_sales) await prisma.userPlatformRole.upsert({ where: { userId_role: { userId: user.id, role: 'platform_sales' } }, update: {}, create: { userId: user.id, role: 'platform_sales' }, }); console.log(`✅ Rol de plataforma "Vendedor" (platform_sales) asignado`); // 6. Invalidar cache de roles de plataforma invalidatePlatformRolesCache(user.id); // 7. Enviar correo con accesos (solo si es nuevo; si ya existia, no se reenvia password) if (esNuevo && tempPassword) { await emailService.sendWelcome(EMAIL, { nombre: NOMBRE, email: EMAIL, tempPassword, }); console.log(`✅ Correo de bienvenida con credenciales enviado a ${EMAIL}`); } else { console.log(`ℹ️ El usuario ya existia; no se envio correo con password`); } console.log('\n🎉 Cuenta de Vendedor lista'); console.log(` Email: ${EMAIL}`); if (tempPassword) console.log(` Password temporal: ${tempPassword}`); console.log(` Tenant: ${tenant.nombre} (${tenant.rfc})`); console.log(` Rol de plataforma: platform_sales (Vendedor)`); } main() .catch((err) => { console.error('\n❌ Error:', err.message || err); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });