refactor: improve type safety and error handling in vacation management components
- Updated the `AprovarFerias.svelte` component to use specific types for `solicitacao` and `gestorId`, enhancing type safety. - Improved error handling by refining catch blocks to handle errors more accurately. - Made minor adjustments to ensure consistent code formatting and readability across the component.
This commit is contained in:
@@ -8,7 +8,7 @@ import {
|
||||
} from "./_generated/server";
|
||||
import { Id } from "./_generated/dataModel";
|
||||
import { renderizarTemplate } from "./templatesMensagens";
|
||||
import { internal } from "./_generated/api";
|
||||
import { internal, api } from "./_generated/api";
|
||||
|
||||
/**
|
||||
* Enfileirar email para envio
|
||||
@@ -58,7 +58,7 @@ export const enviarEmailComTemplate = mutation({
|
||||
destinatario: v.string(),
|
||||
destinatarioId: v.optional(v.id("usuarios")),
|
||||
templateCodigo: v.string(),
|
||||
variaveis: v.any(), // Record<string, string>
|
||||
variaveis: v.record(v.string(), v.string()),
|
||||
enviadoPorId: v.id("usuarios"),
|
||||
},
|
||||
returns: v.object({
|
||||
@@ -113,7 +113,7 @@ export const listarFilaEmails = query({
|
||||
),
|
||||
limite: v.optional(v.number()),
|
||||
},
|
||||
returns: v.array(v.any()),
|
||||
// Tipo inferido automaticamente pelo Convex
|
||||
handler: async (ctx, args) => {
|
||||
if (args.status) {
|
||||
const emails = await ctx.db
|
||||
@@ -166,7 +166,7 @@ export const reenviarEmail = mutation({
|
||||
*/
|
||||
export const getEmailById = internalQuery({
|
||||
args: { emailId: v.id("notificacoesEmail") },
|
||||
returns: v.union(v.any(), v.null()),
|
||||
// Tipo inferido automaticamente pelo Convex
|
||||
handler: async (ctx, args) => {
|
||||
return await ctx.db.get(args.emailId);
|
||||
},
|
||||
@@ -174,7 +174,7 @@ export const getEmailById = internalQuery({
|
||||
|
||||
export const getActiveEmailConfig = internalQuery({
|
||||
args: {},
|
||||
returns: v.union(v.any(), v.null()),
|
||||
// Tipo inferido automaticamente pelo Convex
|
||||
handler: async (ctx) => {
|
||||
return await ctx.db
|
||||
.query("configuracaoEmail")
|
||||
@@ -188,9 +188,10 @@ export const markEmailEnviando = internalMutation({
|
||||
returns: v.null(),
|
||||
handler: async (ctx, args) => {
|
||||
const email = await ctx.db.get(args.emailId);
|
||||
if (!email) return null;
|
||||
await ctx.db.patch(args.emailId, {
|
||||
status: "enviando",
|
||||
tentativas: ((email as any)?.tentativas || 0) + 1,
|
||||
tentativas: (email.tentativas || 0) + 1,
|
||||
ultimaTentativa: Date.now(),
|
||||
});
|
||||
return null;
|
||||
@@ -214,10 +215,11 @@ export const markEmailFalha = internalMutation({
|
||||
returns: v.null(),
|
||||
handler: async (ctx, args) => {
|
||||
const email = await ctx.db.get(args.emailId);
|
||||
if (!email) return null;
|
||||
await ctx.db.patch(args.emailId, {
|
||||
status: "falha",
|
||||
erroDetalhes: args.erro,
|
||||
tentativas: ((email as any)?.tentativas || 0) + 1,
|
||||
tentativas: (email.tentativas || 0) + 1,
|
||||
});
|
||||
return null;
|
||||
},
|
||||
@@ -270,12 +272,12 @@ export const enviarEmailAction = action({
|
||||
|
||||
// Criar transporter do nodemailer
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: (config as any).smtpHost,
|
||||
port: (config as any).smtpPort,
|
||||
secure: (config as any).smtpSecure,
|
||||
host: config.servidor,
|
||||
port: config.porta,
|
||||
secure: config.usarSSL,
|
||||
auth: {
|
||||
user: (config as any).smtpUser,
|
||||
pass: (config as any).smtpPassword,
|
||||
user: config.usuario,
|
||||
pass: config.senhaHash, // Note: em produção deve ser descriptografado
|
||||
},
|
||||
tls: {
|
||||
rejectUnauthorized: false,
|
||||
@@ -284,15 +286,15 @@ export const enviarEmailAction = action({
|
||||
|
||||
// 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,
|
||||
from: `"${config.nomeRemetente}" <${config.emailRemetente}>`,
|
||||
to: email.destinatario,
|
||||
subject: email.assunto,
|
||||
html: email.corpo,
|
||||
});
|
||||
|
||||
console.log("✅ Email enviado com sucesso!");
|
||||
console.log(" Para:", (email as any).destinatario);
|
||||
console.log(" Assunto:", (email as any).assunto);
|
||||
console.log(" Para:", email.destinatario);
|
||||
console.log(" Assunto:", email.assunto);
|
||||
console.log(" Message ID:", info.messageId);
|
||||
|
||||
// Marcar como enviado
|
||||
@@ -301,16 +303,18 @@ export const enviarEmailAction = action({
|
||||
});
|
||||
|
||||
return { sucesso: true };
|
||||
} catch (error: any) {
|
||||
console.error("❌ Erro ao enviar email:", error.message);
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : String(error);
|
||||
console.error("❌ Erro ao enviar email:", errorMessage);
|
||||
|
||||
// Marcar como falha
|
||||
await ctx.runMutation(internal.email.markEmailFalha, {
|
||||
emailId: args.emailId,
|
||||
erro: error.message || "Erro ao enviar email",
|
||||
erro: errorMessage,
|
||||
});
|
||||
|
||||
return { sucesso: false, erro: error.message || "Erro ao enviar email" };
|
||||
return { sucesso: false, erro: errorMessage };
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -342,7 +346,7 @@ export const processarFilaEmails = internalMutation({
|
||||
|
||||
// Agendar envio via action
|
||||
// IMPORTANTE: Não podemos chamar action diretamente de mutation
|
||||
// Por isso, usaremos o scheduler
|
||||
// Por isso, usaremos o scheduler com string path
|
||||
await ctx.scheduler.runAfter(0, "email:enviarEmailAction" as any, {
|
||||
emailId: email._id,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user