Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch Test tab to Process tab #288

Merged
merged 15 commits into from
Jan 5, 2025
Merged

Switch Test tab to Process tab #288

merged 15 commits into from
Jan 5, 2025

Conversation

elie222
Copy link
Owner

@elie222 elie222 commented Jan 4, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new "Process" page in the Automation section.
    • Added a toggle to switch between Test and Apply modes for email rule processing.
  • User Interface Changes

    • Simplified the Automation page layout.
    • Updated the "Test" tab to "Process" with new functionality.
    • Enhanced Toggle component with optional right-side label.
    • Improved the layout of the Processing Prompt File Dialog for a more structured onboarding experience.
    • Updated instructional text in the Bulk Run Rules modal for clarity.
  • Usability Improvements

    • Streamlined instructions for email processing by directing users to the "Mail" page, now opening in a new tab.
    • Enhanced data handling in the Pending Table for better context during rule evaluation.
    • Configured the Crisp chat widget to be hidden on mobile devices.

Copy link

vercel bot commented Jan 4, 2025

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

Name Status Preview Updated (UTC)
inbox-zero ✅ Ready (Inspect) Visit Preview Jan 5, 2025 0:43am

Copy link
Contributor

coderabbitai bot commented Jan 4, 2025

Warning

Rate limit exceeded

@elie222 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 12 minutes and 29 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between ca9fdd1 and aa8fce3.

📒 Files selected for processing (1)
  • apps/web/app/(app)/automation/TestRules.tsx (12 hunks)

Walkthrough

The pull request introduces significant changes to the automation and testing workflow in the web application. The modifications focus on restructuring the user interface for processing emails, introducing a new Process component, and refactoring the testing and rule application flow. The changes simplify the user experience by consolidating functionality, renaming components, and providing more intuitive navigation between different modes of email rule processing.

Changes

File Change Summary
apps/web/app/(app)/automation/BulkRunRules.tsx Simplified modal instructions, added target="_blank" to Mail page link
apps/web/app/(app)/automation/Process.tsx New component with applyMode state and toggle for switching between test and apply modes
apps/web/app/(app)/automation/ProcessingPromptFileDialog.tsx Refactored dialog with Carousel component, removed commented loading states
apps/web/app/(app)/automation/TestRules.tsx Renamed testing-related variables, added testMode prop, updated UI text
apps/web/app/(app)/automation/page.tsx Replaced "Test" tab with "Process" tab, removed BulkRunRules component
apps/web/components/Toggle.tsx Added labelRight prop, updated component layout
apps/web/utils/actions/ai-rule.ts Consolidated runRulesAction and testAiAction, improved input validation
apps/web/utils/actions/validation.ts Added schema definition for runRulesBody and corresponding type
apps/web/utils/ai/choose-rule/run-rules.ts Removed testRulesOnMessage function, simplifying rule execution logic
apps/web/utils/queue/email-actions.ts Renamed variable force to rerun, updated runRulesAction call with isTest: false
apps/web/app/(app)/automation/ReportMistake.tsx Updated type declarations from TestResult to RunRulesResult, modified function signatures
apps/web/app/(app)/automation/Pending.tsx Updated RuleCell to include message prop, enhancing data passed to it
apps/web/utils/actions/group.ts Updated functions to validate user login status using session.user.email instead of session.user.id
apps/web/utils/ai/group/find-newsletters.ts Modified findNewsletters function to include userEmail parameter for filtering
apps/web/utils/ai/group/find-receipts.ts Updated findReceipts function to include userEmail parameter for filtering

Possibly Related PRs

  • AI prompt for each generated argument #191: The changes in RuleForm.tsx involve handling AI-generated fields, which may relate to the user interface adjustments in BulkRunRules.tsx that simplify user instructions.
  • Block emails user unsubscribed from #218: The changes in BulkUnsubscribeDesktop.tsx focus on user interactions and UI updates, which may relate to the user experience improvements in BulkRunRules.tsx.
  • Email action analytics #219: The introduction of analytics in EmailActionsAnalytics.tsx may relate to the user interface changes in BulkRunRules.tsx as both involve user interactions and feedback mechanisms.
  • Add bulk actions #223: The addition of bulk actions in BulkActions.tsx could relate to the bulk processing functionalities in BulkRunRules.tsx.
  • Added withActionInstrumentation to track server action errors #241: The introduction of instrumentation for tracking actions in ai-rule.ts may relate to the user interactions and processing in BulkRunRules.tsx.
  • Generate groups with AI prompt #244: The changes related to generating groups with AI prompts may connect with the user interface updates in BulkRunRules.tsx that involve AI functionalities.
  • Onboarding #245: The onboarding enhancements in OnboardingEmailAssistant.tsx may relate to the user experience improvements in BulkRunRules.tsx.
  • Queue fixes #250: The queue fixes in BulkRunRules.tsx directly relate to the modifications made in the same file regarding the initialization of the abortRef variable.
  • AI template responses #263: The AI template responses may connect with the user interface updates in BulkRunRules.tsx that involve AI functionalities.
  • Report mistakes when testing #268: The reporting of mistakes when testing in ai-rule-fix.test.ts may relate to the user interactions in BulkRunRules.tsx.
  • Add call webhook action #282: The addition of the webhook action in WebhookGenerate.tsx may connect with the processing functionalities in BulkRunRules.tsx.
  • Adjust group matches #285: The adjustments to group matches in TestRules.tsx may relate to the user interface updates in BulkRunRules.tsx that involve testing and processing rules.

