Merge remote-tracking branch 'origin/master' into feat-ajuste-acesso

This commit is contained in:
2025-10-30 14:01:08 -03:00
76 changed files with 15420 additions and 1212 deletions

View File

@@ -229,7 +229,9 @@ export const enviarEmailAction = action({
},
returns: v.object({ sucesso: v.boolean(), erro: v.optional(v.string()) }),
handler: async (ctx, args) => {
// TODO: Implementar com nodemailer quando instalado
"use node";
// eslint-disable-next-line @typescript-eslint/no-var-requires
const nodemailer = require("nodemailer");
try {
// Buscar email da fila
@@ -248,7 +250,17 @@ export const enviarEmailAction = action({
);
if (!config) {
return { sucesso: false, erro: "Configuração de email não encontrada" };
return {
sucesso: false,
erro: "Configuração de email não encontrada ou inativa",
};
}
if (!config.testadoEm) {
return {
sucesso: false,
erro: "Configuração SMTP não foi testada. Teste a conexão primeiro!",
};
}
// Marcar como enviando
@@ -256,15 +268,32 @@ export const enviarEmailAction = action({
emailId: args.emailId,
});
// TODO: Enviar email real com nodemailer aqui
console.log(
"⚠️ AVISO: Envio de email simulado (nodemailer não instalado)"
);
// Criar transporter do nodemailer
const transporter = nodemailer.createTransport({
host: (config as any).smtpHost,
port: (config as any).smtpPort,
secure: (config as any).smtpSecure,
auth: {
user: (config as any).smtpUser,
pass: (config as any).smtpPassword,
},
tls: {
rejectUnauthorized: false,
},
});
// Enviar email REAL
const info = await transporter.sendMail({
from: `"${(config as any).remetenteNome}" <${(config as any).remetenteEmail}>`,
to: (email as any).destinatario,
subject: (email as any).assunto,
html: (email as any).corpo,
});
console.log("✅ Email enviado com sucesso!");
console.log(" Para:", (email as any).destinatario);
console.log(" Assunto:", (email as any).assunto);
// Simular delay de envio
await new Promise((resolve) => setTimeout(resolve, 500));
console.log(" Message ID:", info.messageId);
// Marcar como enviado
await ctx.runMutation(internal.email.markEmailEnviado, {
@@ -273,6 +302,8 @@ export const enviarEmailAction = action({
return { sucesso: true };
} catch (error: any) {
console.error("❌ Erro ao enviar email:", error.message);
// Marcar como falha
await ctx.runMutation(internal.email.markEmailFalha, {
emailId: args.emailId,
@@ -309,17 +340,19 @@ export const processarFilaEmails = internalMutation({
continue;
}
// Agendar envio (será feito por uma action separada)
// Por enquanto, apenas marca como enviado para não bloquear
await ctx.db.patch(email._id, {
status: "enviado",
enviadoEm: Date.now(),
// Agendar envio via action
// IMPORTANTE: Não podemos chamar action diretamente de mutation
// Por isso, usaremos o scheduler
await ctx.scheduler.runAfter(0, "email:enviarEmailAction" as any, {
emailId: email._id,
});
processados++;
}
console.log(`📧 Fila de emails processada: ${processados} emails`);
console.log(
`📧 Fila de emails processada: ${processados} emails agendados para envio`
);
return { processados };
},