feat: implement scheduling for notifications with enhanced validation
- Added functionality to schedule notifications for future delivery, including date and time selection in the UI. - Implemented validation to ensure scheduled times are in the future and correctly formatted. - Updated backend email handling to support scheduled sending, with appropriate checks for agendamentos. - Enhanced user feedback for both immediate and scheduled notifications, improving overall user experience.
This commit is contained in:
@@ -21,6 +21,7 @@ export const enfileirarEmail = mutation({
|
||||
corpo: v.string(),
|
||||
templateId: v.optional(v.id("templatesMensagens")),
|
||||
enviadoPorId: v.id("usuarios"),
|
||||
agendadaPara: v.optional(v.number()), // timestamp opcional para agendamento
|
||||
},
|
||||
returns: v.object({
|
||||
sucesso: v.boolean(),
|
||||
@@ -33,6 +34,13 @@ export const enfileirarEmail = mutation({
|
||||
return { sucesso: false };
|
||||
}
|
||||
|
||||
// Validar agendamento se fornecido
|
||||
if (args.agendadaPara !== undefined) {
|
||||
if (args.agendadaPara <= Date.now()) {
|
||||
return { sucesso: false };
|
||||
}
|
||||
}
|
||||
|
||||
// Adicionar à fila
|
||||
const emailId = await ctx.db.insert("notificacoesEmail", {
|
||||
destinatario: args.destinatario,
|
||||
@@ -44,12 +52,22 @@ export const enfileirarEmail = mutation({
|
||||
tentativas: 0,
|
||||
enviadoPor: args.enviadoPorId,
|
||||
criadoEm: Date.now(),
|
||||
agendadaPara: args.agendadaPara,
|
||||
});
|
||||
|
||||
// Agendar envio imediato via action
|
||||
await ctx.scheduler.runAfter(0, api.actions.email.enviar, {
|
||||
emailId,
|
||||
});
|
||||
// Agendar envio
|
||||
if (args.agendadaPara !== undefined) {
|
||||
// Agendar para o momento especificado
|
||||
const delayMs = args.agendadaPara - Date.now();
|
||||
await ctx.scheduler.runAfter(delayMs, api.actions.email.enviar, {
|
||||
emailId,
|
||||
});
|
||||
} else {
|
||||
// Envio imediato
|
||||
await ctx.scheduler.runAfter(0, api.actions.email.enviar, {
|
||||
emailId,
|
||||
});
|
||||
}
|
||||
|
||||
return { sucesso: true, emailId };
|
||||
},
|
||||
@@ -65,6 +83,7 @@ export const enviarEmailComTemplate = mutation({
|
||||
templateCodigo: v.string(),
|
||||
variaveis: v.record(v.string(), v.string()),
|
||||
enviadoPorId: v.id("usuarios"),
|
||||
agendadaPara: v.optional(v.number()), // timestamp opcional para agendamento
|
||||
},
|
||||
returns: v.object({
|
||||
sucesso: v.boolean(),
|
||||
@@ -82,6 +101,13 @@ export const enviarEmailComTemplate = mutation({
|
||||
return { sucesso: false };
|
||||
}
|
||||
|
||||
// Validar agendamento se fornecido
|
||||
if (args.agendadaPara !== undefined) {
|
||||
if (args.agendadaPara <= Date.now()) {
|
||||
return { sucesso: false };
|
||||
}
|
||||
}
|
||||
|
||||
// Renderizar template
|
||||
const assunto = renderizarTemplate(template.titulo, args.variaveis);
|
||||
const corpo = renderizarTemplate(template.corpo, args.variaveis);
|
||||
@@ -97,12 +123,22 @@ export const enviarEmailComTemplate = mutation({
|
||||
tentativas: 0,
|
||||
enviadoPor: args.enviadoPorId,
|
||||
criadoEm: Date.now(),
|
||||
agendadaPara: args.agendadaPara,
|
||||
});
|
||||
|
||||
// Agendar envio imediato via action
|
||||
await ctx.scheduler.runAfter(0, api.actions.email.enviar, {
|
||||
emailId,
|
||||
});
|
||||
// Agendar envio
|
||||
if (args.agendadaPara !== undefined) {
|
||||
// Agendar para o momento especificado
|
||||
const delayMs = args.agendadaPara - Date.now();
|
||||
await ctx.scheduler.runAfter(delayMs, api.actions.email.enviar, {
|
||||
emailId,
|
||||
});
|
||||
} else {
|
||||
// Envio imediato
|
||||
await ctx.scheduler.runAfter(0, api.actions.email.enviar, {
|
||||
emailId,
|
||||
});
|
||||
}
|
||||
|
||||
return { sucesso: true, emailId };
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user