Poem

🐰 In the realm of automation's dance,
Rules hop and toggle with a glance,
Test mode, apply mode, switch with glee,
A rabbit's workflow, now set free!
Emails processed with playful might,
Code leaps forward, oh so bright! 🚀


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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. (Beta)
  • @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
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 (5)
apps/web/app/(app)/automation/Process.tsx (1)

14-14: Consider naming clarity for toggle state.
Currently, applyMode is false by default, implying the "Test" mode is active by default. Consider renaming it to a more descriptive name (e.g., isApplying) or clarifying it in the component’s documentation for better readability.

apps/web/app/(app)/automation/page.tsx (1)

30-30: Rename the tab value or label to avoid confusion.
You’re using <TabsTrigger value="test">Process</TabsTrigger>, which can be confusing for both maintainers and users. Consider updating value="test" to value="process" (or renaming the label) for consistency and future clarity.

- <TabsTrigger value="test">Process</TabsTrigger>
+ <TabsTrigger value="process">Process</TabsTrigger>
apps/web/app/(app)/automation/BulkRunRules.tsx (1)

117-125: Add rel="noopener noreferrer" when opening links in new tabs.
To avoid potential security or performance issues (e.g., window.opener references), it’s good practice to add rel="noopener noreferrer" for external or new-tab links.

<Link
  href="/mail"
  target="_blank"
- className="font-semibold hover:underline"
+ rel="noopener noreferrer"
+ className="font-semibold hover:underline"
>
  Mail
</Link>
apps/web/app/(app)/automation/TestRules.tsx (1)

Line range hint 118-130: Proper error handling for onRun.
Catching potential errors via toastError is good. Consider capturing potential network or request cancellation errors for finer debugging if needed.

apps/web/components/Toggle.tsx (1)

21-21: Consider enhancing screen reader support for the right label

The layout changes look good, with balanced spacing and consistent styling. However, consider updating the screen reader only text to include both labels when present.

-          <span className="sr-only">{label}</span>
+          <span className="sr-only">{label} {labelRight}</span>

Also applies to: 44-48

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 009a0d3 and 9fdfb4d.

📒 Files selected for processing (6)
  • apps/web/app/(app)/automation/BulkRunRules.tsx (1 hunks)
  • apps/web/app/(app)/automation/Process.tsx (1 hunks)
  • apps/web/app/(app)/automation/ProcessingPromptFileDialog.tsx (0 hunks)
  • apps/web/app/(app)/automation/TestRules.tsx (9 hunks)
  • apps/web/app/(app)/automation/page.tsx (3 hunks)
  • apps/web/components/Toggle.tsx (2 hunks)
💤 Files with no reviewable changes (1)
  • apps/web/app/(app)/automation/ProcessingPromptFileDialog.tsx
🔇 Additional comments (16)
apps/web/app/(app)/automation/Process.tsx (2)

21-24: Ensure copy aligns with intended user actions.
When "applyMode" is true, the text states "Run your rules on previous emails," which is straightforward. However, ensure the messaging in future expansions of the UI remains consistent with this intended "apply" behavior, especially if additional modes or states are introduced.


37-37: Prop usage verification.
Passing testMode={!applyMode} to TestRulesContent is clear and consistent here. Just ensure future updates maintain correct usage if definitions of “test” and “apply” pivot.

apps/web/app/(app)/automation/page.tsx (1)

56-56: No concerns for now.
The <Process /> component is imported and rendered directly. Looks fine and keeps the code clean.

apps/web/app/(app)/automation/TestRules.tsx (10)

49-49: Great to see reuse of BulkRunRules.
Importing BulkRunRules here aligns the “run” logic. This keeps “process” and “test” modes distinct while reusing logic effectively.


60-60: Consistent usage of testMode prop.
Passing testMode at the call site clarifies the component’s mode. The approach is clean and straightforward.


72-72: Prop destructuring is succinct.
Destructuring { testMode } at the function signature is neat and helps keep the code self-documenting.


113-116: Clear renaming from “testing” to “running.”
Renaming these to isRunningAll, isRunning, etc., is clearer and prevents confusion regarding the new “test” vs. “apply” modes. Nicely done.


158-169: Good conditionals to switch between “Test All” and “Run on All.”
This logic makes the UI adapt nicely to the current mode. Implementation is straightforward and easy to follow.


171-171: Conditional usage of BulkRunRules.
Hiding BulkRunRules during test mode helps maintain a clean user experience. Good architectural decision.


