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:
2025-10-31 13:39:41 -03:00
parent 5dec7d7da7
commit 5cb63f9437
20 changed files with 155 additions and 112 deletions

View File

@@ -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,
});