Conversation
|
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.
What changed
Two confirmed production bugs on main, one commit each. Host announcements now record who they reached: before, recording the outcome of a batch failed whenever its first delivery had gone out, so counts stayed at zero and a later retry could send the same announcement again. And three regexes in bounce-mail parsing now run in linear time: before, one crafted email could block the API for tens of seconds.
Before you start
Verify
Announcements reach attendees once, and the host sees the count — [Web] [Mobile]
Regression
Opening an announcement — [Web] [Mobile]
Findings addressed
Announcement outcomes (critical). The delivery pipeline passes each outcome's sent time as a JavaScript date. postgres.js types an array parameter by its first element, so a list that starts with a date is sent as a single timestamp, and Postgres rejects the cast to an array (error 42846). Every batch whose first delivery succeeded failed after the notifications and emails had already gone out. The deliveries stayed "sending", the counts never refreshed, and the stale-sending sweep re-queued the batch, which could re-claim and re-send those deliveries up to 3 times once they were 10 minutes old. Present since the host platform landed (2026-09-06). Reproduced locally on an in-process Postgres (PGlite) with the real repository code: main fails with 42846, and this branch records every outcome.
Bounce parsing stalls (critical, security). Mail handling runs in the API process. Three regexes in bounce detection were quadratic on long runs:
Anyone who can send mail to the reply domain could stall every request. Measured on main: 6.3 s per field at 64 KiB, and 13.3 s for one crafted message through the real mail parser. After: under 2 ms each, and 4 ms at 512 KiB.
Decisions for the reviewer
User-visible copy changes
None.
Tests changed
host-broadcast-outcomes-bindingunit test: the outcome update binds strings, never dates (fails on main).host-broadcast-outcomes-pgintegration test: applies a batch whose first delivery was sent, and one where all were sent, against the real schema (runs in CI).inbound-bounce-linear-timeunit test: the three stall shapes and one end-to-end message through the real parser, each under 500 ms (on main they take 6 to 13 s), plus first-match checks.Verification
Staging checks
https://api.civfix.dev/readyzanswers ready (no migration).Not covered
🤖 Generated with Claude Code