Line range hint 188-193: Selective rendering of custom form.
Conditionally showing the custom form only when testMode and AI rules exist is a neat approach to reduce potential confusion for non-AI rules.


211-214: Descriptive prop usage.
Passing isRunning, result, onRun, and testMode clarifies each row’s state. This maintains an intuitive structure.


290-300: Well-structured prop definitions.
Defining the prop interface inline is straightforward. Keeping explicit prop types ensures clarity for maintainers.


326-328: Conditional text “Test” vs. “Run.”
Appropriately controlling the button label based on testMode helps unify UI logic and reduces duplication.

apps/web/components/Toggle.tsx (3)

1-1: LGTM! Well-structured interface extension

The switch to Field component and addition of labelRight prop provides better flexibility for the toggle layout while maintaining type safety.

Also applies to: 9-9


17-17: LGTM! Clean props destructuring

The props destructuring is properly updated to include the new labelRight prop.


Line range hint 1-57: Verify the toggle implementation in Process component

The changes look well-structured for supporting the Test/Apply mode toggle. Let's verify the implementation in the Process component.

✅ Verification successful

Toggle component is correctly integrated for Test/Apply mode switching

The Toggle component is properly implemented in the Process component:

  • Imported correctly from the components directory
  • Used with all required props: name, label, labelRight, enabled, and onChange
  • Properly controls the test/apply mode state via the applyMode state variable
  • The mode state is correctly passed down to TestRulesContent component
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for Toggle usage in Process component
rg -l "Toggle" "apps/web/app/(app)/automation/Process.tsx"

# Check the implementation context
ast-grep --pattern 'import { Toggle } from "@/components/Toggle"'

Length of output: 855


Script:

#!/bin/bash
# Check the Toggle usage context in Process.tsx
rg -A 10 "Toggle" "apps/web/app/(app)/automation/Process.tsx"

Length of output: 567

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: 1

🧹 Nitpick comments (6)
apps/web/app/(app)/automation/TestRules.tsx (4)

60-60: Consider making testMode configurable

Instead of hardcoding testMode={true}, consider forwarding it from the parent component's props for better reusability and flexibility.

-          <TestRulesContent testMode />
+          <TestRulesContent testMode={props.testMode ?? true} />

135-144: Enhance error handling with specific error types

The error handling could be more specific to help users better understand and resolve issues.

Consider categorizing errors and providing more specific error messages:

       if (isActionError(result)) {
+        const errorTitle = result.code === 'RATE_LIMIT' 
+          ? 'Rate limit exceeded' 
+          : 'Processing error';
         toastError({
-          title: "There was an error processing the email",
+          title: errorTitle,
           description: result.error,
         });
       }

174-188: Enhance button accessibility

The button group could benefit from ARIA labels for better screen reader support.

-            <Button onClick={handleStop} variant="outline">
+            <Button 
+              onClick={handleStop} 
+              variant="outline"
+              aria-label="Stop processing emails"
+            >
               <PauseIcon className="mr-2 h-4 w-4" />
               Stop
             </Button>

313-316: Improve type definitions with interface

Consider using an interface for better type organization and documentation.

+interface TestRulesContentRowProps {
+  message: Message;
+  userEmail: string;
+  isRunning: boolean;
+  result: TestResult;
+  onRun: () => void;
+  testMode: boolean;
+}

-}: {
-  message: Message;
-  userEmail: string;
-  isRunning: boolean;
-  result: TestResult;
-  onRun: () => void;
-  testMode: boolean;
+}: TestRulesContentRowProps
apps/web/utils/actions/ai-rule.ts (1)

50-55: Standardize error structure and refine validation
Using Zod here is a good start. Consider returning a more uniform error shape (e.g., { success: false, error: error.message }) to help the front end reliably handle failures.

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

162-177: Comprehensive schema for rule execution
runRulesBody accurately validates the required fields. Consider additional checks (e.g., ensuring valid email in from or a length limit on subject) to prevent malformed input.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9fdfb4d and 048d36a.

📒 Files selected for processing (5)
  • apps/web/app/(app)/automation/TestRules.tsx (9 hunks)
  • apps/web/utils/actions/ai-rule.ts (6 hunks)
  • apps/web/utils/actions/validation.ts (1 hunks)
  • apps/web/utils/ai/choose-rule/run-rules.ts (0 hunks)
  • apps/web/utils/queue/email-actions.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/web/utils/ai/choose-rule/run-rules.ts
🔇 Additional comments (6)
apps/web/utils/actions/ai-rule.ts (5)

14-14: Use a single unified function for rule execution
Good approach to consolidate the logic by importing and using runRulesOnMessage.


32-33: Adopt schema-based validation for maintainability
Importing runRulesBody and RunRulesBody enables more robust and consistent input validation.


79-90: Review test mode logic
Skipping the database lookup if isTest is true seems reasonable, but verify that test scenarios won’t need existing rule data. Confirm that no edge cases are affected by bypassing this query.


