feat: add BullMQ job queue with admin monitoring UI
All checks were successful
Build and Push Backend Image / build (push) Successful in 48s
Build and Push Buttplug Image / build (push) Successful in 3m26s
Build and Push Frontend Image / build (push) Successful in 1m11s

- Add BullMQ to backend; mail jobs (verification, password reset) now enqueued instead of sent inline
- Mail worker processes jobs with 3-attempt exponential backoff retry
- Admin GraphQL resolvers: adminQueues, adminQueueJobs, adminRetryJob, adminRemoveJob, adminPauseQueue, adminResumeQueue
- Admin frontend page at /admin/queues: queue cards with counts, job table with status filter, retry/remove/pause actions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-08 18:25:09 +01:00
parent 6dcdc0130b
commit ea23233645
16 changed files with 927 additions and 6 deletions

View File

@@ -0,0 +1,28 @@
import { Worker } from "bullmq";
import { redisConnectionOpts } from "../connection.js";
import { sendVerification, sendPasswordReset } from "../../lib/email.js";
export function startMailWorker(): Worker {
const worker = new Worker(
"mail",
async (job) => {
switch (job.name) {
case "sendVerification":
await sendVerification(job.data.email as string, job.data.token as string);
break;
case "sendPasswordReset":
await sendPasswordReset(job.data.email as string, job.data.token as string);
break;
default:
throw new Error(`Unknown mail job: ${job.name}`);
}
},
{ connection: redisConnectionOpts },
);
worker.on("failed", (job, err) => {
console.error(`Mail job ${job?.id} (${job?.name}) failed:`, err.message);
});
return worker;
}