- Add job queue abstraction (InMemoryQueue and Redis/BullMQ adapter) - Add polling worker with retry logic and exponential backoff - Add 6 job handlers: darkwatch.scan, voiceprint.batch, hometitle.scan, removebrokers.process, reports.generate, notifications.send - Add cron-based scheduler with tier-appropriate frequencies (Basic/Plus/Premium) - Add tRPC scheduler router for admin (runJobNow, getJobStatus, etc.) - Add entry point with graceful shutdown support - Achieve 100% test pass rate for new job system
39 lines
1.1 KiB
TypeScript
39 lines
1.1 KiB
TypeScript
import { eq, and } from "drizzle-orm";
|
|
import { db } from "~/server/db";
|
|
import { watchlistItems, subscriptions } from "~/server/db/schema";
|
|
import { runScan } from "~/server/services/darkwatch.service";
|
|
|
|
interface DarkWatchScanPayload {
|
|
userId: string;
|
|
subscriptionId: string;
|
|
}
|
|
|
|
export async function handler(payload: DarkWatchScanPayload): Promise<void> {
|
|
const { userId, subscriptionId } = payload;
|
|
|
|
const sub = await db
|
|
.select()
|
|
.from(subscriptions)
|
|
.where(and(eq(subscriptions.id, subscriptionId), eq(subscriptions.status, "active")))
|
|
.limit(1)
|
|
.then((r) => r[0]);
|
|
|
|
if (!sub) {
|
|
console.warn(`[darkwatch.scan] Subscription ${subscriptionId} not found or inactive, skipping`);
|
|
return;
|
|
}
|
|
|
|
const items = await db
|
|
.select()
|
|
.from(watchlistItems)
|
|
.where(and(eq(watchlistItems.subscriptionId, subscriptionId), eq(watchlistItems.isActive, true)));
|
|
|
|
if (items.length === 0) {
|
|
console.log(`[darkwatch.scan] No active watchlist items for subscription ${subscriptionId}`);
|
|
return;
|
|
}
|
|
|
|
await runScan(userId);
|
|
console.log(`[darkwatch.scan] Completed scan for subscription ${subscriptionId}`);
|
|
}
|