104-105: Propagate test flags consistently
Passing isTest directly to runRulesOnMessage keeps the flow consistent for testing vs. production scenarios.


140-141: Explicitly declare test execution
Using isTest: true here is a clear way to unify logic under the same function without duplicating test-only methods.

apps/web/utils/queue/email-actions.ts (1)

17-19: Match unified signature for rule execution
Passing email, force, and isTest: false aligns with the new runRulesAction parameter structure, ensuring consistency.

apps/web/app/(app)/automation/TestRules.tsx Outdated Show resolved Hide resolved
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/queue/email-actions.ts (1)

18-23: Invoking runRulesAction with force and isTest: false
No error-handling block is present here. Consider capturing and logging errors for potential troubleshooting.

 } catch (error) {
+  console.error("Failed to run AI rules:", error);
 }
apps/web/utils/actions/ai-rule.ts (1)

Line range hint 139-157: Consider extracting test message creation

The test message object creation could be moved to a separate helper function to improve maintainability and reusability.

+function createTestMessage(content: string): ParsedMessage {
+  return {
+    id: "testMessageId",
+    threadId: "testThreadId",
+    snippet: content,
+    textPlain: content,
+    headers: {
+      date: new Date().toISOString(),
+      from: "",
+      to: "",
+      subject: "",
+    },
+    historyId: "",
+    inline: [],
+    internalDate: new Date().toISOString(),
+  };
+}

 const result = await runRulesOnMessage({
   isTest: true,
   gmail,
-  message: {
-    id: "testMessageId",
-    threadId: "testThreadId",
-    snippet: content,
-    textPlain: content,
-    headers: {
-      date: new Date().toISOString(),
-      from: "",
-      to: "",
-      subject: "",
-    },
-    historyId: "",
-    inline: [],
-    internalDate: new Date().toISOString(),
-  },
+  message: createTestMessage(content),
   rules: user.rules,
   user,
 });
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 048d36a and 4cc7b1f.

📒 Files selected for processing (6)
  • apps/web/app/(app)/automation/ReportMistake.tsx (17 hunks)
  • apps/web/app/(app)/automation/TestRules.tsx (11 hunks)
  • apps/web/utils/actions/ai-rule.ts (8 hunks)
  • apps/web/utils/actions/validation.ts (1 hunks)
  • apps/web/utils/ai/choose-rule/run-rules.ts (2 hunks)
  • apps/web/utils/queue/email-actions.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/utils/actions/validation.ts
🔇 Additional comments (48)
apps/web/app/(app)/automation/ReportMistake.tsx (20)

19-19: Adopting the new RunRulesResult import looks good.
No further action needed.


27-27: Switch from testAiAction to runRulesAction is consistent with the new approach.
No issues found.


48-48: Newly imported ParsedMessage type
This strengthens the type safety for message usage.


59-59: Refined parameter type to RunRulesResult | null.
Good alignment with the new result structure.


103-103: Matching result: RunRulesResult | null
Ensures consistency across components.


248-248: message param introduced in AIFixView.
This ensures we have the full message data, which is helpful for AI-based fixes.


275-275: Prop message strongly typed as ParsedMessage.
This improves clarity and prevents runtime errors.


285-285: Reinforced typing with message: ParsedMessage.
No issues found.


314-314: Rendering <SuggestedFix> with full message prop.
No concerns; it ensures consistent usage of the ParsedMessage.


332-332: RuleMismatch now uses RunRulesResult | null.
Continues the updated result pattern.


458-458: ManualFixView extracts result as RunRulesResult | null.
No issues; consistent usage.


499-499: Including <RerunTestButton> inside ManualFixView.
This is a good addition to allow quick re-checking after manual fixes.


563-563: AIFixForm updated to accept result: RunRulesResult | null.
Ensures usage of the correct structure from the consolidated rules approach.


646-646: Calling <SuggestedFix> inside AIFixForm.
Provides immediate AI-based suggestions to the user.


658-658: New SuggestedFix component signature
No issues found; the design is straightforward.


664-664: message: ParsedMessage
Keeps consistent param pattern across components.


680-680: Triggering <RerunTestButton> after accepting fix
Enables quick feedback loop on any AI-proposed changes.


733-733: Introduction of function RerunTestButton
Enhances user workflow by allowing rule re-tests from the same UI.


735-735: const [testResult, setTestResult] = useState<RunRulesResult>();
No issues found, aligns with type usage.


744-755: Implementation of rerun logic
Provides a consistent approach to retesting messages with runRulesAction.

apps/web/utils/queue/email-actions.ts (1)

16-16: Retrieve the last message in the thread
Make sure all callers confirm that threads with no messages won't be processed. Already handled by the condition if (!message) return;

apps/web/utils/ai/choose-rule/run-rules.ts (2)

23-23: RunRulesResult type introduced
This is a clean structure that standardizes the outcome of rule evaluation. No concerns.


41-41: runRulesOnMessage now returns Promise<RunRulesResult>
Well-aligned with the new type. No issues found.

apps/web/app/(app)/automation/TestRules.tsx (21)

