From 452828babefa2f4f2da7737ec277c741e3373cc7 Mon Sep 17 00:00:00 2001 From: Agent Zero Date: Mon, 20 Jul 2026 14:26:07 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20never=20restore=20deleted=20mails=20duri?= =?UTF-8?q?ng=20sync=20=E2=80=94=20deleted=20means=20deleted?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Sync was restoring deleted_at mails when found on IMAP server - This caused deleted mails to reappear in inbox on every sync - Now deleted mails are always skipped during sync, never restored - IMAP delete is retried via sync queue --- app/plugins/builtins/mail/services.py | 39 +++++++-------------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/app/plugins/builtins/mail/services.py b/app/plugins/builtins/mail/services.py index 8bd9c01..303a824 100644 --- a/app/plugins/builtins/mail/services.py +++ b/app/plugins/builtins/mail/services.py @@ -665,22 +665,12 @@ async def imap_sync_folder( ).scalar_one_or_none() if existing_mail: - # If mail has deleted_at but is still on the IMAP server, - # the IMAP delete failed. - # Only restore if the mail is in the SAME folder we're syncing. - # If the mail was moved to Trash in DB (folder_id=Trash) but is - # still in INBOX on IMAP, DON'T restore to INBOX — keep it - # in Trash and let the sync queue retry the IMAP MOVE. + # If mail has deleted_at, it was deleted in LeoCRM. + # DO NOT restore it — keep it deleted and let the sync queue + # retry the IMAP delete/move. This prevents deleted mails from + # reappearing in the inbox. if existing_mail.deleted_at is not None: - if existing_mail.folder_id == folder.id: - # Mail is in the right folder on IMAP — restore - existing_mail.deleted_at = None - logger.info("imap_sync_folder: restored mail %s (still on IMAP server in correct folder)", existing_mail.id) - else: - # Mail is in a different folder in DB — IMAP move failed - # Don't restore, don't change folder_id — keep in Trash - logger.info("imap_sync_folder: skipping mail %s (deleted, in folder %s but found in %s on IMAP, move failed)", existing_mail.id, existing_mail.folder_id, folder.imap_name) - continue + continue # Update folder_id and imap_uid if mail moved to a different folder if existing_mail.folder_id != folder.id: existing_mail.folder_id = folder.id @@ -1174,22 +1164,11 @@ async def imap_sync_account( ).scalar_one_or_none() if existing_mail: - # If mail has deleted_at but is still on the IMAP server, - # the IMAP delete failed. - # Only restore if the mail is in the SAME folder we're syncing. - # If the mail was moved to Trash in DB (folder_id=Trash) but is - # still in INBOX on IMAP, DON'T restore to INBOX — keep it - # in Trash and let the sync queue retry the IMAP MOVE. + # If mail has deleted_at, it was deleted in LeoCRM. + # DO NOT restore it — keep it deleted and let the sync queue + # retry the IMAP delete/move. if existing_mail.deleted_at is not None: - if existing_mail.folder_id == folder.id: - # Mail is in the right folder on IMAP — restore - existing_mail.deleted_at = None - logger.info("imap_sync_account: restored mail %s (still on IMAP server in correct folder)", existing_mail.id) - else: - # Mail is in a different folder in DB — IMAP move failed - # Don't restore, don't change folder_id — keep in Trash - logger.info("imap_sync_account: skipping mail %s (deleted, in folder %s but found in %s on IMAP, move failed)", existing_mail.id, existing_mail.folder_id, folder.imap_name) - continue + continue # Track folder moves: update folder_id and imap_uid if the # mail now appears in a different IMAP folder. if existing_mail.folder_id != folder.id: