RECOMMENDATIONS #8: additive AfterSentAtUtc+AfterId cursor — browse windows fetch
via a (SentAtUtc, Id) keyset filter, O(pageSize) at any depth, COUNT skipped
(TotalCount=-1). Adds the Id tie-break to browse ordering (fixes latent
duplicate/skip on equal timestamps). Verified: InMemory continuation test + a
live-Postgres throwaway proving the Guid cursor comparison translates (removed).
Also root-causes the recurring pre-commit/CI format failures: dotnet-format on
Windows defaulted to CRLF while .gitattributes stores LF — the two fought forever.
Adds .editorconfig (end_of_line=lf etc.) so every tool agrees, and normalises the
straggler files. This bug bit three separate commits before being diagnosed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Heuristic classifier falls back to AI only when it can't determine a category;
unsubscribe confidence blends method reliability with an AI safety opinion and
surfaces it in the Unsubscribe Manager; emails get an on-demand AI one-line
summary in the detail pane. All AI calls degrade gracefully when AI is disabled
or the provider errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a periodic inbox-summary email per opted-in user. SMTP is
configured via appsettings (Smtp section); the digest is built from
existing analytics (health score, top senders, recommendations) and
sent by a new hourly DigestWorker, mirroring the GmailSyncWorker
pattern. Frequency and send hour are configurable (Digest section).
Backend: IEmailSender (SmtpEmailSender, MailKit), IDigestService,
DigestWorker, new User.DigestEnabled/LastDigestSentUtc fields +
migration, SettingsController for the per-user toggle and a
send-now test endpoint, all scoped to the authenticated UserId.
Frontend: SettingsApi + a bell/no-bell toggle button in the topbar.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>