fix(db): give the anomaly-alert dedup claims their own alert_dedup_claims table - #8985
Conversation
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
…aims table runAnomalyAlerts in src/review/alerts.ts writes per-hour dedup claims shaped (id, project, target_id, notification_key, status) with ON CONFLICT(project, target_id, notification_key) DO NOTHING, but pointed those raw INSERTs at notification_deliveries -- the migrated badge read-model (0031), whose columns are dedup_key/channel/recipient_login/... with a UNIQUE(dedup_key, channel) index. None of the claim columns nor the ON CONFLICT target exist there. runAnomalyAlerts has no callers yet, so this hasn't fired, but the moment it is wired to a cron path every Discord-notify invocation throws at the first INSERT. Add migration 0181 creating a distinctly-named alert_dedup_claims table with the (project, target_id, notification_key) unique index the port actually needs, and point both claim inserts at it. Allowlist the table in check-schema-drift as a raw-SQL-only feature table (alerts.ts accesses it via env.DB.prepare, not Drizzle). A new test drives runAnomalyAlerts against the real migrated D1 (createTestEnv) and asserts both claims land in alert_dedup_claims and a same-hour repeat is throttled by the unique constraint -- proving the write path no longer collides. Closes JSONbored#8901
5cccc75 to
0e85040
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8985 +/- ##
==========================================
+ Coverage 90.56% 93.88% +3.32%
==========================================
Files 96 807 +711
Lines 22490 80485 +57995
Branches 3884 24408 +20524
==========================================
+ Hits 20367 75561 +55194
- Misses 1945 3560 +1615
- Partials 178 1364 +1186
Flags with carried forward coverage won't be shown. Click here to find out more.
|
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-26 15:51:01 UTC
Review summary Nits — 3 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
Two PRs merged within 18 minutes of each other and both grabbed migration number 0181 (0181_alert_dedup_claims.sql from #8985, 0181_decision_replay_inputs.sql from #9014), breaking db:migrations:check on main for every subsequent PR. Renumbers the later-merged file (decision_replay_inputs) to 0182, the next free number. No code or test references either file by name/number, so this is a pure rename.
fix(db): give the anomaly-alert dedup claims their own alert_dedup_claims table
runAnomalyAlerts in src/review/alerts.ts writes per-hour dedup claims shaped
(id, project, target_id, notification_key, status) with
ON CONFLICT(project, target_id, notification_key) DO NOTHING, but pointed those
raw INSERTs at notification_deliveries -- the migrated badge read-model (0031),
whose columns are dedup_key/channel/recipient_login/... with a UNIQUE(dedup_key,
channel) index. None of the claim columns nor the ON CONFLICT target exist there.
runAnomalyAlerts has no callers yet, so this hasn't fired, but the moment it is
wired to a cron path every Discord-notify invocation throws at the first INSERT.
Add migration 0181 creating a distinctly-named alert_dedup_claims table with the
(project, target_id, notification_key) unique index the port actually needs, and
point both claim inserts at it. Allowlist the table in check-schema-drift as a
raw-SQL-only feature table (alerts.ts accesses it via env.DB.prepare, not Drizzle).
A new test drives runAnomalyAlerts against the real migrated D1 (createTestEnv)
and asserts both claims land in alert_dedup_claims and a same-hour repeat is
throttled by the unique constraint -- proving the write path no longer collides.
Closes #8901
Validation
Verified locally on this branch before opening:
npm run typechecknpx turbo run build:tsc build:verifynpm run test:coverage— patch coverage 100.0% of changed lines