feat: improve email status querying and URL handling
- Updated email status query to execute only when there are email IDs, enhancing performance. - Ensured URL handling in email sending functions always includes a protocol, improving reliability. - Added new queries for fetching emails by IDs and listing scheduled emails, enriching email management capabilities.
This commit is contained in:
@@ -52,14 +52,15 @@
|
|||||||
// Mapa de emailIds para rastrear status
|
// Mapa de emailIds para rastrear status
|
||||||
let emailIdsRastreados = $state<Set<string>>(new Set());
|
let emailIdsRastreados = $state<Set<string>>(new Set());
|
||||||
|
|
||||||
// Query para buscar status dos emails
|
// Query para buscar status dos emails (só executa quando há IDs)
|
||||||
const emailIdsArray = $derived(
|
const emailIdsArray = $derived(
|
||||||
Array.from(emailIdsRastreados).map((id) => id as Id<"notificacoesEmail">),
|
Array.from(emailIdsRastreados).map((id) => id as Id<"notificacoesEmail">),
|
||||||
);
|
);
|
||||||
const emailsStatusQuery = useQuery(
|
// Usar função para evitar execução quando array está vazio
|
||||||
api.email.buscarEmailsPorIds,
|
const emailsStatusQuery = $derived.by(() => {
|
||||||
emailIdsArray.length > 0 ? { emailIds: emailIdsArray } : undefined,
|
if (emailIdsArray.length === 0) return null;
|
||||||
);
|
return useQuery(api.email.buscarEmailsPorIds, { emailIds: emailIdsArray });
|
||||||
|
});
|
||||||
|
|
||||||
// Queries para agendamentos
|
// Queries para agendamentos
|
||||||
const agendamentosEmailQuery = useQuery(
|
const agendamentosEmailQuery = useQuery(
|
||||||
|
|||||||
@@ -440,7 +440,12 @@ export const enviarMensagem = mutation({
|
|||||||
const usuarioParticipante = await ctx.db.get(participanteId);
|
const usuarioParticipante = await ctx.db.get(participanteId);
|
||||||
if (usuarioParticipante?.email) {
|
if (usuarioParticipante?.email) {
|
||||||
// Obter URL do sistema (padrão: localhost para dev)
|
// Obter URL do sistema (padrão: localhost para dev)
|
||||||
const urlSistema = process.env.FRONTEND_URL || "http://localhost:5173";
|
let urlSistema = process.env.FRONTEND_URL || "http://localhost:5173";
|
||||||
|
|
||||||
|
// Garantir que a URL sempre tenha protocolo
|
||||||
|
if (!urlSistema.match(/^https?:\/\//i)) {
|
||||||
|
urlSistema = `http://${urlSistema}`;
|
||||||
|
}
|
||||||
|
|
||||||
ctx.scheduler.runAfter(1000, api.email.enviarEmailComTemplate, {
|
ctx.scheduler.runAfter(1000, api.email.enviarEmailComTemplate, {
|
||||||
destinatario: usuarioParticipante.email,
|
destinatario: usuarioParticipante.email,
|
||||||
|
|||||||
@@ -173,6 +173,12 @@ export const enviarEmailComTemplate = action({
|
|||||||
|
|
||||||
// Renderizar template com variáveis
|
// Renderizar template com variáveis
|
||||||
const variaveisTemplate = args.variaveis || {};
|
const variaveisTemplate = args.variaveis || {};
|
||||||
|
|
||||||
|
// Garantir que urlSistema sempre tenha protocolo se presente
|
||||||
|
if (variaveisTemplate.urlSistema && !variaveisTemplate.urlSistema.match(/^https?:\/\//i)) {
|
||||||
|
variaveisTemplate.urlSistema = `http://${variaveisTemplate.urlSistema}`;
|
||||||
|
}
|
||||||
|
|
||||||
const tituloRenderizado = renderizarTemplate(template.titulo, variaveisTemplate);
|
const tituloRenderizado = renderizarTemplate(template.titulo, variaveisTemplate);
|
||||||
const corpoRenderizado = renderizarTemplate(template.corpo, variaveisTemplate);
|
const corpoRenderizado = renderizarTemplate(template.corpo, variaveisTemplate);
|
||||||
|
|
||||||
@@ -327,6 +333,68 @@ export const obterEstatisticasFilaEmails = query({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buscar emails por IDs (para monitoramento de status)
|
||||||
|
*/
|
||||||
|
export const buscarEmailsPorIds = query({
|
||||||
|
args: {
|
||||||
|
emailIds: v.array(v.id("notificacoesEmail")),
|
||||||
|
},
|
||||||
|
handler: async (ctx, args) => {
|
||||||
|
const emails = [];
|
||||||
|
for (const emailId of args.emailIds) {
|
||||||
|
const email = await ctx.db.get(emailId);
|
||||||
|
if (email) {
|
||||||
|
emails.push(email);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return emails;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listar agendamentos de email (emails com agendadaPara definido)
|
||||||
|
*/
|
||||||
|
export const listarAgendamentosEmail = query({
|
||||||
|
args: {},
|
||||||
|
handler: async (ctx) => {
|
||||||
|
// Buscar todos os emails agendados (pendentes ou enviando)
|
||||||
|
const emailsAgendados = await ctx.db
|
||||||
|
.query("notificacoesEmail")
|
||||||
|
.filter((q) => {
|
||||||
|
const temAgendamento = q.neq(q.field("agendadaPara"), undefined);
|
||||||
|
const statusValido = q.or(
|
||||||
|
q.eq(q.field("status"), "pendente"),
|
||||||
|
q.eq(q.field("status"), "enviando")
|
||||||
|
);
|
||||||
|
return q.and(temAgendamento, statusValido);
|
||||||
|
})
|
||||||
|
.order("asc")
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Enriquecer com informações de destinatário e template
|
||||||
|
const emailsEnriquecidos = await Promise.all(
|
||||||
|
emailsAgendados.map(async (email) => {
|
||||||
|
const destinatarioInfo = email.destinatarioId
|
||||||
|
? await ctx.db.get(email.destinatarioId)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const templateInfo = email.templateId
|
||||||
|
? await ctx.db.get(email.templateId)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...email,
|
||||||
|
destinatarioInfo,
|
||||||
|
templateInfo,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return emailsEnriquecidos;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// ========== PUBLIC MUTATIONS (MANUAL) ==========
|
// ========== PUBLIC MUTATIONS (MANUAL) ==========
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user