feat: notification digests via SMTP
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>
This commit is contained in:
@@ -73,3 +73,16 @@ public interface IExportService
|
||||
{
|
||||
Task<(byte[] Content, string ContentType, string FileName)> ExportReportAsync(Guid userId, ExportFormat format, CancellationToken ct = default);
|
||||
}
|
||||
|
||||
/// <summary>SMTP-backed email delivery, used for digest notifications. No-ops if SMTP is not configured.</summary>
|
||||
public interface IEmailSender
|
||||
{
|
||||
bool IsEnabled { get; }
|
||||
Task SendAsync(string toAddress, string subject, string htmlBody, CancellationToken ct = default);
|
||||
}
|
||||
|
||||
/// <summary>Builds and sends the periodic inbox digest for opted-in users.</summary>
|
||||
public interface IDigestService
|
||||
{
|
||||
Task SendDigestAsync(Guid userId, CancellationToken ct = default);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user