initial project setup
Fastify + Prisma backend, React + Vite frontend, Docker deployment. Multi-board feedback platform with anonymous cookie auth, passkey upgrade path, ALTCHA spam protection, plugin system, and full privacy-first architecture.
This commit is contained in:
60
packages/api/src/cron/index.ts
Normal file
60
packages/api/src/cron/index.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import cron from "node-cron";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { config } from "../config.js";
|
||||
import { cleanExpiredChallenges } from "../routes/passkey.js";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
export function startCronJobs() {
|
||||
// prune old activity events - daily at 3am
|
||||
cron.schedule("0 3 * * *", async () => {
|
||||
const cutoff = new Date();
|
||||
cutoff.setDate(cutoff.getDate() - config.DATA_RETENTION_ACTIVITY_DAYS);
|
||||
|
||||
const result = await prisma.activityEvent.deleteMany({
|
||||
where: { createdAt: { lt: cutoff } },
|
||||
});
|
||||
if (result.count > 0) {
|
||||
console.log(`Pruned ${result.count} old activity events`);
|
||||
}
|
||||
});
|
||||
|
||||
// prune orphaned anonymous users - daily at 4am
|
||||
cron.schedule("0 4 * * *", async () => {
|
||||
const cutoff = new Date();
|
||||
cutoff.setDate(cutoff.getDate() - config.DATA_RETENTION_ORPHAN_USER_DAYS);
|
||||
|
||||
const result = await prisma.user.deleteMany({
|
||||
where: {
|
||||
authMethod: "COOKIE",
|
||||
createdAt: { lt: cutoff },
|
||||
posts: { none: {} },
|
||||
comments: { none: {} },
|
||||
votes: { none: {} },
|
||||
},
|
||||
});
|
||||
if (result.count > 0) {
|
||||
console.log(`Pruned ${result.count} orphaned users`);
|
||||
}
|
||||
});
|
||||
|
||||
// clean webauthn challenges - every 10 minutes
|
||||
cron.schedule("*/10 * * * *", () => {
|
||||
cleanExpiredChallenges();
|
||||
});
|
||||
|
||||
// remove failed push subscriptions - daily at 5am
|
||||
cron.schedule("0 5 * * *", async () => {
|
||||
// subscriptions with no associated user get cleaned by cascade
|
||||
// this handles any other stale ones
|
||||
const cutoff = new Date();
|
||||
cutoff.setDate(cutoff.getDate() - 30);
|
||||
|
||||
const result = await prisma.pushSubscription.deleteMany({
|
||||
where: { createdAt: { lt: cutoff } },
|
||||
});
|
||||
if (result.count > 0) {
|
||||
console.log(`Cleaned ${result.count} old push subscriptions`);
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user