Add campaign scheduling lifecycle jobs

This commit is contained in:
2026-06-05 21:38:34 +02:00
parent 3f148bcec2
commit 70951789d2
7 changed files with 384 additions and 0 deletions

View File

@@ -4,6 +4,8 @@ import { normalizeListLimit } from "./domain";
import { internalMutation, mutation, query } from "./_generated/server";
import type { MutationCtx, QueryCtx } from "./_generated/server";
export const AUDIT_REVIEW_NOTICE_AFTER_MS = 30 * 24 * 60 * 60 * 1000;
const auditStatus = v.union(
v.literal("draft"),
v.literal("approved"),
@@ -352,6 +354,9 @@ export const publishPublicAudit = mutation({
await ctx.db.patch(args.id, {
status: "published",
publishedAt: now,
reviewDueAt: now + AUDIT_REVIEW_NOTICE_AFTER_MS,
lifecycleNotificationAt: undefined,
lifecycleExtendedUntil: undefined,
deactivatedAt: undefined,
updatedAt: now,
});
@@ -373,6 +378,34 @@ export const reapprovePublicAudit = mutation({
await ctx.db.patch(args.id, {
status: "published",
publishedAt: now,
reviewDueAt: now + AUDIT_REVIEW_NOTICE_AFTER_MS,
lifecycleNotificationAt: undefined,
lifecycleExtendedUntil: undefined,
deactivatedAt: undefined,
updatedAt: now,
});
return { slug: audit.slug };
},
});
export const extendPublicAuditLifecycle = mutation({
args: {
id: v.id("audits"),
days: v.number(),
},
handler: async (ctx, args) => {
await requireOperator(ctx);
const audit = await ctx.db.get(args.id);
if (!audit) {
throw new Error("Audit wurde nicht gefunden.");
}
const now = Date.now();
await ctx.db.patch(args.id, {
status: "published",
lifecycleExtendedUntil: now + args.days * 24 * 60 * 60 * 1000,
reviewDueAt: now + args.days * 24 * 60 * 60 * 1000,
deactivatedAt: undefined,
updatedAt: now,
});