Skip to content

Comments

Delete old drafts#489

Merged
elie222 merged 1 commit intomainfrom
feat/delete-old-drafts
Jun 5, 2025
Merged

Delete old drafts#489
elie222 merged 1 commit intomainfrom
feat/delete-old-drafts

Conversation

@elie222
Copy link
Owner

@elie222 elie222 commented Jun 5, 2025

Summary by CodeRabbit

  • New Features
    • Improved draft email management to automatically handle deletion of previous drafts when appropriate.
  • Bug Fixes
    • Enhanced logic for detecting and deleting outdated drafts, ensuring drafts are only deleted if content matches and not already sent.
  • Tests
    • Added comprehensive tests for draft deletion scenarios to ensure robust handling and error resilience.
  • Documentation
    • Updated testing guidelines with a new best practice recommendation.
  • Chores
    • Updated version number to v1.3.21.

@vercel
Copy link

vercel bot commented Jun 5, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
inbox-zero 🔄 Building (Inspect) Visit Preview Jun 5, 2025 7:02pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 5, 2025

Walkthrough

A new test suite was added for the handlePreviousDraftDeletion function, and its logic was enhanced to better filter and manage draft deletions, including improved content comparison and concurrent deletion with status updates. The draft action was updated to accept an executedRule parameter and to run draft creation and previous draft deletion in parallel. Documentation and versioning were updated.

Changes

File(s) Change Summary
apps/web/tests/ai/choose-rule/draft-management.test.ts Added comprehensive tests for handlePreviousDraftDeletion, covering various draft deletion scenarios.
apps/web/utils/ai/choose-rule/draft-management.ts Improved logic for filtering, content comparison, concurrent deletion, and logging in draft deletion handling.
apps/web/utils/ai/actions.ts Updated draft to accept executedRule and run draft creation and previous draft deletion concurrently.
.cursor/rules/testing.mdc Appended guideline: "Do not mock the Logger" to testing best practices.
version.txt Incremented version from v1.3.20 to v1.3.21.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant draft (actions.ts)
    participant draftEmail
    participant handlePreviousDraftDeletion
    participant Gmail
    participant Logger

    User->>draft: call draft(gmail, executedRule, logger, ...)
    draft->>+draftEmail: create draft
    draft->>+handlePreviousDraftDeletion: delete previous draft
    handlePreviousDraftDeletion->>Gmail: fetch previous draft
    handlePreviousDraftDeletion->>Logger: log actions/errors
    handlePreviousDraftDeletion->>Gmail: delete draft (if applicable)
    handlePreviousDraftDeletion->>Logger: log deletion/update
    draftEmail-->>draft: draftId
    handlePreviousDraftDeletion-->>draft: (done)
    draft-->>User: draftId
Loading

Poem

A bunny hops to test and write,
Deleting drafts with logic tight.
Now actions run in parallel cheer,
With careful checks and logs so clear.
A version hops up—what a sight!
In every change, the code feels right.
🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

apps/web/__tests__/ai/choose-rule/draft-management.test.ts

Oops! Something went wrong! :(

ESLint: 9.28.0

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

apps/web/utils/ai/actions.ts

Oops! Something went wrong! :(

ESLint: 9.28.0

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

apps/web/utils/ai/choose-rule/draft-management.ts

Oops! Something went wrong! :(

ESLint: 9.28.0

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

✅ BugBot reviewed your changes and found no bugs!


BugBot free trial expires on June 9, 2025
You have used $0.00 of your $50.00 spend limit so far. Manage your spend limit in the Cursor dashboard.

Was this report helpful? Give feedback by reacting with 👍 or 👎

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
apps/web/utils/ai/actions.ts (1)

124-141: Excellent optimization with parallel execution.

Running draft creation and previous draft deletion concurrently is a smart optimization. The implementation correctly destructures only the first result since handlePreviousDraftDeletion doesn't return a meaningful value.

Consider that if handlePreviousDraftDeletion throws an error, it will cause the entire Promise.all to reject and prevent the draft from being created. Given that draft deletion is not critical to the main flow, you might want to handle errors within handlePreviousDraftDeletion to ensure draft creation always succeeds.

Looking at the handlePreviousDraftDeletion function in apps/web/utils/ai/choose-rule/draft-management.ts (lines 106-109), I can see it already has proper error handling with try-catch and logging, so the current implementation should be robust.

apps/web/__tests__/ai/choose-rule/draft-management.test.ts (1)

24-40: Consider adding tests for different quote header patterns.

While the current test covers the most common quote pattern (\n\nOn .* wrote:), the actual function supports multiple patterns. Consider adding tests for the other supported patterns to ensure robust quote stripping.

Add test cases for other quote header patterns:

+  it("should handle different quote header patterns", async () => {
+    const testCases = [
+      {
+        pattern: "----+ Original Message ----+",
+        content: "Hello, test\n\n-------- Original Message --------\n> Previous message",
+        expected: "Hello, test"
+      },
+      {
+        pattern: ">+ On .*",
+        content: "Hello, test\n\n>> On Monday...\n> Previous message", 
+        expected: "Hello, test"
+      },
+      {
+        pattern: "From: .*",
+        content: "Hello, test\n\nFrom: sender@example.com\n> Previous message",
+        expected: "Hello, test"
+      }
+    ];
+    
+    // Test each pattern...
+  });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d960b2 and ce0134e.

📒 Files selected for processing (5)
  • .cursor/rules/testing.mdc (1 hunks)
  • apps/web/__tests__/ai/choose-rule/draft-management.test.ts (1 hunks)
  • apps/web/utils/ai/actions.ts (2 hunks)
  • apps/web/utils/ai/choose-rule/draft-management.ts (4 hunks)
  • version.txt (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
apps/web/utils/ai/actions.ts (1)
apps/web/utils/ai/choose-rule/draft-management.ts (1)
  • handlePreviousDraftDeletion (11-110)
apps/web/utils/ai/choose-rule/draft-management.ts (1)
apps/web/utils/gmail/draft.ts (1)
  • deleteDraft (24-45)
apps/web/__tests__/ai/choose-rule/draft-management.test.ts (4)
apps/web/utils/logger.ts (1)
  • createScopedLogger (17-65)
apps/web/utils/gmail/draft.ts (2)
  • getDraft (9-22)
  • deleteDraft (24-45)
apps/web/utils/types.ts (1)
  • ParsedMessage (47-58)
apps/web/utils/ai/choose-rule/draft-management.ts (1)
  • handlePreviousDraftDeletion (11-110)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Static Code Analysis Js
  • GitHub Check: Jit Security
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (14)
version.txt (1)

1-1: Version increment looks appropriate.

The version bump from v1.3.20 to v1.3.21 is appropriate for the draft management enhancements in this PR.

.cursor/rules/testing.mdc (1)

44-45: Good addition to testing best practices.

The guideline to avoid mocking the Logger is sensible and aligns with the code changes where logging behavior is important to preserve in tests.

apps/web/utils/ai/actions.ts (1)

22-22: Good addition of the import.

The import for handlePreviousDraftDeletion is correctly added to support the new parallel execution.

apps/web/utils/ai/choose-rule/draft-management.ts (4)

25-31: Improved filtering logic for better draft selection.

The explicit filtering by threadId and emailAccountId ensures precise targeting of drafts, and the draftSendLog: null condition properly excludes already-sent drafts. The explicit exclusion of the current executedRule.id prevents self-reference issues.


56-72: Enhanced content comparison with multiple quote patterns.

The implementation of multiple quote header patterns significantly improves the accuracy of content comparison by handling different email client quote formats. The loop structure efficiently finds the first matching pattern and properly extracts the user's content.

The patterns cover common quote formats:

  • Gmail/Outlook: "On ... wrote:"
  • Some email clients: "---- Original Message ----"
  • Reply prefixes: "> On ..."
  • Forward headers: "From: ..."

84-93: Excellent use of parallel operations for performance.

The concurrent execution of deleteDraft and database update using Promise.all is a good optimization. Both operations are independent and can safely run in parallel, reducing the overall execution time.

The error handling is properly managed by the outer try-catch block, and the logging provides good visibility into the operations.


127-127: Clean use of shorthand property notation.

The simplification to use shorthand property notation ({ draftId } instead of { draftId: draftId }) improves code readability without changing functionality.

apps/web/__tests__/ai/choose-rule/draft-management.test.ts (7)

1-22: Well-structured test setup with comprehensive mocking.

The imports and mock setup are properly configured. The mocking strategy correctly isolates the function under test by mocking external dependencies (Prisma and Gmail draft functions).


42-104: Excellent test coverage for the main success scenario.

This test correctly validates the core functionality:

  • Proper database query with all expected filters
  • Content comparison logic with quote stripping (the test content with "\n\nOn Monday wrote:" gets stripped correctly)
  • Concurrent execution of draft deletion and database update
  • All assertions verify the correct function calls and parameters

The mock data accurately represents real-world email draft scenarios.


106-143: Good test for preventing deletion of user-modified drafts.

This test ensures that when users modify draft content, the system respects their changes and doesn't delete the draft. The content comparison ("test" vs "MODIFIED") correctly triggers the skip deletion logic.


145-156: Proper handling of the no previous draft scenario.

This test correctly validates that when no previous draft exists, the function gracefully exits without making unnecessary Gmail API calls.


158-175: Good edge case coverage for Gmail API scenarios.

This test handles the case where a draft record exists in the database but the actual draft has been deleted from Gmail (404 scenarios), ensuring the function doesn't crash.


177-189: Excellent error handling validation.

The test correctly verifies that database errors are caught and logged without throwing, ensuring the function's resilience doesn't break the overall workflow.


191-226: Important edge case for drafts without plain text content.

This test covers scenarios where drafts might only have HTML content or no readable text content, ensuring the function handles these gracefully without attempting deletion.

@elie222 elie222 merged commit 1d54dc4 into main Jun 5, 2025
9 of 10 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jul 16, 2025
@elie222 elie222 deleted the feat/delete-old-drafts branch December 18, 2025 23:02
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.

1 participant