diff --git a/apps/web/src/routes/(dashboard)/ti/notificacoes/+page.svelte b/apps/web/src/routes/(dashboard)/ti/notificacoes/+page.svelte index 78a5641..fda4550 100644 --- a/apps/web/src/routes/(dashboard)/ti/notificacoes/+page.svelte +++ b/apps/web/src/routes/(dashboard)/ti/notificacoes/+page.svelte @@ -52,14 +52,15 @@ // Mapa de emailIds para rastrear status let emailIdsRastreados = $state>(new Set()); - // Query para buscar status dos emails + // Query para buscar status dos emails (só executa quando há IDs) const emailIdsArray = $derived( Array.from(emailIdsRastreados).map((id) => id as Id<"notificacoesEmail">), ); - const emailsStatusQuery = useQuery( - api.email.buscarEmailsPorIds, - emailIdsArray.length > 0 ? { emailIds: emailIdsArray } : undefined, - ); + // Usar função para evitar execução quando array está vazio + const emailsStatusQuery = $derived.by(() => { + if (emailIdsArray.length === 0) return null; + return useQuery(api.email.buscarEmailsPorIds, { emailIds: emailIdsArray }); + }); // Queries para agendamentos const agendamentosEmailQuery = useQuery( diff --git a/packages/backend/convex/chat.ts b/packages/backend/convex/chat.ts index b2f024d..fa1708f 100644 --- a/packages/backend/convex/chat.ts +++ b/packages/backend/convex/chat.ts @@ -440,7 +440,12 @@ export const enviarMensagem = mutation({ const usuarioParticipante = await ctx.db.get(participanteId); if (usuarioParticipante?.email) { // 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, { destinatario: usuarioParticipante.email, diff --git a/packages/backend/convex/email.ts b/packages/backend/convex/email.ts index 6e29450..a55fa32 100644 --- a/packages/backend/convex/email.ts +++ b/packages/backend/convex/email.ts @@ -173,6 +173,12 @@ export const enviarEmailComTemplate = action({ // Renderizar template com variáveis 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 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) ========== /**