30-30: Use of runRulesAction
Replacing older testing logic is consistent with the new naming. No issues found here.


37-37: New import for RunRulesResult
Follows the rename from TestResult.


49-49: BulkRunRules import
Allows batch processing. No issues found.


60-60: <TestRulesContent testMode />
Clear distinction between test mode vs. run mode.


72-72: Function signature: TestRulesContent({ testMode }: { testMode: boolean })
Enables toggling behavior based on usage context.


113-116: New state variables isRunningAll, isRunning, results
Improves clarity over the old "testing" naming.


118-141: onRun function: Replaces onTest logic
Construct is sensible: sets loading states, invokes runRulesAction, updates results.


143-149: handleRunAll loops over messages
Relevant approach for mass processing. No immediate issues.


156-157: handleStart sets isRunningAll
Straightforward toggling. Good.


161-162: handleStop toggles off mass-run
Allows user to gracefully halt.


168-182: Render "Stop" or "Test All"/"Run on All" button
UI clarity is well handled.


185-185: Render "Custom" button conditionally
Ensures it only shows if AI rules exist in test mode.


198-198: Displays TestRulesForm when showCustomForm and testMode
User can quickly test the AI logic with a custom input.


221-224: Passing props to TestRulesContentRow
Streamlines relevant info for each message. No concerns.


251-251: testResult state in TestRulesForm
Stores the outcome of testAiCustomContentAction.


300-303: In TestRulesContentRow, new isRunning and result parameters
Makes the row aware of loading state and outcome.


307-310: Enhanced signature with result: RunRulesResult
Consistent with the broader type changes.


315-315: Conditional styling while isRunning
A user-friendly indicator. No issues found.


328-333: Displaying test results or the ReportMistake button
Clear user workflow for verifying rules or reporting mistakes.


336-338: Render "Test" or "Run" depending on testMode
Good UI distinction for different usage scenarios.


352-352: TestResultDisplay updated to handle RunRulesResult
This effectively replaces the older TestResult usage.

apps/web/utils/actions/ai-rule.ts (4)

49-54: Input validation enhancement looks good!

The refactoring improves type safety by:

  1. Using a validated request body with runRulesBody.safeParse
  2. Early return on validation failure
  3. Clean destructuring of validated data

77-89: Good optimization for test scenarios!

The conditional database query based on isTest flag is an excellent performance optimization. When running tests, we skip the unnecessary database lookup for existing rules.


507-510: Improved error logging with context!

The addition of user email context to error logs is a great improvement for debugging and monitoring. This will help track down user-specific issues more effectively.

Also applies to: 526-526, 530-530, 674-677


Line range hint 103-108: Verify error handling in runRulesOnMessage

The function call looks correct, but we should ensure proper error handling in the downstream runRulesOnMessage function since we're passing important parameters like isTest.

✅ Verification successful

Error handling is properly implemented in runRulesOnMessage and its dependencies

The implementation shows appropriate error handling throughout the function chain:

  • The main runRulesOnMessage function has proper error propagation
  • Database operations in upsertExecutedRule have explicit error handling for unique constraint violations
  • Other errors are properly propagated up the call stack
  • The function properly handles both successful and skipped rule executions
  • Test mode (isTest) is properly handled to prevent unwanted side effects
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check error handling in runRulesOnMessage implementation
ast-grep --pattern 'function runRulesOnMessage($_) {
  $$$
  try {
    $$$
  } catch $_
}'

Length of output: 92


Script:

#!/bin/bash
# Let's try to find the implementation of runRulesOnMessage using ripgrep
rg "runRulesOnMessage" -A 10

Length of output: 4957


Script:

#!/bin/bash
# Let's check the implementation of runRulesOnMessage in the specific file
cat apps/web/utils/ai/choose-rule/run-rules.ts

Length of output: 5187

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 (1)
apps/web/app/(app)/automation/TestRules.tsx (1)

146-152: Incrementally applying rules to all messages
The loop calls onRun for each message, respecting rerun only when needed. As a good-to-have refactor, you might consider concurrency controls (e.g., running multiple tests at once up to a certain limit) to improve performance.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4cc7b1f and caf2ff3.

📒 Files selected for processing (6)
  • apps/web/app/(app)/automation/BulkRunRules.tsx (2 hunks)
  • apps/web/app/(app)/automation/Pending.tsx (1 hunks)
  • apps/web/app/(app)/automation/TestRules.tsx (12 hunks)
  • apps/web/utils/actions/ai-rule.ts (8 hunks)
  • apps/web/utils/actions/validation.ts (1 hunks)
  • apps/web/utils/ai/choose-rule/run-rules.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/web/utils/actions/validation.ts
  • apps/web/app/(app)/automation/BulkRunRules.tsx
  • apps/web/utils/ai/choose-rule/run-rules.ts
🔇 Additional comments (33)
apps/web/app/(app)/automation/Pending.tsx (1)

