-
Notifications
You must be signed in to change notification settings - Fork 332
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
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
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 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. 📒 Files selected for processing (1)
WalkthroughThe 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 Changes
Possibly Related PRs
Poem
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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
isfalse
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 updatingvalue="test"
tovalue="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
: Addrel="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 addrel="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 foronRun
.
Catching potential errors viatoastError
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 labelThe 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
📒 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"
istrue
, 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.
PassingtestMode={!applyMode}
toTestRulesContent
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 ofBulkRunRules
.
ImportingBulkRunRules
here aligns the “run” logic. This keeps “process” and “test” modes distinct while reusing logic effectively.
60-60
: Consistent usage oftestMode
prop.
PassingtestMode
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 toisRunningAll
,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 ofBulkRunRules
.
HidingBulkRunRules
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 whentestMode
and AI rules exist is a neat approach to reduce potential confusion for non-AI rules.
211-214
: Descriptive prop usage.
PassingisRunning
,result
,onRun
, andtestMode
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 ontestMode
helps unify UI logic and reduces duplication.apps/web/components/Toggle.tsx (3)
1-1
: LGTM! Well-structured interface extensionThe switch to
Field
component and addition oflabelRight
prop provides better flexibility for the toggle layout while maintaining type safety.Also applies to: 9-9
17-17
: LGTM! Clean props destructuringThe props destructuring is properly updated to include the new
labelRight
prop.
Line range hint
1-57
: Verify the toggle implementation in Process componentThe 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
There was a problem hiding this 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 configurableInstead 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 typesThe 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 accessibilityThe 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 interfaceConsider 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; +}: TestRulesContentRowPropsapps/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 infrom
or a length limit onsubject
) to prevent malformed input.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 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 usingrunRulesOnMessage
.
32-33
: Adopt schema-based validation for maintainability
ImportingrunRulesBody
andRunRulesBody
enables more robust and consistent input validation.
79-90
: Review test mode logic
Skipping the database lookup ifisTest
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
PassingisTest
directly torunRulesOnMessage
keeps the flow consistent for testing vs. production scenarios.
140-141
: Explicitly declare test execution
UsingisTest: 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
Passingforce
, andisTest: false
aligns with the newrunRulesAction
parameter structure, ensuring consistency.
There was a problem hiding this 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
: InvokingrunRulesAction
withforce
andisTest: 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 creationThe 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
📒 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 newRunRulesResult
import looks good.
No further action needed.
27-27
: Switch fromtestAiAction
torunRulesAction
is consistent with the new approach.
No issues found.
48-48
: Newly importedParsedMessage
type
This strengthens the type safety for message usage.
59-59
: Refined parameter type toRunRulesResult | null
.
Good alignment with the new result structure.
103-103
: Matchingresult: RunRulesResult | null
Ensures consistency across components.
248-248
:message
param introduced inAIFixView
.
This ensures we have the full message data, which is helpful for AI-based fixes.
275-275
: Propmessage
strongly typed asParsedMessage
.
This improves clarity and prevents runtime errors.
285-285
: Reinforced typing withmessage: ParsedMessage
.
No issues found.
314-314
: Rendering<SuggestedFix>
with fullmessage
prop.
No concerns; it ensures consistent usage of theParsedMessage
.
332-332
:RuleMismatch
now usesRunRulesResult | null
.
Continues the updated result pattern.
458-458
:ManualFixView
extractsresult
asRunRulesResult | null
.
No issues; consistent usage.
499-499
: Including<RerunTestButton>
insideManualFixView
.
This is a good addition to allow quick re-checking after manual fixes.
563-563
:AIFixForm
updated to acceptresult: RunRulesResult | null
.
Ensures usage of the correct structure from the consolidated rules approach.
646-646
: Calling<SuggestedFix>
insideAIFixForm
.
Provides immediate AI-based suggestions to the user.
658-658
: NewSuggestedFix
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 offunction 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 withrunRulesAction
.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 conditionif (!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 returnsPromise<RunRulesResult>
Well-aligned with the new type. No issues found.apps/web/app/(app)/automation/TestRules.tsx (21)
30-30
: Use ofrunRulesAction
Replacing older testing logic is consistent with the new naming. No issues found here.
37-37
: New import forRunRulesResult
Follows the rename fromTestResult
.
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 variablesisRunningAll
,isRunning
,results
Improves clarity over the old "testing" naming.
118-141
:onRun
function: ReplacesonTest
logic
Construct is sensible: sets loading states, invokesrunRulesAction
, updates results.
143-149
:handleRunAll
loops over messages
Relevant approach for mass processing. No immediate issues.
156-157
:handleStart
setsisRunningAll
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
: DisplaysTestRulesForm
whenshowCustomForm
andtestMode
User can quickly test the AI logic with a custom input.
221-224
: Passing props toTestRulesContentRow
Streamlines relevant info for each message. No concerns.
251-251
:testResult
state inTestRulesForm
Stores the outcome oftestAiCustomContentAction
.
300-303
: InTestRulesContentRow
, newisRunning
andresult
parameters
Makes the row aware of loading state and outcome.
307-310
: Enhanced signature withresult: RunRulesResult
Consistent with the broader type changes.
315-315
: Conditional styling whileisRunning
A user-friendly indicator. No issues found.
328-333
: Displaying test results or theReportMistake
button
Clear user workflow for verifying rules or reporting mistakes.
336-338
: Render "Test" or "Run" depending ontestMode
Good UI distinction for different usage scenarios.
352-352
:TestResultDisplay
updated to handleRunRulesResult
This effectively replaces the olderTestResult
usage.apps/web/utils/actions/ai-rule.ts (4)
49-54
: Input validation enhancement looks good!The refactoring improves type safety by:
- Using a validated request body with
runRulesBody.safeParse
- Early return on validation failure
- 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 runRulesOnMessageThe function call looks correct, but we should ensure proper error handling in the downstream
runRulesOnMessage
function since we're passing important parameters likeisTest
.✅ 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 10Length 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.tsLength of output: 5187
There was a problem hiding this 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 callsonRun
for each message, respectingrerun
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
📒 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 newmessage
prop
Providing the fullmessage
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
TheRefreshCcwIcon
import from "lucide-react" cleanly integrates into the code to facilitate refresh or rerun actions.
31-31
: Confirm correct references torunRulesAction
andtestAiCustomContentAction
The newly imported actions appear aligned with the usage in this file.
38-38
: Appropriate type-only import
ImportingRunRulesResult
as a type limits bundled code size and improves clarity. Good practice.
50-50
: NewBulkRunRules
import
TheBulkRunRules
component likely facilitates applying rules en masse. Ensure it handles edge cases when messages are unavailable.
62-62
: Explicitly passingtestMode
to<TestRulesContent>
This prop-driven approach cleanly differentiates between test vs. apply modes.
74-74
: Function signature updated to accepttestMode
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 ofisRunningAllRef
,isRunningAll
, andisRunning
enables granular control over bulk rule execution. This looks good for controlling UI states.
118-118
: Tracking results in state
Using aRecord<string, RunRulesResult>
allows storing the outcome for each message. This is appropriate for quick lookups based on message ID.
120-144
: RobustonRun
function with error handling
• The code clearly setsisRunning[message.id]
to indicate loading.
• It usestoastError
to report issues, then toggles the running state off upon completion.
• Returning the rule evaluation result viasetResults
is consistent and user-friendly.
159-160
: Handle start
The method clearly sets theisRunningAll
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 withtestMode
"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 ofTestRulesForm
CombininghasAiRules
,showCustomForm
, andtestMode
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
: ExtendingTestRulesContentRow
with new props
The added destructured props are coherent. Ensure that all references toisRunning
,result
,onRun
, andtestMode
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
• Theexisting
badge clarifies whether a rule had already been applied.
• Offering a rerun button is consistent with the test/apply paradigm.
• TheReportMistake
integration is also a great feature to refine AI accuracy.
372-372
: New or updatedTestResultDisplay
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 forRunRulesResult
This import clarifies the function return type, improving type-safety.
28-28
: ImportingActionError
IncludingActionError
identifies error responses more precisely. Good addition for typed error handling.
34-35
: UtilizingrunRulesBody
andRunRulesBody
This schema-based approach strengthens input validation and ensures robust type usage.
52-57
:runRulesAction
validation step
UsingrunRulesBody.safeParse
to validateunsafeBody
is a security best practice that prevents malformed requests.
79-99
: Conditional fetch ofexecutedRule
Skipping the database query whenisTest
orrerun
istrue
saves resources and clarifies logic flow.
102-116
: Return existing rule
If anexecutedRule
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 callsrunRulesOnMessage
withisTest
included. This centralizes logic for both test and standard rule runs, reducing code duplication.
156-157
: Testing AI content withrunRulesOnMessage
By settingisTest: 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.
There was a problem hiding this 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 propsThe 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 assertionThe 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 componentThe 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 thefrom
field oruserEmail
might appear in uppercase or mixed case, using.toLowerCase()
before theincludes
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 bothsender
anduserEmail
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 thatnewsletterSenders
is comprehensive.
The new filtering based onuserEmail
is correct. However, make surenewsletterSenders
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 tofindReceipts
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 fromfindNewsletters
.
InregenerateNewsletterGroup
, iffindNewsletters
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 fromfindReceipts
.
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
📒 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 devicesUsing
Crisp.setHideOnMobile(true)
afterCrisp.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. TheisTest: 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
torerun
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
: Usingfalse
apps/web/components/email-list/EmailList.tsx
: Using bothtrue
andfalse
🏁 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 tsLength of output: 49
Script:
#!/bin/bash # Let's try a broader search to find all usages of runAiRules rg "runAiRules\(" --type ts -A 2Length of output: 849
apps/web/utils/ai/group/find-newsletters.ts (1)
15-15
: Add defensive checks foruserEmail
.
Before usinguserEmail
, consider validating that it is notnull
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 foruserEmail
.
Ensure thatuserEmail
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" }
ifsession?.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 undefineduser.email
.
Sinceuser.email!
is used, confirm thatuser
indeed has a validuser
might be missing an✅ 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. Beforeuser.email!
is used:
- The user is fetched with
prisma.user.findUnique()
- There's an explicit check
if (!user) return { error: "User not found" }
- 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.tsLength 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.tsLength of output: 2191
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); | ||
} | ||
|
There was a problem hiding this comment.
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:
- Track errors during bulk operations
- Continue processing even if individual items fail
- 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.
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(); | |
}; |
Summary by CodeRabbit
Release Notes
New Features
User Interface Changes
Usability Improvements