Skip to content

feat(settings): AI tab and email preferences with a local send schedule - #1531

Merged
Makisuo merged 33 commits into
feat/settings-mcpfrom
feat/settings-ai-email-prefs
Oct 17, 2026
Merged

Makisuo merged 33 commits into
feat/settings-mcpfrom
feat/settings-ai-email-prefs

Merge branch 'feat/settings-mcp' into feat/settings-ai-email-prefs

a06d415
Select commit
Loading
Failed to load commit list.
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.

  • isDigestDue decides sends on the subscriber's local day/hour/zone
  • Digest claims now guard on a 6-day resend cutoff, not UTC midnight
  • send_hour column (default 9) plus day/hour/zone validation on upsert
  • Auto-triage limits move to the AI tab behind SettingsSaveBar

Before merge

Still open from earlier reviews

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 sendHour reaches isDigestDue (DigestService.ts:1047, WebAnalyticsDigestService.ts:464)
  • Migration is additive and non-nullable: ADD COLUMN IF NOT EXISTS send_hour integer NOT NULL DEFAULT 9
  • rowToResponse emits the new sendHour the 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.