181-181: Validate usage of the new message prop
Providing the full message object to <RuleCell> is a sensible approach if you need more context for rule-related operations. Confirm that <RuleCell> safely handles and uses only the required parts of the message to avoid potential overhead.

apps/web/app/(app)/automation/TestRules.tsx (20)

20-20: No issues with the new import
The RefreshCcwIcon import from "lucide-react" cleanly integrates into the code to facilitate refresh or rerun actions.


31-31: Confirm correct references to runRulesAction and testAiCustomContentAction
The newly imported actions appear aligned with the usage in this file.


38-38: Appropriate type-only import
Importing RunRulesResult as a type limits bundled code size and improves clarity. Good practice.


50-50: New BulkRunRules import
The BulkRunRules component likely facilitates applying rules en masse. Ensure it handles edge cases when messages are unavailable.


62-62: Explicitly passing testMode to <TestRulesContent>
This prop-driven approach cleanly differentiates between test vs. apply modes.


74-74: Function signature updated to accept testMode
This is a straightforward prop pattern. Ensure that all internal logic requiring test mode references this boolean consistently.


115-117: New states for managing run status
The addition of isRunningAllRef, isRunningAll, and isRunning enables granular control over bulk rule execution. This looks good for controlling UI states.


118-118: Tracking results in state
Using a Record<string, RunRulesResult> allows storing the outcome for each message. This is appropriate for quick lookups based on message ID.


120-144: Robust onRun function with error handling
• The code clearly sets isRunning[message.id] to indicate loading.
• It uses toastError to report issues, then toggles the running state off upon completion.
• Returning the rule evaluation result via setResults is consistent and user-friendly.


159-160: Handle start
The method clearly sets the isRunningAll states to begin the bulk process. No issues found.


164-165: Handle stop
Stops the bulk process and resets the running state. Straightforward approach.


171-177: Conditional rendering for Start/Stop buttons
This design choice provides an intuitive way for users to toggle bulk rule testing.


178-185: Differentiating button text with testMode
"Test All" vs. "Run on All" clarifies user intent. This is a clean, user-friendly approach.


188-188: Showing a custom form in test mode
Conditionally rendering this button helps keep the UI streamlined and only shows the form when AI-based rules are available.


201-201: Conditional display of TestRulesForm
Combining hasAiRules, showCustomForm, and testMode ensures that only relevant users see the custom rule test form.


224-227: Passing run states & methods
These props (isRunning, result, onRun, testMode) cleanly separate presentation from logic, keeping the row component focused.


303-313: Extending TestRulesContentRow with new props
The added destructured props are coherent. Ensure that all references to isRunning, result, onRun, and testMode are safely used.


318-318: Conditionally applying pulse styling
This visual feedback is good for indicating an ongoing operation. No concerns noted.


331-352: Enhanced UI for results and rerun
• The existing badge clarifies whether a rule had already been applied.
• Offering a rerun button is consistent with the test/apply paradigm.
• The ReportMistake integration is also a great feature to refine AI accuracy.


372-372: New or updated TestResultDisplay export
Centralizing result display logic fosters reusability. The hover logic neatly shows more details.

apps/web/utils/actions/ai-rule.ts (12)

16-16: Refined import for RunRulesResult
This import clarifies the function return type, improving type-safety.


28-28: Importing ActionError
Including ActionError identifies error responses more precisely. Good addition for typed error handling.


34-35: Utilizing runRulesBody and RunRulesBody
This schema-based approach strengthens input validation and ensures robust type usage.


52-57: runRulesAction validation step
Using runRulesBody.safeParse to validate unsafeBody is a security best practice that prevents malformed requests.


79-99: Conditional fetch of executedRule
Skipping the database query when isTest or rerun is true saves resources and clarifies logic flow.


102-116: Return existing rule
If an executedRule is found, the code returns the existing data. This prevents re-running the same logic unnecessarily.


Line range hint 120-144: Running rules on the parsed message
The function now calls runRulesOnMessage with isTest included. This centralizes logic for both test and standard rule runs, reducing code duplication.


156-157: Testing AI content with runRulesOnMessage
By setting isTest: true, the logic remains consistent with other rule-running scenarios. Nicely unifies the approach.


524-527: Logging validation errors
A thorough log entry helps diagnose issues when input validation fails.


543-543: Ensure user existence
Returning { error: "User not found" } if user is missing is an appropriate safeguard.


547-547: Validate user email
Exiting early if user email is not found is essential for avoiding null reference errors downstream.


691-694: Handling missing rule ID in edited rules
The error log clarifies debugging if the AI prompt references a rule without an ID. This is beneficial for diagnosing prompt generation issues.

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: 1

🧹 Nitpick comments (11)
apps/web/utils/queue/email-actions.ts (1)

16-17: Consider using optional chaining for safer array access.

While the early return is good practice, the array access could be safer.

Consider this safer alternative:

-      const message = thread.messages?.[thread.messages.length - 1];
+      const message = thread.messages?.at(-1);

This uses the at() method which is safer for array bounds and more idiomatic.

apps/web/app/(app)/automation/TestRules.tsx (3)

