Problem
packages/jobs/src/nrd-feed.ts lines 104–106:
for (const org of orgs) {
await scannerJob.trigger({ org_id: org.id });
}
On a Trigger.dev replay (manual re-run or runner crash after partial completion), this loop reruns from the top with no idempotency guard. Each replay fires a full new scannerJob batch for all orgs. The job also has no retry: { maxAttempts: 1 }.
Fix
Option A — add retry: { maxAttempts: 1 } since NRD feed reruns are harmless but wasteful.
Option B — pass idempotencyKey: ${date}-${org.id}`` to each scannerJob.trigger call so Trigger.dev deduplicates retriggers for the same date/org pair.
Bonus gap
The NRD-matched domain strings (matched array) are computed but never forwarded to scannerJob. The scanner runs a fresh DuckDuckGo search regardless — the NRD feed's value (targeted notification about freshly registered suspicious domains) is silently discarded. Add domains?: string[] to ScannerJobPayload and forward matched.
Problem
packages/jobs/src/nrd-feed.tslines 104–106:On a Trigger.dev replay (manual re-run or runner crash after partial completion), this loop reruns from the top with no idempotency guard. Each replay fires a full new
scannerJobbatch for all orgs. The job also has noretry: { maxAttempts: 1 }.Fix
Option A — add
retry: { maxAttempts: 1 }since NRD feed reruns are harmless but wasteful.Option B — pass
idempotencyKey:${date}-${org.id}`` to eachscannerJob.triggercall so Trigger.dev deduplicates retriggers for the same date/org pair.Bonus gap
The NRD-matched domain strings (
matchedarray) are computed but never forwarded toscannerJob. The scanner runs a fresh DuckDuckGo search regardless — the NRD feed's value (targeted notification about freshly registered suspicious domains) is silently discarded. Adddomains?: string[]toScannerJobPayloadand forwardmatched.