Repository navigation
fix(alerts): 500s on manual broadcast + geo dedupe; add admin edit/clear/delete routes - #20
Merged
Merged
Conversation
…ear/delete routes - insertAlert: manual issue now uses ON CONFLICT DO NOTHING like the geo path. Catching the unique violation and then querying ran inside an aborted Postgres transaction (25P02), turning the intended 409 into a 500. - insertAlert: detect a skipped row by the id itself. TypeORM 0.3 pushes one identifier entry per value set even when RETURNING yields nothing, so `identifiers.length === 0` never fired and `identifiers[0].id` threw — this also 500'd geo hazard-score reports that hit an existing active alert. - IssueAlertDto: windowStart/windowEnd are @IsDateString (400, not a 500 from an invalid timestamp); accept free-text estimatedWindow used by the dashboard. - Add PUT/PATCH/DELETE /admin/alerts/:id (edit, clear, delete) that the web dashboard calls; they were lost when the dashboard dropped its own DB access (cryohealth 20da49a). Clear/delete require an audited reason; delete 409s with dependents when CHWs have acknowledged the alert. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 of 3 tasks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Broadcasting an alert from the admin portal failed with a generic "Failed to broadcast alert", and deleting an alert returned 404. Three API bugs plus missing routes:
windowStart;new Date()produced an Invalid Date and Postgres rejected it.windowStart/windowEndare now@IsDateString(400 instead of 500), andIssueAlertDtoaccepts free-textestimatedWindow, which the dashboard displays everywhere.insertAlertcaught the unique violation and then queried the existing alert inside the now-aborted transaction (25P02). The manual path now usesON CONFLICT DO NOTHING, the same as the geo path.identifiersentry per value set even whenRETURNINGyields no row, soidentifiers.length === 0never fired andidentifiers[0].idthrew. We now check the id itself. This affectedPOST /alerts/hazard-scoreswhenever a lake returned to a tier that still had an active alert.PUT/PATCH/DELETE /admin/alerts/:id. The dashboard calls these routes. They were lost when the dashboard dropped its own DB access (uExel/cryohealth20da49a). This ports that logic: edit (body/tier/window, audited diff), clear (reason required), and delete (reason required; 409 withdependentsif CHWs acknowledged the alert).Companion dashboard PR: uExel/cryohealth
fix/broadcast-alert-form. Either repo can deploy first:whitelist: truewithoutforbidNonWhitelistedmeans an older API silently dropsestimatedWindow.Not changed (policy, flagged for discussion)
currentTier. Shishper currently showswatchbecause of the manual "test" alert, while geo has an active CRITICAL.Test plan
npm test: 45/45 pass. The two updated dedupe tests fail on the old code and pass on the new.tsc --noEmitandeslint src/alertsclean🤖 Generated with Claude Code