74-74: Consider using a discriminated union type for component props

The boolean testMode prop could be replaced with a more explicit discriminated union type to better represent the component's modes and prevent potential confusion.

-export function TestRulesContent({ testMode }: { testMode: boolean }) {
+type TestRulesContentMode = { mode: 'test' } | { mode: 'process' };
+export function TestRulesContent({ mode }: TestRulesContentMode) {

This would make the component's purpose clearer and provide better type safety when used.


136-139: Improve type safety by removing type assertion

The type assertion as RunRulesResult could be replaced with proper type validation.

-        setResults((prev) => ({
-          ...prev,
-          [message.id]: result as RunRulesResult,
-        }));
+        if ('rule' in result || ('reason' in result && !('error' in result))) {
+          setResults((prev) => ({
+            ...prev,
+            [message.id]: result,
+          }));
+        }

171-185: Consider extracting action buttons into a separate component

The action buttons logic could be extracted into a reusable component to improve maintainability and reduce duplication.

+const ActionButtons = ({ 
+  isRunningAll, 
+  testMode, 
+  onStop, 
+  onRunAll 
+}: { 
+  isRunningAll: boolean;
+  testMode: boolean;
+  onStop: () => void;
+  onRunAll: () => void;
+}) => (
+  <div className="flex items-center gap-2">
+    {isRunningAll ? (
+      <Button onClick={onStop} variant="outline">
+        <PauseIcon className="mr-2 h-4 w-4" />
+        Stop
+      </Button>
+    ) : (
+      <Button onClick={onRunAll}>
+        <BookOpenCheckIcon className="mr-2 h-4 w-4" />
+        {testMode ? "Test All" : "Run on All"}
+      </Button>
+    )}
+    {!testMode && <BulkRunRules />}
+  </div>
+);

This would make the main component cleaner and the button logic more reusable.

apps/web/utils/ai/group/find-newsletters.ts (1)

29-33: Ensure case-insensitive matching if email addresses may vary in letter-case.
If the from field or userEmail might appear in uppercase or mixed case, using .toLowerCase() before the includes check can help ensure no false negatives.

- !from.includes(userEmail),
+ !from.toLowerCase().includes(userEmail.toLowerCase()),
apps/web/utils/ai/group/find-receipts.ts (1)

56-56: Consider case-insensitive filtering for user emails.
Use .toLowerCase() on both sender and userEmail to eliminate potential mismatch if either is in uppercase form.

-      ) && !sender.includes(userEmail),
+      ) && !sender.toLowerCase().includes(userEmail.toLowerCase()),
apps/web/utils/actions/group.ts (5)

178-182: Confirm that newsletterSenders is comprehensive.
The new filtering based on userEmail is correct. However, make sure newsletterSenders includes all relevant domains so that the query effectively catches all newsletters.

Would you like me to open a new GitHub issue proposing a curated list of newsletters?


Line range hint 207-221: Check for large request volumes.
Frequent calls to findReceipts fetching up to 100 results might cause performance bottlenecks if the user has a large mailbox. Consider caching or pagination strategies if usage grows.


Line range hint 250-281: Add user awareness for different group types.
The error message "{ error: 'Group not found' }" is correct, but consider surfacing more context to users if possible (e.g., "Group for user X not found"). This can help with auditing or debugging.


314-316: Handle empty results from findNewsletters.
In regenerateNewsletterGroup, if findNewsletters returns an empty array, the user might not receive any updates. Consider adding logs or notifications if no newsletters are found.


334-336: Similarly handle empty results from findReceipts.
As with newsletters, consider logging when no receipts are found to keep the user informed.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between caf2ff3 and ca9fdd1.

📒 Files selected for processing (6)
  • apps/web/app/(app)/automation/TestRules.tsx (12 hunks)
  • apps/web/components/CrispChat.tsx (1 hunks)
  • apps/web/utils/actions/group.ts (9 hunks)
  • apps/web/utils/ai/group/find-newsletters.ts (2 hunks)
  • apps/web/utils/ai/group/find-receipts.ts (2 hunks)
  • apps/web/utils/queue/email-actions.ts (1 hunks)
🔇 Additional comments (7)
apps/web/components/CrispChat.tsx (1)

11-11: Hide Crisp chat on mobile devices

Using Crisp.setHideOnMobile(true) after Crisp.configure is a straightforward and valid way to hide the Crisp chat widget on smaller screens. This approach should enhance the mobile user experience, reducing clutter and potential layout issues.

apps/web/utils/queue/email-actions.ts (2)

18-23: Well-structured parameter object with clear intent.

The updated runRulesAction call with named parameters improves readability and maintainability. The isTest: false flag aligns well with the PR's objective of switching from Test to Process functionality.


9-9: Parameter rename improves clarity.

The rename from force to rerun better describes the parameter's purpose.

Let's verify all call sites have been updated:

✅ Verification successful

Parameter rename is safe and all call sites are updated

