Skip to content

feat(email): weekly-digest once-per-week guard + deploy success emails - #75

Merged
mastermanas805 merged 1 commit into
masterfrom
fix/deploy-emails-and-weekly-digest-cadence
Jun 2, 2026
Merged

feat(email): weekly-digest once-per-week guard + deploy success emails#75
mastermanas805 merged 1 commit into
masterfrom
fix/deploy-emails-and-weekly-digest-cadence

Conversation

@mastermanas805

Copy link
Copy Markdown
Member

Two fixes, both verified against the prod audit_log (not just code).

1. Weekly digest fired daily, not weekly

Prod ledger showed digest.weekly rows 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 to master, 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 EXISTS guard excluding any team with a digest.weekly row inside weeklyDigestDedupeWindow ("6 days") — the "dedupe lives in the DB" pattern from expiry_reminder.go / quota_wall_nudge.go. Cadence is now correct regardless of how often River fires.

2. No email on deployment

api writes deploy.created + deploy.healthy audit 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 + eventEmailBodyRenderers with 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 adds app_url/app_name/env to the deploy.healthy audit 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.
  • Existing registry-iterating tests now validate the new kinds.

Verification status

Local: build + vet clean, internal/jobs package green. Not yet verified live — and transactional email is still blocked in prod by the unvalidated Brevo sender (project_brevo_sender_not_validated) until noreply@instanode.dev is validated.

🤖 Generated with Claude Code

…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>
@mastermanas805
mastermanas805 merged commit 113264a into master Jun 2, 2026
11 checks passed
@mastermanas805
mastermanas805 deleted the fix/deploy-emails-and-weekly-digest-cadence branch June 2, 2026 13:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant