Commit Graph

6 Commits

Author SHA1 Message Date
cesnimda 654acacf5f fix(categories): correct all seven smart-folder bugs at the source (PHASE 2)
CI / backend (pull_request) Successful in 56s
CI / frontend (pull_request) Successful in 12s
CI / format (pull_request) Successful in 52s
CI / db-tests (pull_request) Successful in 57s
Security / secrets (pull_request) Successful in 3s
Security / dependencies (pull_request) Successful in 57s
Security / sast (pull_request) Successful in 37s
Root causes + fixes:
- Archive leaked Sent mail: filter was just 'not in inbox'. Added ExcludeGmailLabels;
  Archive now excludes SENT/DRAFT/SPAM/TRASH/CHAT by label.
- Read Later / Pinned / Unlabelled returned EVERYTHING (no folder case -> default all).
  Pinned = IsImportant; Read Later = new local IsReadLater marker (+toggle endpoints);
  Unlabelled = HasUserLabels=false.
- Trash & Spam always empty: IncludeSpamTrash=false + sync never set IsTrashed nor created
  EmailLabel rows. Now fetches spam/trash, sets IsTrashed from the TRASH label, and links
  every message to its Gmail labels (also fixes Sent/Spam/category-by-label/Unlabelled).
- Old Mail: now strictly older than 6 months (was 1 year).

Guardrail: sync upsert is now idempotent (drops prior copy before reinsert) so re-sync
can't duplicate a message or leave stale labels. 4 new filter tests; 65 backend + frontend
green; migration is a single non-destructive column add.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 16:21:53 +02:00
cesnimda 074d39d9a2 feat(platform): feature flags + user settings foundation (#35)
CI / backend (push) Successful in 1m4s
CI / frontend (push) Successful in 18s
CI / format (push) Successful in 1m1s
CI / db-tests (push) Successful in 1m4s
Deploy Staging / deploy (push) Successful in 37s
CI / backend (pull_request) Successful in 1m7s
CI / frontend (pull_request) Successful in 18s
CI / format (pull_request) Successful in 59s
CI / db-tests (pull_request) Successful in 1m5s
Security / secrets (push) Successful in 4s
Security / dependencies (push) Successful in 1m4s
Security / secrets (pull_request) Successful in 4s
Security / dependencies (pull_request) Successful in 1m4s
2026-07-02 18:04:14 +02:00
cesnimda 2056548702 feat(ai): pgvector embedding infrastructure (#19)
CI / backend (push) Successful in 51s
CI / frontend (push) Successful in 15s
Deploy Staging / deploy (push) Successful in 46s
Security / secrets (push) Successful in 4s
Security / dependencies (push) Successful in 56s
CI / backend (pull_request) Successful in 54s
CI / frontend (pull_request) Successful in 15s
Security / secrets (pull_request) Successful in 3s
Security / dependencies (pull_request) Successful in 55s
2026-07-02 03:00:06 +02:00
cesnimda 64f835f719 feat: AI categorisation fallback, unsubscribe confidence scoring, one-line summaries
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>
2026-06-30 22:21:10 +02:00
cesnimda 0163165beb 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>
2026-06-30 22:11:39 +02:00
cesnimda f43ef5f945 chore: init project 2026-06-30 15:53:32 +02:00