feat(email): weekly-digest once-per-week guard + deploy success emails - #75
Merged
mastermanas805 merged 1 commit intoJun 2, 2026
Merged
Conversation
…ails Two fixes verified against the prod audit_log: 1. WeeklyDigestWorker fired DAILY, not weekly (digest.weekly rows on 2026-05-25/26/27/28). River's periodic schedule + UniqueOpts(7d) does not survive the worker's frequent auto-deploy restarts. Add a DB-level NOT EXISTS guard (the "dedupe lives in the DB" pattern) excluding teams that already got a digest in the last 6 days, so cadence is correct regardless of how often River fires. 2. deploy.created / deploy.healthy audit rows were written by the api but had NO email path — silently dropped by the forwarder. Wire both into supportedAuditKinds + eventEmailBuilders + eventEmailBodyRenderers with Go-rendered bodies: a "deployment started" email on create and a "your app is live at <url>" email on healthy. Co-Authored-By: Claude Opus 4.8 (1M context) <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.
Two fixes, both verified against the prod
audit_log(not just code).1. Weekly digest fired daily, not weekly
Prod ledger showed
digest.weeklyrows on 2026-05-25 / 26 / 27 / 28 — every non-anonymous team got the "weekly summary" four days in a row (reported by @mastermanas805).Root cause: the once-per-week guarantee lived only in River's periodic schedule (
mondayAt8UTCSchedule+UniqueOpts{ByPeriod: 7d}). The worker auto-deploys on every push tomaster, so it restarts often; River's catch-up enqueue on startup re-ran the sweep on consecutive days and the 7-day unique window did not hold across restarts.Fix: the candidate query now has a
NOT EXISTSguard excluding any team with adigest.weeklyrow insideweeklyDigestDedupeWindow("6 days") — the "dedupe lives in the DB" pattern fromexpiry_reminder.go/quota_wall_nudge.go. Cadence is now correct regardless of how often River fires.2. No email on deployment
apiwritesdeploy.created+deploy.healthyaudit rows on every deploy, but the email forwarder had no path for them — the rows landed and were silently dropped. (Same omission class as 49639e7 / W2.)Fix: registered both kinds in
supportedAuditKinds+eventEmailBuilders+eventEmailBodyRendererswith Go-rendered bodies — a "deployment started" email on create and a "your app is live at " email on healthy. Pairs with the api PR that addsapp_url/app_name/envto thedeploy.healthyaudit metadata.Tests
deploy_success_email_test.go— builders flow metadata, healthy renderer surfaces the live URL (+ dashboard fallback), created email never invents a URL, fail-soft on no recipient.weekly_digest_test.go— pins the once-per-week guard args on the candidate query.Verification status
Local: build + vet clean,
internal/jobspackage green. Not yet verified live — and transactional email is still blocked in prod by the unvalidated Brevo sender (project_brevo_sender_not_validated) untilnoreply@instanode.devis validated.🤖 Generated with Claude Code