Files
HoruxDespachosNuevo/apps/api/scripts/resend-welcome.ts
Horux Dev 7df27ce66d chore: catálogo obligaciones, cierre automático, fixes SAT y facturación
- Catálogo de obligaciones fiscales expandido a 30 entradas con campo requierePago.
- Soporte de frecuencia cuatrimestral en obligaciones y declaraciones.
- Automatización de cierre de obligaciones fiscales desde Documentos › Declaraciones.
- Nuevas tablas obligacion_evidencias, obligacion_periodos estados y declaracion_obligaciones.
- Nuevo servicio obligacion-evidencias.service.ts y endpoints REST.
- Refactor de declaraciones.service.ts para vincular obligaciones y crear evidencias.
- Notificaciones por email para evidencias de obligaciones.
- Adjuntar PDFs en correo de declaración subida.
- Fix drill-down de CFDIs: carga completa al visualizar.
- Fix sincronización SAT: tipos P/N, UUID case-insensitive, no reutilizar requestId.
- Fix suscripciones pending en /configuracion/planes-despacho.
- Fix sugerencias de Clave Producto SAT: importar catálogo y robustecer autocomplete.
- Quitar toggle manual de completado en Configuración › Obligaciones fiscales › Tareas.
- Scripts de soporte para Demo Ventas y utilerías (change-user-email, resend-welcome, import-clave-prod-serv).
- Documentación de cambios en docs/CAMBIOS-2026-05-04.md.
2026-06-22 04:53:59 +00:00

68 lines
1.8 KiB
TypeScript

/**
* Script: resend-welcome
*
* Genera una nueva contraseña temporal para el usuario y reenvía el correo
* de bienvenida. Útil cuando el envío anterior falló o se perdió.
*
* Ejecución:
* cd apps/api && npx tsx scripts/resend-welcome.ts
*/
import { PrismaClient } from '@prisma/client';
import bcrypt from 'bcryptjs';
import { randomBytes } from 'crypto';
import { emailService } from '../src/services/email/email.service.js';
const prisma = new PrismaClient();
const EMAIL = 'miguel.corona@corpcyl.com';
function generateTempPassword(length = 12): string {
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789';
let result = '';
const bytes = randomBytes(length);
for (let i = 0; i < length; i++) {
result += chars[bytes[i] % chars.length];
}
return result + '!';
}
async function main() {
const user = await prisma.user.findUnique({ where: { email: EMAIL } });
if (!user) {
console.error(`❌ No existe un usuario con el correo ${EMAIL}`);
process.exit(1);
}
const tempPassword = generateTempPassword();
const passwordHash = await bcrypt.hash(tempPassword, 12);
await prisma.user.update({
where: { id: user.id },
data: {
passwordHash,
tokenVersion: { increment: 1 },
},
});
console.log('⏳ Enviando correo de bienvenida a', EMAIL, '...');
await emailService.sendWelcome(EMAIL, {
nombre: user.nombre,
email: EMAIL,
tempPassword,
});
console.log('✅ Correo de bienvenida enviado');
console.log(' Nombre:', user.nombre);
console.log(' Email:', EMAIL);
console.log(' Contraseña temporal:', tempPassword);
}
main()
.catch((e) => {
console.error('\n❌ Error enviando correo:', e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});