Initial commit
This commit is contained in:
commit
38c24fc9dc
166 files changed
+22002
No files matched your search
@@ -0,0 +1,41 @@
|
||||
import { and, eq, lt } from 'drizzle-orm'
|
||||
import { db } from '../../db/client.js'
|
||||
import { notifications, topics } from '../../db/schema.js'
|
||||
import { resolveRetentionDefaultDays } from '../admin/system-settings.js'
|
||||
|
||||
const CLEANUP_INTERVAL_MS = 60 * 60 * 1000 // 1 hour
|
||||
|
||||
// Per-topic retentionDays overrides the global default; 0 means "forever".
|
||||
// See docs/phase1/03-database-model.md, "Retention cleanup".
|
||||
export async function runRetentionCleanup(): Promise<number> {
|
||||
const topicRows = await db.select().from(topics)
|
||||
const retentionDefaultDays = await resolveRetentionDefaultDays()
|
||||
let totalDeleted = 0
|
||||
|
||||
for (const topic of topicRows) {
|
||||
const retentionDays = topic.retentionDays ?? retentionDefaultDays
|
||||
if (retentionDays === 0) continue
|
||||
|
||||
const cutoff = new Date(Date.now() - retentionDays * 24 * 60 * 60 * 1000)
|
||||
const deleted = await db
|
||||
.delete(notifications)
|
||||
.where(and(eq(notifications.topicId, topic.id), lt(notifications.createdAt, cutoff)))
|
||||
.returning({ id: notifications.id })
|
||||
|
||||
totalDeleted += deleted.length
|
||||
}
|
||||
|
||||
return totalDeleted
|
||||
}
|
||||
|
||||
export function startRetentionCleanupJob(
|
||||
onError: (err: unknown) => void = console.error,
|
||||
): NodeJS.Timeout {
|
||||
const run = () => {
|
||||
runRetentionCleanup().catch(onError)
|
||||
}
|
||||
run() // catch up on anything overdue from before this boot
|
||||
const timer = setInterval(run, CLEANUP_INTERVAL_MS)
|
||||
timer.unref() // never block process shutdown just to keep this alive
|
||||
return timer
|
||||
}
|
||||
Reference in new issue
Block a user