feat(email): route all email sends through Cloudflare Queue

Introduces a CF Queue binding (kk-email-queue) to decouple email
delivery from request handlers, preventing slow responses and
providing automatic retries. All send*Email calls now go through
the queue when the binding is available, with direct-send fallbacks
for local dev. Reminder fan-outs mark DB rows optimistically before
enqueueing to prevent re-enqueue on subsequent cron ticks.
This commit is contained in:
2026-03-11 17:13:35 +01:00
parent 7f431c0091
commit e5d2b13b21
12 changed files with 524 additions and 106 deletions

View File

@@ -1,13 +1,33 @@
import { auth } from "@kk/auth";
import { env } from "@kk/env/server";
import type { EmailMessage } from "./email-queue";
export async function createContext({ req }: { req: Request }) {
// CF Workers runtime Queue type (not the alchemy resource type)
type Queue = {
send(
message: EmailMessage,
options?: { contentType?: string },
): Promise<void>;
sendBatch(
messages: Array<{ body: EmailMessage }>,
options?: { contentType?: string },
): Promise<void>;
};
export async function createContext({
req,
emailQueue,
}: {
req: Request;
emailQueue?: Queue;
}) {
const session = await auth.api.getSession({
headers: req.headers,
});
return {
session,
env,
emailQueue,
};
}