All call sites of runAiRules have been updated to use boolean literals (true/false) as arguments, which is compatible with the renamed parameter. Found in:

  • apps/web/app/(app)/automation/BulkRunRules.tsx: Using false
  • apps/web/components/email-list/EmailList.tsx: Using both true and false
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining usage of the old parameter name
rg -l "runAiRules\([^)]*force[^)]*\)" --type ts

Length of output: 49


Script:

#!/bin/bash
# Let's try a broader search to find all usages of runAiRules
rg "runAiRules\(" --type ts -A 2

Length of output: 849

apps/web/utils/ai/group/find-newsletters.ts (1)

15-15: Add defensive checks for userEmail.
Before using userEmail, consider validating that it is not null or empty. This ensures robust handling in cases where the session might not provide a valid email.

You can run a quick search to confirm that all callers of findNewsletters pass a valid, non-empty string:

apps/web/utils/ai/group/find-receipts.ts (1)

39-43: Suggest adding null check for userEmail.
Ensure that userEmail is checked or enforced to be a valid string before usage to avoid unexpected runtime errors.

apps/web/utils/actions/group.ts (2)

Line range hint 164-182: Add consistent error handling for missing or invalid session user email.
The logic returns { error: "Not logged in" } if session?.user.email is missing. Ensure there’s a consistent approach in your app to manage this scenario (e.g., redirecting the user to a login page).


107-125: Avoid potential property access on undefined user.email.
Since user.email! is used, confirm that user indeed has a valid email. If there's a scenario where user might be missing an email, the code can fail.

✅ Verification successful

Let me analyze the code snippets to verify the concern about user.email! usage.


Let me try a different search pattern to find the relevant code context.


Let me check how the user object is obtained and validated before this usage.


Based on the code context, I can now provide the final response:

Non-null assertion on user.email is safe here
The code is safe because the user object is obtained from a database query with proper validation. Before user.email! is used:

  1. The user is fetched with prisma.user.findUnique()
  2. There's an explicit check if (!user) return { error: "User not found" }
  3. The user parameter is typed with Pick<User, "email">, ensuring email exists
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
#!/bin/bash
# Searching for possible user objects usage to ensure that user.email is always non-null before usage
rg -A 5 'user\.email'

Length of output: 69917


Script:

#!/bin/bash
# Let's check how user object is obtained and validated before this code
rg -B 10 "group\.ts.*filter\(\(sender\) => !sender\.includes\(user\.email!\)\)"

Length of output: 81


Script:

#!/bin/bash
# Let's find the context around the user.email! usage in group.ts
rg -B 10 "sender\.includes\(user\.email!" apps/web/utils/actions/group.ts

Length of output: 337


Script:

#!/bin/bash
# Let's find the function definition and user object initialization
rg -B 20 "generateGroupItemsFromPrompt" apps/web/utils/actions/group.ts

Length of output: 2191

Comment on lines +146 to 154
const handleRunAll = async () => {
handleStart();

for (const message of messages) {
if (!isTestingAllRef.current) break;
if (testResults[message.id]) continue;
await onTest(message);
if (!isRunningAllRef.current) break;
if (results[message.id]) continue;
await onRun(message);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance error handling for bulk operations

The bulk operation could benefit from better error handling and progress tracking.

 const handleRunAll = async () => {
   handleStart();
+  const errors: Array<{ messageId: string; error: string }> = [];
 
   for (const message of messages) {
     if (!isRunningAllRef.current) break;
     if (results[message.id]) continue;
-    await onRun(message);
+    try {
+      await onRun(message);
+    } catch (error) {
+      errors.push({ 
+        messageId: message.id, 
+        error: error instanceof Error ? error.message : 'Unknown error' 
+      });
+    }
   }
 
+  if (errors.length > 0) {
+    toastError({
+      title: `Failed to process ${errors.length} message(s)`,
+      description: "Check the console for details",
+    });
+    console.error('Bulk operation errors:', errors);
+  }
+
   handleStop();
 };

This change would:

  1. Track errors during bulk operations
  2. Continue processing even if individual items fail
  3. Provide feedback about failed operations
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleRunAll = async () => {
handleStart();
for (const message of messages) {
if (!isTestingAllRef.current) break;
if (testResults[message.id]) continue;
await onTest(message);
if (!isRunningAllRef.current) break;
if (results[message.id]) continue;
await onRun(message);
}
const handleRunAll = async () => {
handleStart();
const errors: Array<{ messageId: string; error: string }> = [];
for (const message of messages) {
if (!isRunningAllRef.current) break;
if (results[message.id]) continue;
try {
await onRun(message);
} catch (error) {
errors.push({
messageId: message.id,
error: error instanceof Error ? error.message : 'Unknown error'
});
}
}
if (errors.length > 0) {
toastError({
title: `Failed to process ${errors.length} message(s)`,
description: "Check the console for details",
});
console.error('Bulk operation errors:', errors);
}
handleStop();
};

@elie222 elie222 merged commit 7384272 into main Jan 5, 2025
3 of 4 checks passed
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