Skip to content

feat: restore messages to original folder when unmarked as spam#236

Merged
Aravinda-HWK merged 4 commits intoLSFLK:mainfrom
MohamadNazik:fix/spam-folder-state-transition
Mar 19, 2026
Merged

feat: restore messages to original folder when unmarked as spam#236
Aravinda-HWK merged 4 commits intoLSFLK:mainfrom
MohamadNazik:fix/spam-folder-state-transition

Conversation

@MohamadNazik
Copy link
Copy Markdown
Contributor

@MohamadNazik MohamadNazik commented Mar 11, 2026

📌 Description

This PR fixes the issue where emails marked as "Not Spam" were always moved to the Inbox, regardless of their original folder. We now track the source folder ID before a message is moved to Spam, allowing it to be properly restored to its correct location (e.g., Sent) when unmarked.


🔍 Changes Made

  • Database: Added a new column to the message-mailbox association table to store the original folder ID.
  • Migration: Implemented an auto-migration check during database initialization to seamlessly update existing user databases.
  • Logic:
    • Updated the internal message movement function to accept and persist the previous folder reference.
    • Updated message storage handlers to save the current folder ID when a message is marked as Junk.
    • Modified restoration logic to use the tracked history when the Junk status is removed, defaulting to "INBOX" only for messages without prior history.
  • Testing: Added new automated unit tests covering folder restoration and default fallback scenarios.

✅ Checklist (Email System)

  • Core IMAP commands tested (LOGIN, CAPABILITY, LIST, SELECT, FETCH, LOGOUT).
  • Authentication is tested.
  • Docker build & run validated.
  • Configuration loading verified for default and custom paths.
  • Persistent storage with Docker volume verified.
  • Error handling and logging verified.
  • Documentation updated (README, config samples).

🧪 Testing Instructions

To verify the fix locally:

  1. Run the new automated unit tests for message restoration.
  2. Manual verification:
    • Select the "Sent" folder.
    • Mark a message as Junk.
    • Verify the message moves to "Spam".
    • Select the "Spam" folder.
    • Mark the same message as Not Spam.
    • Expected: Message moves back to "Sent".

📷 Screenshots / Logs (if applicable)

(No response)


⚠️ Notes for Reviewers

  • Schema Change: This PR introduces a new column to the database. An auto-migration script is included to handle existing installations.
  • Mutual Exclusion: The logic remains consistent in ensuring that Junk and NonJunk status flags are handled correctly during folder transitions.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Mar 11, 2026

CLA assistant check
All committers have signed the CLA.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses an issue where messages unmarked as spam were always moved to the Inbox, regardless of their original location. By introducing a mechanism to track the message's original folder, the system can now accurately restore messages to their correct previous mailbox, improving user experience and maintaining mail organization.

Highlights

  • Database Schema Update: A new column, previous_mailbox_id, has been added to the message_mailbox table to track the original folder of a message before it's moved to spam.
  • Automatic Database Migration: An auto-migration check is now performed during database initialization to seamlessly add the new previous_mailbox_id column to existing user databases.
  • Enhanced Message Movement Logic: The MoveMessageToMailbox function has been updated to accept and persist the previous folder ID. When a message is marked as Junk, its current folder ID is saved. When unmarked as NonJunk, the message is restored to its tracked original folder, or defaults to 'INBOX' if no prior history exists.
  • New Unit Tests: Automated unit tests have been added to cover scenarios for correct folder restoration and the default fallback to 'INBOX' when a message is unmarked as spam.
Changelog
  • internal/db/sqlite.go
    • Added previous_mailbox_id column to the message_mailbox table with a foreign key constraint to mailboxes(id).
    • Implemented a migration check to add the previous_mailbox_id column to existing message_mailbox tables if it does not already exist.
  • internal/server/message/message.go
    • Modified HandleStore to pass the state.SelectedMailboxID as the previousMailboxID when a message is marked as Junk, ensuring the original folder is recorded.
    • Updated HandleStore to retrieve the previous_mailbox_id from the message_mailbox table when a message is unmarked as Junk, using it as the targetFolder for restoration.
    • Changed the signature of MoveMessageToMailbox to accept an optional previousMailboxID *int64 parameter.
    • Modified the INSERT statement in MoveMessageToMailbox to include the previous_mailbox_id when a message is moved.
  • internal/server/message/spam_restoration_test.go
    • Added TestSpamRestoration to verify that messages moved from a specific folder (e.g., 'Sent') to 'Spam' are correctly restored to their original folder when unmarked.
    • Added TestSpamDefaultRestoreToInbox to confirm that messages initially placed directly into 'Spam' (without a recorded previous_mailbox_id) are restored to 'INBOX' when unmarked.
  • internal/server/uid/uid.go
    • Modified handleUIDStore to pass the state.SelectedMailboxID as the previousMailboxID when a message is marked as Junk, mirroring changes in message.go.
    • Updated handleUIDStore to query and utilize the previous_mailbox_id for message restoration when a message is unmarked as Junk, ensuring consistent behavior across store handlers.
Activity
  • The pull request introduces a new feature and includes database schema changes with an auto-migration, along with new unit tests to validate the functionality.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a useful feature to restore messages to their original folder when they are unmarked as spam. The implementation correctly adds a previous_mailbox_id column to the database, includes a migration for existing installations, and adds new tests to verify the behavior. However, I've identified some critical and high-severity issues related to error handling. In both the database migration logic and the message restoration logic, potential database errors are silently ignored. This could lead to an inconsistent database state or incorrect behavior (like falling back to INBOX) without any logs or warnings. I have provided specific suggestions to ensure these errors are properly handled and logged.

Comment thread internal/db/sqlite.go Outdated
Comment thread internal/server/message/message.go Outdated
Comment thread internal/server/uid/uid.go Outdated
@Aravinda-HWK
Copy link
Copy Markdown
Collaborator

@MohamadNazik Could you please resolve the Gemini reviews?

Comment thread internal/server/message/spam_restoration_test.go Outdated
@MohamadNazik MohamadNazik marked this pull request as draft March 17, 2026 03:18
- Fix error handling in DB migration logic to prevent silent failures
- Add logging for database query errors during message restoration
- Consolidate spam restoration tests into store_test.go
- Add descriptive documentation comments to the new test cases
@MohamadNazik
Copy link
Copy Markdown
Contributor Author

@Aravinda-HWK
I have addressed all gemini reviews and the review comments from reviewers. Please check.

@MohamadNazik MohamadNazik marked this pull request as ready for review March 17, 2026 07:19
@Aravinda-HWK
Copy link
Copy Markdown
Collaborator

@Aravinda-HWK I have addressed all gemini reviews and the review comments from reviewers. Please check.

Hi @MohamadNazik I removed the migration because we are not in production level. No need for that.

Copy link
Copy Markdown
Collaborator

@Aravinda-HWK Aravinda-HWK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@Aravinda-HWK Aravinda-HWK merged commit 5f30035 into LSFLK:main Mar 19, 2026
5 checks passed
Aravinda-HWK added a commit that referenced this pull request Mar 22, 2026
* feat: restore messages to original folder when unmarked as spam

* refactor: address PR review comments for spam restoration logic
- Fix error handling in DB migration logic to prevent silent failures
- Add logging for database query errors during message restoration
- Consolidate spam restoration tests into store_test.go
- Add descriptive documentation comments to the new test cases

* refactor: remove migration logic for previous_mailbox_id column in createMessageMailboxTable

---------

Co-authored-by: Aravinda-HWK <aravinda.20@cse.mrt.ac.lk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Mail marked as “Not Spam” always moves to Inbox instead of the original folder

3 participants