feat(marketing-pages): sendWelcomeEmail job + handler enqueues it

sendWelcomeEmailJob takes IMailerService, validates the typed input
(userId + email), and delegates to mailer.sendWelcome. The
onAuthUserSignedUpHandler now takes IJobQueue and enqueues
"marketing-pages.send-welcome-email" with the event payload.

Both binders bind a RecordingMailerService at the IMailerService
symbol (production placeholder until a real adapter ships) and pass
mailer / queue into the wrapped factories. Dev-seed additionally
queue.register()s the slug so the in-memory queue dispatches via
the wrapped job; production relies on the generated Payload event-task
to resolve the wrapped handler from the container.
This commit is contained in:
2026-05-08 16:35:45 +02:00
parent 6b57a34c0c
commit 7e844c646d
9 changed files with 177 additions and 22 deletions

View File

@@ -1,4 +1,5 @@
export { pages } from "./collections/pages";
export { siteSettings } from "./globals/site-settings";
// <gen:job-tasks>
export { sendWelcomeEmailTask } from "./jobs/send-welcome-email.task";
export { onAuthUserSignedUpEventTask } from "./jobs/__events-auth-user-signed-up.task";

View File

@@ -0,0 +1,18 @@
// packages/marketing-pages/src/integrations/cms/jobs/send-welcome-email.task.ts
import type { TaskConfig } from "payload";
import { marketingPagesContainer } from "../../../di/container";
import { MARKETING_PAGES_SYMBOLS } from "../../../di/symbols";
import type { ISendWelcomeEmailJob } from "../../../jobs/send-welcome-email.job";
export const sendWelcomeEmailTask: TaskConfig<"marketing-pages.send-welcome-email"> = {
slug: "marketing-pages.send-welcome-email",
inputSchema: [],
retries: { attempts: 3, backoff: { type: "exponential", delay: 1000 } },
handler: async ({ input }) => {
const job = marketingPagesContainer.get<ISendWelcomeEmailJob>(
MARKETING_PAGES_SYMBOLS.ISendWelcomeEmailJob,
);
await job(input as never);
return { output: {} };
},
};