Compare commits

..

2 Commits

Author SHA1 Message Date
fe83a3d371 feat: update email handling and user management logic
- Added logic to update user email if it differs from the existing record when updating a funcionario.
- Refactored email sending action to improve code readability and maintainability, including consistent formatting and error handling.
- Enhanced logging for email configuration and sending processes to provide clearer feedback during operations.
2025-11-05 15:05:54 -03:00
Kilder Costa
d0bcef4d40 Merge pull request #7 from killer-cf/feat-ausencia
Feat ausencia
2025-11-05 10:49:12 -03:00
2 changed files with 50 additions and 18 deletions

View File

@@ -1,9 +1,10 @@
"use node"; "use node";
import { action } from "../_generated/server"; import { action } from "../_generated/server";
import { v } from "convex/values"; import { v } from "convex/values";
import { internal } from "../_generated/api"; import { internal } from "../_generated/api";
import { decryptSMTPPasswordNode } from "./utils/nodeCrypto"; import { decryptSMTPPasswordNode } from "./utils/nodeCrypto";
import nodemailer from "nodemailer";
export const enviar = action({ export const enviar = action({
args: { args: {
@@ -12,7 +13,6 @@ export const enviar = action({
returns: v.object({ sucesso: v.boolean(), erro: v.optional(v.string()) }), returns: v.object({ sucesso: v.boolean(), erro: v.optional(v.string()) }),
handler: async (ctx, args) => { handler: async (ctx, args) => {
"use node"; "use node";
const nodemailer = await import("nodemailer");
let email; let email;
try { try {
@@ -26,16 +26,22 @@ export const enviar = action({
} }
// Buscar configuração SMTP ativa // Buscar configuração SMTP ativa
const configRaw = await ctx.runQuery(internal.email.getActiveEmailConfig, {}); const configRaw = await ctx.runQuery(
internal.email.getActiveEmailConfig,
{}
);
if (!configRaw) { if (!configRaw) {
console.error("❌ Configuração SMTP não encontrada ou inativa para email:", email.destinatario); console.error(
"❌ Configuração SMTP não encontrada ou inativa para email:",
email.destinatario
);
return { return {
sucesso: false, sucesso: false,
erro: "Configuração de email não encontrada ou inativa. Verifique as configurações SMTP no painel de TI.", erro: "Configuração de email não encontrada ou inativa. Verifique as configurações SMTP no painel de TI.",
}; };
} }
console.log("📧 Tentando enviar email:", { console.log("📧 Tentando enviar email:", {
para: email.destinatario, para: email.destinatario,
assunto: email.assunto, assunto: email.assunto,
@@ -46,10 +52,18 @@ export const enviar = action({
// Descriptografar senha usando função compatível com Node.js // Descriptografar senha usando função compatível com Node.js
let senhaDescriptografada: string; let senhaDescriptografada: string;
try { try {
senhaDescriptografada = await decryptSMTPPasswordNode(configRaw.senhaHash); senhaDescriptografada = await decryptSMTPPasswordNode(
configRaw.senhaHash
);
} catch (decryptError) { } catch (decryptError) {
const decryptErrorMessage = decryptError instanceof Error ? decryptError.message : String(decryptError); const decryptErrorMessage =
console.error("Erro ao descriptografar senha SMTP:", decryptErrorMessage); decryptError instanceof Error
? decryptError.message
: String(decryptError);
console.error(
"Erro ao descriptografar senha SMTP:",
decryptErrorMessage
);
return { return {
sucesso: false, sucesso: false,
erro: `Erro ao descriptografar senha SMTP: ${decryptErrorMessage}`, erro: `Erro ao descriptografar senha SMTP: ${decryptErrorMessage}`,
@@ -65,7 +79,9 @@ export const enviar = action({
// Avisar mas não bloquear se não foi testado // Avisar mas não bloquear se não foi testado
if (!config.testadoEm) { if (!config.testadoEm) {
console.warn("⚠️ Configuração SMTP não foi testada. Tentando enviar mesmo assim..."); console.warn(
"⚠️ Configuração SMTP não foi testada. Tentando enviar mesmo assim..."
);
} }
// Marcar como enviando // Marcar como enviando
@@ -128,8 +144,14 @@ export const enviar = action({
await transporter.verify(); await transporter.verify();
console.log("✅ Conexão SMTP verificada com sucesso"); console.log("✅ Conexão SMTP verificada com sucesso");
} catch (verifyError) { } catch (verifyError) {
const verifyErrorMessage = verifyError instanceof Error ? verifyError.message : String(verifyError); const verifyErrorMessage =
console.warn("⚠️ Falha na verificação SMTP, mas tentando enviar mesmo assim:", verifyErrorMessage); verifyError instanceof Error
? verifyError.message
: String(verifyError);
console.warn(
"⚠️ Falha na verificação SMTP, mas tentando enviar mesmo assim:",
verifyErrorMessage
);
// Não bloquear envio por falha na verificação, apenas avisar // Não bloquear envio por falha na verificação, apenas avisar
} }
@@ -184,9 +206,10 @@ export const enviar = action({
return { sucesso: true }; return { sucesso: true };
} catch (error) { } catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error); const errorMessage =
error instanceof Error ? error.message : String(error);
const errorStack = error instanceof Error ? error.stack : undefined; const errorStack = error instanceof Error ? error.stack : undefined;
console.error("❌ Erro ao enviar email:", { console.error("❌ Erro ao enviar email:", {
emailId: args.emailId, emailId: args.emailId,
destinatario: email?.destinatario, destinatario: email?.destinatario,
@@ -195,8 +218,8 @@ export const enviar = action({
}); });
// Marcar como falha com detalhes completos // Marcar como falha com detalhes completos
const erroCompleto = errorStack const erroCompleto = errorStack
? `${errorMessage}\n\nStack: ${errorStack}` ? `${errorMessage}\n\nStack: ${errorStack}`
: errorMessage; : errorMessage;
await ctx.runMutation(internal.email.markEmailFalha, { await ctx.runMutation(internal.email.markEmailFalha, {
@@ -208,5 +231,3 @@ export const enviar = action({
} }
}, },
}); });

View File

@@ -371,6 +371,17 @@ export const update = mutation({
} }
} }
const usuarioExists = await ctx.db
.query("usuarios")
.withIndex("by_funcionarioId", (q) => q.eq("funcionarioId", args.id))
.unique();
if (usuarioExists && usuarioExists.email !== args.email) {
await ctx.db.patch(usuarioExists._id, {
email: args.email,
});
}
const { id, ...updateData } = args; const { id, ...updateData } = args;
await ctx.db.patch(id, updateData); await ctx.db.patch(id, updateData);
return null; return null;