diff --git a/src/worker/index.ts b/src/worker/index.ts index a088d7f..5c90dfb 100644 --- a/src/worker/index.ts +++ b/src/worker/index.ts @@ -304,6 +304,23 @@ const maintenanceWorker = new Worker( console.log( `[maintenance] pruned snapshots — fund NAV: ${deletedFundNav.count} rows, user portfolio: ${deletedUserPortfolio.count} rows (>7d)`, ) + + // ── Related hashtag pruning ──────────────────────────────────────────── + // 1. Null-target records: the related hashtag was deleted (onDelete: SetNull) + // or was never tracked. Delete unconditionally — the upsert in the price + // worker will recreate them if the co-occurrence is seen again. + // 2. Weak associations: low co-occurrence records that were never reinforced, + // pruned after 30 days of inactivity. + const relatedCutoff = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000) + const [deletedNullTarget, deletedWeak] = await Promise.all([ + prisma.relatedHashtag.deleteMany({ where: { relatedId: null } }), + prisma.relatedHashtag.deleteMany({ + where: { relatedId: { not: null }, coOccurrences: { lt: 5 }, updatedAt: { lt: relatedCutoff } }, + }), + ]) + console.log( + `[maintenance] pruned relatedHashtag — ${deletedNullTarget.count} null-target, ${deletedWeak.count} weak (>30d, <5 co-occurrences)`, + ) }, { connection: redisOpts() }, )