Repository navigation
feat(settings): AI tab and email preferences with a local send schedule - #1531
Merged
Merged
Maple Review Bot / Maple / review
succeeded
Oct 17, 2026 in 1m 21s
Confidence 7/10 · No issues found
🟢 Confidence 7/10 · likely safe to merge
The scheduling change moves every subscriber's digest time and is pinned by zone/DST tests, but the no-primary-email save path from F1 is still a silent no-op.
quality 98/100 · 1 note · tests covered · risk medium · 2/2 new units observable
Moves auto-triage onto the AI tab with provider cards and adds email preferences with a local day/hour/zone digest schedule (new send_hour column, backend-validated, isDigestDue + a 6-day claim window). Logic is well pinned by tests; the only open defect is the silent no-op save for a user with no primary email.
isDigestDuedecides sends on the subscriber's local day/hour/zone- Digest claims now guard on a 6-day resend cutoff, not UTC midnight
send_hourcolumn (default 9) plus day/hour/zone validation on upsert- Auto-triage limits move to the AI tab behind
SettingsSaveBar
Before merge
- Migration · Check it is safe on production data and with the code still deployed ·
packages/db/drizzle/20261017080931_digest_send_hour/migration.sql
Still open from earlier reviews
- 🔵 Note · F1 · Save is a silent no-op for a user with no primary email ·
apps/web/src/components/account/email-preferences-section.tsx:121
Production impact
Production traffic of the changed files (last 7 days)
| File | Calls/day | Busiest operations |
|---|---|---|
packages/backend/src/services/digest/WebAnalyticsDigestService.ts |
240 | WebAnalyticsDigestService.runTick 240/day, 0.0% err |
What was checked
- Digest tick queries use full-row selects, so
sendHourreachesisDigestDue(DigestService.ts:1047, WebAnalyticsDigestService.ts:464) - Migration is additive and non-nullable:
ADD COLUMN IF NOT EXISTS send_hour integer NOT NULL DEFAULT 9 rowToResponseemits the newsendHourthe response schema requires (DigestService.ts:1272)
Observability coverage: 2 of 2 changes observable
| Change | Kind | Observable | Evidence |
|---|---|---|---|
| DigestService.runDigestTick due-selection and claim window | background job | yes | Existing effectful tick span; service observed at 240 ticks/day in the last 7 days |
| WebAnalyticsDigestService.runTick due-selection and claim window | background job | yes | Effect.fn("WebAnalyticsDigestService.runTick") span at WebAnalyticsDigestService.ts:455 |
a06d415 · Updated on every push. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.
Loading