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
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>
This commit is contained in:
@@ -72,6 +72,22 @@ public class EmailController : ApiControllerBase
|
||||
[HttpPost("{id:guid}/untrash")]
|
||||
public Task<IActionResult> Untrash(Guid id, CancellationToken ct) => Act(id, CleanupActionType.Archive, ct);
|
||||
|
||||
/// <summary>Toggle the local-only Read Later marker (no Gmail side effect).</summary>
|
||||
[HttpPost("{id:guid}/readlater")]
|
||||
public Task<IActionResult> ReadLater(Guid id, CancellationToken ct) => SetReadLater(id, true, ct);
|
||||
|
||||
[HttpPost("{id:guid}/unreadlater")]
|
||||
public Task<IActionResult> UnreadLater(Guid id, CancellationToken ct) => SetReadLater(id, false, ct);
|
||||
|
||||
private async Task<IActionResult> SetReadLater(Guid id, bool value, CancellationToken ct)
|
||||
{
|
||||
var email = await _db.Emails.FirstOrDefaultAsync(e => e.Id == id && e.UserId == UserId, ct);
|
||||
if (email is null) return NotFound();
|
||||
email.IsReadLater = value;
|
||||
await _db.SaveChangesAsync(ct);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inline unsubscribe. Detects the unsubscribe mechanism for the email's sender,
|
||||
/// then executes it (HTTP one-click or HTTP link). mailto targets cannot be sent
|
||||
|
||||
Reference in New Issue
Block a user