Skip to content

Add UI for cursor rules style prompt#227

Merged
elie222 merged 23 commits intomainfrom
rules-large-prompt
Sep 19, 2024
Merged

Add UI for cursor rules style prompt#227
elie222 merged 23 commits intomainfrom
rules-large-prompt

Conversation

@elie222
Copy link
Owner

@elie222 elie222 commented Sep 17, 2024

Summary by CodeRabbit

  • New Features

    • Introduced unit tests for the aiDiffRules function to validate rule comparison and error handling.
    • Added unit tests for the aiPromptToRules function to ensure accurate conversion of prompts into structured rules.
    • Enhanced the functionality for saving user-defined rules prompts with improved data validation.
    • Implemented a comprehensive schema for rule creation to ensure structured validation.
    • Improved automation logic for managing user rules, ensuring appropriate actions are automated.
    • Launched a new React component for users to create and manage email handling prompts with real-time feedback.
  • Bug Fixes

    • Enhanced validation for saving user rules prompts to ensure data integrity.
  • Chores

    • Updated ESLint configuration for better TypeScript support and code quality.

@vercel
Copy link

vercel bot commented Sep 17, 2024

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

Name Status Preview Updated (UTC)
inbox-zero ✅ Ready (Inspect) Visit Preview Sep 19, 2024 3:12am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 17, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

The changes introduce updates to the ESLint configuration for Next.js, enhancing linting capabilities and code quality. New test files validate the functionality of aiDiffRules and aiPromptToRules, ensuring accurate rule generation and error handling. Enhancements in the ai-rule.ts file include new functions for saving user rules and improved organization of existing functions. A new schema for rule creation is defined, and utility functions for converting prompts and analyzing rule differences are introduced.

Changes

File Change Summary
apps/web/.eslintrc.json Updated ESLint configuration to extend from "@inboxzero/eslint-config/next.js" for Next.js support.
apps/web/__tests__/ai-choose-rule.test.ts, apps/web/__tests__/ai-diff-rules.test.ts, apps/web/__tests__/ai-prompt-to-rules.test.ts Added unit tests for aiChooseRule, aiDiffRules, and aiPromptToRules, validating rule generation, categorization, and error handling.
apps/web/utils/actions/ai-rule.ts Added saveRulesPromptAction for saving user rules prompts; refactored createAutomationAction and createRule.
apps/web/utils/ai/rule/prompt-to-rules.ts, apps/web/utils/ai/rule/diff-rules.ts Added aiPromptToRules for converting prompts into structured rules and aiDiffRules for analyzing differences between prompt files.
apps/web/utils/ai/rule/create-rule-schema.ts Introduced createRuleSchema for validating rule properties and structure.
apps/web/utils/ai/rule/create-rule.ts Modularized the schema import for createRuleSchema, improving organization and maintainability.
apps/web/app/(app)/automation/RulesPrompt.tsx Introduced RulesPrompt component for user interaction with email handling prompts.
packages/eslint-config/next.js Enhanced ESLint configuration with additional style guide extensions and updated parser options.

Possibly related PRs

  • AI prompt for each generated argument #191: Changes in handling AI-generated fields and actions may relate to the aiPromptToRules function's role in generating structured rules based on user prompts.
  • Inbox Zero API #203: Introduces an API for managing inbox data, which could connect with the main PR's focus on improving code quality and maintainability.
  • Add support for Anthropic #215: Addition of support for Anthropic may connect with the AI functionalities in the main PR, particularly in rule generation.
  • Block emails user unsubscribed from #218: Functionality to block unsubscribed emails may relate to the main PR's focus on enhancing user experience and functionality.

Poem

🐇 In the garden where prompts take flight,
New rules are crafted, a wondrous sight.
With schemas and tests, we pave the way,
For emails to dance and rules to play.
So hop along, let the magic unfurl,
In the world of prompts, watch creativity swirl! 🌼


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 generate interesting stats about this repository and render them as a table.
    -- @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 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: 3

Outside diff range and nitpick comments (1)
apps/web/utils/actions/ai-rule.ts (1)

26-29: Use import type for type-only imports.

The static analysis tool suggests using import type for the SaveRulesPromptBody type import since it's only used as a type.

Importing types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.

Apply this diff to optimize the import:

-import {
-  saveRulesPromptBody,
-  SaveRulesPromptBody,
-} from "@/utils/actions/validation";
+import { saveRulesPromptBody } from "@/utils/actions/validation";
+import type { SaveRulesPromptBody } from "@/utils/actions/validation";
Tools
Biome

[error] 25-29: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between a0ba09d and d1b86cf.

Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
Files selected for processing (7)
  • apps/web/app/(app)/automation/RulesPrompt.tsx (1 hunks)
  • apps/web/app/(app)/automation/page.tsx (3 hunks)
  • apps/web/components/ui/scroll-area.tsx (1 hunks)
  • apps/web/package.json (1 hunks)
  • apps/web/prisma/schema.prisma (1 hunks)
  • apps/web/utils/actions/ai-rule.ts (2 hunks)
  • apps/web/utils/actions/validation.ts (1 hunks)
Additional context used
Biome
apps/web/app/(app)/automation/RulesPrompt.tsx

[error] 17-21: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 73-73: This hook does not specify all of its dependencies: getValues

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 73-73: This hook does not specify all of its dependencies: setValue

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 142-142: Avoid using the index of an array as key property in an element.

This is the source of the key value.

The order of the items may change, and this also affects performances and component state.
Check the React documentation.

(lint/suspicious/noArrayIndexKey)

apps/web/utils/actions/ai-rule.ts

[error] 25-29: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

Additional comments not posted (10)
apps/web/components/ui/scroll-area.tsx (2)

8-24: LGTM!

The ScrollArea component is well-implemented and follows best practices:

  • It correctly uses the Radix UI primitives to create a scrollable area.
  • The cn utility function is used appropriately to manage class names.
  • The component is properly typed using React.forwardRef and the correct type definitions.
  • It correctly passes the ref and props to the underlying Radix UI component.
  • It correctly wraps its children within the viewport.
  • It correctly includes the ScrollBar component and the ScrollAreaPrimitive.Corner component.

26-46: LGTM!

The ScrollBar component is well-implemented and follows best practices:

  • It correctly uses the Radix UI primitives to create the scrollbar.
  • The cn utility function is used appropriately to manage class names.
  • The component is properly typed using React.forwardRef and the correct type definitions.
  • It correctly passes the ref and props to the underlying Radix UI component.
  • It correctly includes the thumb element.
  • It correctly supports both vertical and horizontal orientations.
apps/web/utils/actions/validation.ts (1)

77-78: LGTM!

The new Zod schema saveRulesPromptBody and its corresponding type SaveRulesPromptBody are correctly defined and exported. The schema provides a structured way to validate the request body for saving rules prompts, improving data integrity and type safety.

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

19-19: LGTM!

The import statement for the RulesPrompt component is correct and necessary for its usage in the AutomationPage component.


Line range hint 31-54: LGTM!

The addition of the "Rules" tab and the rendering of the RulesPrompt component are implemented correctly and consistently with the existing tab structure and content rendering. The code segment maintains a consistent layout and styling with the other tabs and their corresponding content.

apps/web/package.json (1)

42-42: LGTM!

The addition of the @radix-ui/react-scroll-area dependency looks good. Just make sure to properly integrate and test the new scrollable area component in the application.

apps/web/app/(app)/automation/RulesPrompt.tsx (2)

49-155: LGTM!

The RulesPrompt component is well-implemented and follows best practices:

  • It uses react-hook-form for efficient form handling and validation.
  • The onSubmit function correctly handles form submission and displays appropriate success/error messages.
  • The addExamplePrompt function enhances user experience by allowing users to easily add example prompts to their input.
  • The component's layout is clean and organized using the Card component and its subcomponents.

Great job!

Tools
Biome

[error] 73-73: This hook does not specify all of its dependencies: getValues

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 73-73: This hook does not specify all of its dependencies: setValue

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 142-142: Avoid using the index of an array as key property in an element.

This is the source of the key value.

The order of the items may change, and this also affects performances and component state.
Check the React documentation.

(lint/suspicious/noArrayIndexKey)


1-48: LGTM!

The remaining code segments, including imports, type definitions, and the examplePrompts array, are well-organized and follow the project's conventions. The examplePrompts array provides a good set of example prompts for users to choose from, enhancing the user experience.

Also applies to: 56-72, 79-139, 150-155

Tools
Biome

[error] 17-21: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

apps/web/prisma/schema.prisma (1)

73-73: LGTM!

The addition of the optional rulesPrompt field to the User model is a valid change to support storing user-specific rules or prompts. The field name and type are appropriate, and the change does not introduce any apparent issues or inconsistencies in the schema.

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

399-413: LGTM!

The saveRulesPromptAction function follows a logical flow of authentication, validation, and database update. It handles error scenarios appropriately and ensures data integrity.

The addition of this function enhances the functionality of the module by allowing users to save their rules prompts, thereby improving user interaction and data management within the application.

Comment on lines 17 to 21
import { Input } from "@/components/Input";
import {
saveRulesPromptBody,
SaveRulesPromptBody,
} from "@/utils/actions/validation";
Copy link
Contributor

Choose a reason for hiding this comment

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

Use import type for type-only imports.

The SaveRulesPromptBody import is only used as a type. Using import type ensures that the type is removed by transpilers and avoids loading unnecessary modules.

Apply this diff to fix the import:

-import {
-  saveRulesPromptBody,
-  SaveRulesPromptBody,
-} from "@/utils/actions/validation";
+import { saveRulesPromptBody } from "@/utils/actions/validation";
+import type { SaveRulesPromptBody } from "@/utils/actions/validation";
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
import { Input } from "@/components/Input";
import {
saveRulesPromptBody,
SaveRulesPromptBody,
} from "@/utils/actions/validation";
import { Input } from "@/components/Input";
import { saveRulesPromptBody } from "@/utils/actions/validation";
import type { SaveRulesPromptBody } from "@/utils/actions/validation";
Tools
Biome

[error] 17-21: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

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

Outside diff range and nitpick comments (1)
apps/web/utils/ai/rule/prompt-to-rules.ts (1)

1-4: Use import type for type-only imports.

The static analysis tool correctly suggests using import type for imports that are only used as types. This ensures that the types are removed by the transpilers and avoids loading unnecessary modules.

Apply this diff to optimize the imports:

-import { z } from "zod";
-import { chatCompletionTools } from "@/utils/llms";
-import { UserAIFields } from "@/utils/llms/types";
+import { z } from "zod";
+import { chatCompletionTools } from "@/utils/llms";
+import type { UserAIFields } from "@/utils/llms/types";
 import { createRuleSchema } from "@/utils/ai/rule/create-rule-schema";
Tools
Biome

[error] 2-3: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between d1b86cf and b6934b1.

Files selected for processing (6)
  • apps/web/tests/ai-prompt-to-rules.test.ts (1 hunks)
  • apps/web/prisma/migrations/20240917021039_rule_prompt/migration.sql (1 hunks)
  • apps/web/utils/actions/ai-rule.ts (2 hunks)
  • apps/web/utils/ai/rule/create-rule-schema.ts (1 hunks)
  • apps/web/utils/ai/rule/create-rule.ts (1 hunks)
  • apps/web/utils/ai/rule/prompt-to-rules.ts (1 hunks)
Additional context used
Biome
apps/web/utils/ai/rule/prompt-to-rules.ts

[error] 2-3: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

apps/web/__tests__/ai-prompt-to-rules.test.ts

[error] 7-7: Don't focus the test.

The 'only' method is often used for debugging or during implementation. It should be removed before deploying to production.
Consider removing 'only' to ensure all tests are executed.
Unsafe fix: Remove focus from test.

(lint/suspicious/noFocusedTests)


[error] 124-126: Prefer for...of instead of forEach.

forEach may lead to performance issues when working with large arrays. When combined with functions like filter or map, this causes multiple iterations over the same type.

(lint/complexity/noForEach)

Additional comments not posted (7)
apps/web/prisma/migrations/20240917021039_rule_prompt/migration.sql (1)

1-2: LGTM!

The migration is clear, concise, and adds a new column rulesPrompt to the User table for storing textual data related to user rules or prompts. The column name is descriptive, and the data type TEXT is appropriate for storing textual data of varying lengths.

apps/web/utils/ai/rule/create-rule.ts (1)

4-4: LGTM!

Moving the createRuleSchema definition to a separate module is a good refactoring decision. It improves code organization and reusability.

apps/web/utils/ai/rule/prompt-to-rules.ts (1)

12-38: LGTM!

The aiPromptToRules function is well-implemented and follows a clear logical flow. It effectively utilizes the chatCompletionTools utility to interact with the AI model and uses Zod for parameter validation, ensuring data integrity.

The function enhances the functionality of the application by automating the rule conversion process, thereby improving efficiency in email management.

apps/web/utils/ai/rule/create-rule-schema.ts (1)

5-67: LGTM! The createRuleSchema is well-defined and provides a robust structure for validating rules.

The schema includes all the necessary properties for creating rules related to email processing. The use of Zod ensures that the data is validated against the defined types and constraints. The detailed descriptions for each property provide clarity on their purpose and usage.

Some key benefits of this schema:

  • The requiresAI property helps prevent the subject line from being set too narrowly by clarifying when AI is required versus when static conditions or groups can be used.
  • The actions property allows for defining multiple actions to be taken when a rule is triggered, providing flexibility in email handling.
  • The staticConditions property enables matching specific email attributes, while the note in the subject field helps ensure proper usage based on the requiresAI value.
  • The optional group property allows for categorizing rules into predefined groups, which can simplify rule management.

Overall, this schema provides a solid foundation for creating and validating rules in the application.

apps/web/__tests__/ai-prompt-to-rules.test.ts (2)

8-127: Excellent test coverage!

The test case comprehensively covers the conversion of a prompt file to rules. It asserts the expected properties of each rule and validates them against the schema. Well done!

Tools
Biome

[error] 124-126: Prefer for...of instead of forEach.

forEach may lead to performance issues when working with large arrays. When combined with functions like filter or map, this causes multiple iterations over the same type.

(lint/complexity/noForEach)


129-139: LGTM!

The test case correctly tests the error handling scenario when provided with an invalid API key. It ensures that the function rejects with an error as expected.

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

400-435: LGTM!

The saveRulesPromptAction function is well-implemented and follows good practices:

  • It properly handles user authentication and returns appropriate errors.
  • It validates the input data using a predefined schema to ensure data integrity.
  • It performs necessary checks on the parsed data and handles empty rulesPrompt case.
  • It retrieves the required user information from the database and ensures data consistency.
  • It updates the user's record in the database with the validated rulesPrompt value.

The function enhances the application's functionality by allowing users to save their rules prompts, improving user interaction and data management.

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

Outside diff range and nitpick comments (2)
apps/web/utils/ai/rule/prompt-to-rules.ts (1)

3-3: Use import type for the UserAIFields import.

The UserAIFields import on line 3 is only used as a type in the function parameter. To ensure that it is removed by the transpilers and avoid loading unnecessary modules, change it to import type:

-import { UserAIFields } from "@/utils/llms/types";
+import type { UserAIFields } from "@/utils/llms/types";

This change aligns with the best practice suggested by the static analysis hint.

Tools
Biome

[error] 2-3: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

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

277-277: Use a template literal instead of string concatenation.

The string concatenation at line 277 is used to create a unique rule name by appending a timestamp to the rule name. Using a template literal instead of string concatenation can improve the readability of the code.

Apply this diff to use a template literal:

-{ ...result, name: result.name + " - " + Date.now() },
+{ ...result, name: `${result.name} - ${Date.now()}` },
Tools
Biome

[error] 277-277: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between b6934b1 and 33d18f6.

Files selected for processing (4)
  • apps/web/tests/ai-prompt-to-rules.test.ts (1 hunks)
  • apps/web/utils/actions/ai-rule.ts (7 hunks)
  • apps/web/utils/ai/rule/create-rule-schema.ts (1 hunks)
  • apps/web/utils/ai/rule/prompt-to-rules.ts (1 hunks)
Additional context used
Biome
apps/web/utils/ai/rule/prompt-to-rules.ts

[error] 2-3: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

apps/web/__tests__/ai-prompt-to-rules.test.ts

[error] 8-8: Don't focus the test.

The 'only' method is often used for debugging or during implementation. It should be removed before deploying to production.
Consider removing 'only' to ensure all tests are executed.
Unsafe fix: Remove focus from test.

(lint/suspicious/noFocusedTests)


[error] 134-136: Prefer for...of instead of forEach.

forEach may lead to performance issues when working with large arrays. When combined with functions like filter or map, this causes multiple iterations over the same type.

(lint/complexity/noForEach)

apps/web/utils/actions/ai-rule.ts

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 277-277: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

Additional comments not posted (10)
apps/web/utils/ai/rule/prompt-to-rules.ts (1)

12-41: LGTM!

The aiPromptToRules function is well-implemented and follows a clear logical flow. It effectively automates the conversion of email management rules from prompt files into a structured format using chatCompletionTools and an AI model.

The function correctly sets up the system message and prompt to guide the AI assistant in parsing the prompt file. It supplies all the necessary information to chatCompletionTools, including the user information, prompt, and a parsing tool description with validated parameters.

The use of the parameters schema ensures that the parsed rules adhere to a well-defined structure, which is then inferred for the return value.

Overall, this function enhances the application's functionality and improves efficiency in email management by providing a structured format for the rules.

apps/web/utils/ai/rule/create-rule-schema.ts (3)

6-6: LGTM!

The name property is correctly defined as a string with a clear description.


7-42: LGTM!

The condition property is correctly defined as an object with the expected properties:

  • type: An enum with the allowed values.
  • aiInstructions: An optional string with a clear description.
  • static: An optional object with from, to, and subject fields.
  • group: An optional enum with the allowed values.

43-79: LGTM!

The actions property is correctly defined as an array of objects with the expected properties:

  • type: A native enum of ActionType.
  • label, to, cc, bcc, subject, content: Optional strings that are transformed to null if they are undefined.

Each property has a clear description.

apps/web/__tests__/ai-prompt-to-rules.test.ts (3)

9-137: LGTM!

The test case logic and assertions are correct and comprehensive. It correctly validates the conversion of prompts to rules and also validates each rule against the schema.

Tools
Biome

[error] 134-136: Prefer for...of instead of forEach.

forEach may lead to performance issues when working with large arrays. When combined with functions like filter or map, this causes multiple iterations over the same type.

(lint/complexity/noForEach)


139-149: LGTM!

The test case correctly validates the error handling of the aiPromptToRules function by mocking the user object with an invalid API key and expecting the function to reject with an error.


134-136: Refactor the for...of loop to use forEach for better performance.

The for...of loop may lead to performance issues when working with large arrays. Consider refactoring it to use forEach instead.

Apply this diff to refactor the loop:

-result.rules.forEach((rule) => {
+for (const rule of result.rules) {
   expect(() => createRuleSchema.parse(rule)).not.toThrow();
-});
+}

Likely invalid or redundant comment.

Tools
Biome

[error] 134-136: Prefer for...of instead of forEach.

forEach may lead to performance issues when working with large arrays. When combined with functions like filter or map, this causes multiple iterations over the same type.

(lint/complexity/noForEach)

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

462-475: LGTM!

The function correctly determines whether actions should be automated based on their types and excludes certain action types like replies, forwards, and send emails from automation, which is a good practice. The use of a Set to efficiently check for the presence of action types is also a nice touch.


Line range hint 214-313: LGTM!

The function correctly handles user authentication, retrieves the necessary user information from the database, creates a rule using the aiCreateRule function, handles the creation of newsletter and receipt groups if the rule is a group rule, creates the rule in the database using the createRule function, and handles duplicate rule names by appending a timestamp to the rule name. The function also returns the ID of the created rule, which is useful for further processing.


288-313: LGTM!

The function correctly creates a rule in the database using the prisma.rule.create function, takes the necessary parameters to create the rule, including the result of the aiCreateRule function, the user ID, and the group ID, and returns the created rule, which is useful for further processing.

Comment on lines 395 to 460
export async function saveRulesPromptAction(
unsafeData: SaveRulesPromptBody,
): Promise<ServerActionResponse> {
const session = await auth();
if (!session?.user.id) return { error: "Not logged in" };

const data = saveRulesPromptBody.parse(unsafeData);

if (!data.rulesPrompt) return { error: "Rules prompt cannot be empty" };

const user = await prisma.user.findUnique({
where: { id: session.user.id },
select: {
aiProvider: true,
aiModel: true,
aiApiKey: true,
email: true,
},
});

if (!user) return { error: "User not found" };
if (!user.email) return { error: "User email not found" };

const parsedRules = await aiPromptToRules({
user: {
...user,
email: user.email,
},
promptFile: data.rulesPrompt,
});

// Save the rules to the database
// await prisma.$transaction(async (tx) => {
// // Update the user's rulesPrompt
// await tx.user.update({
// where: { id: session.user.id },
// data: { rulesPrompt: data.rulesPrompt },
// });

// // Delete existing rules
// await tx.rule.deleteMany({
// where: { userId: session.user.id },
// });

// // Create new rules
// for (const rule of parsedRules.rules) {
// await tx.rule.create({
// data: {
// name: rule.name,
// instructions: "",
// userId: session.user.id,
// type: RuleType.AI,
// actions: {
// createMany: {
// data: rule.actions,
// },
// },
// automate: shouldAutomate(rule.actions),
// runOnThreads: false,
// },
// });
// }
// });

return { success: true };
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Complete the implementation and handle errors.

The function is not fully implemented, as the code for saving the rules to the database is commented out. Please uncomment the code to complete the implementation.

Also, handle any errors that may occur during the execution of the aiPromptToRules function to ensure the function fails gracefully.

Comment on lines +5 to +10
import {
RuleType,
ExecutedRuleStatus,
Action,
ActionType,
} from "@prisma/client";
Copy link
Contributor

Choose a reason for hiding this comment

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

Use import type for type-only imports.

The imports at line range 5-10 are only used as types. Using import type ensures that the types are removed by the transpilers and avoids loading unnecessary modules, which can improve the performance of the application.

Apply this diff to use import type:

-import {
+import type {
   RuleType,
   ExecutedRuleStatus,
   Action,
   ActionType,
 } from "@prisma/client";
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
import {
RuleType,
ExecutedRuleStatus,
Action,
ActionType,
} from "@prisma/client";
import type {
RuleType,
ExecutedRuleStatus,
Action,
ActionType,
} from "@prisma/client";
Tools
Biome

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

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

Outside diff range and nitpick comments (1)
apps/web/utils/actions/ai-rule.ts (1)

251-251: Consider using a template literal for string interpolation.

While string concatenation works, using a template literal is considered a better practice for string interpolation.

Apply this diff to use a template literal:

-{ ...result, name: result.name + " - " + Date.now() },
+{ ...result, name: `${result.name} - ${Date.now()}` },
Tools
Biome

[error] 251-251: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 33d18f6 and a9ecfd0.

Files selected for processing (2)
  • apps/web/utils/actions/ai-rule.ts (6 hunks)
  • apps/web/utils/error.ts (1 hunks)
Additional context used
Biome
apps/web/utils/actions/ai-rule.ts

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 251-251: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

Additional comments not posted (12)
apps/web/utils/error.ts (1)

30-30: LGTM!

The additional type check typeof error === "object" improves the robustness of the isActionError function by ensuring that error is an object before performing the property check. This change enhances the type safety and prevents potential runtime errors when dealing with non-object types.

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

5-10: ** Use import type for type-only imports.**

The imports at line range 5-10 are only used as types. Using import type ensures that the types are removed by the transpilers and avoids loading unnecessary modules, which can improve the performance of the application.

Apply this diff to use import type:

-import {
+import type {
   RuleType,
   ExecutedRuleStatus,
   Action,
   ActionType,
 } from "@prisma/client";
Tools
Biome

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


31-35: LGTM!

The imports are necessary for the functionality introduced in this file and there are no apparent issues.


212-215: LGTM!

The code segment is handling the group ID and rule creation based on the AI-generated rule correctly. The error handling and flow of the code segment are appropriate.


217-237: LGTM!

The createRule function is creating a new rule in the database based on the AI-generated rule correctly. The mapping of the AI-generated rule data to the database fields is appropriate and the use of the shouldAutomate function to determine the value of the automate field is a good approach.


239-260: LGTM!

The safeCreateRule function is a good wrapper around the createRule function to handle errors and ensure that a new rule is created even if the rule name already exists. The error handling and flow of the code segment are appropriate.

Tools
Biome

[error] 251-251: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


Line range hint 262-324: LGTM!

The getGroupId function is handling the group ID based on the AI-generated rule's group condition correctly. The logic for handling the newsletter and receipt groups is appropriate and the error handling and flow of the code segment are good.

Tools
Biome

[error] 251-251: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


407-447: LGTM!

The saveRulesPromptAction function is handling the saving of a user's rules prompt and creating the corresponding rules correctly. The validation and error handling are appropriate and the use of the aiPromptToRules function to parse the rules prompt into rules is a good approach. The updating of the user's rulesPrompt field and the creation of the rules are handled properly.


449-462: LGTM!

The shouldAutomate function is determining whether a set of actions should be automated based on the presence of certain action types correctly. The logic for determining whether to automate the actions is appropriate and the use of a set to check for the presence of action types is an efficient approach.


Line range hint 268-297: LGTM!

The code segment is handling the case where the AI-generated rule's group condition is a newsletter group correctly. The logic for checking if a newsletter group already exists and returning the group ID or an error is appropriate and the creation of a new newsletter group if one doesn't exist is handled properly.

Tools
Biome

[error] 251-251: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


Line range hint 297-324: LGTM!

The code segment is handling the case where the AI-generated rule's group condition is a receipt group correctly. The logic for checking if a receipt group already exists and returning the group ID or an error is appropriate and the creation of a new receipt group if one doesn't exist is handled properly.


430-444: LGTM!

The code segment is handling the parsing of the rules prompt into rules and the creation of the rules correctly. The use of the aiPromptToRules function to parse the rules prompt is appropriate and the looping through the parsed rules and creating each rule using the safeCreateRule function is handled properly. The error handling by returning the result of getGroupId if it's an error is also appropriate.

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

Outside diff range and nitpick comments (1)
apps/web/app/(app)/automation/page.tsx (1)

31-32: Consider the tab order.

The addition of the new "prompt" and "rules" tabs is appropriate and enhances the functionality of the AutomationPage component. However, consider if the current order of the tabs aligns with the desired user flow and prioritization of the features.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between a9ecfd0 and f769a44.

Files selected for processing (2)
  • apps/web/app/(app)/automation/RulesPrompt.tsx (1 hunks)
  • apps/web/app/(app)/automation/page.tsx (2 hunks)
Additional context used
Biome
apps/web/app/(app)/automation/RulesPrompt.tsx

[error] 19-23: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 77-77: This hook does not specify all of its dependencies: getValues

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 77-77: This hook does not specify all of its dependencies: setValue

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 146-146: Avoid using the index of an array as key property in an element.

This is the source of the key value.

The order of the items may change, and this also affects performances and component state.
Check the React documentation.

(lint/suspicious/noArrayIndexKey)

Additional comments not posted (6)
apps/web/app/(app)/automation/page.tsx (3)

19-19: LGTM!

The import statement for the RulesPrompt component is correctly added.


27-27: LGTM!

The change in the defaultValue prop of the Tabs component to "prompt" is appropriate and aligns with the addition of the new "prompt" tab.


52-54: LGTM!

The addition of the TabsContent component for the "prompt" tab and the rendering of the RulesPrompt component inside it is correctly implemented. The className prop ensures consistent styling with the other tab contents.

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

62-75: LGTM!

The onSubmit function correctly handles the asynchronous form submission, displays appropriate toast notifications based on the result, and navigates to the desired page upon successful submission.


50-159: Great work on the RulesPrompt component!

The component is well-structured and follows best practices for form handling and validation using react-hook-form. It provides a user-friendly interface with a text area for inputting rules and a list of example prompts that can be easily added to the input.

The form submission is handled correctly, and appropriate feedback is provided to the user through toast notifications. The component is also properly styled using CSS classes and UI components from the project's component library.

Overall, the RulesPrompt component is a solid addition to the codebase and enhances the user experience for creating and managing email handling prompts.

Tools
Biome

[error] 77-77: This hook does not specify all of its dependencies: getValues

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 77-77: This hook does not specify all of its dependencies: setValue

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 146-146: Avoid using the index of an array as key property in an element.

This is the source of the key value.

The order of the items may change, and this also affects performances and component state.
Check the React documentation.

(lint/suspicious/noArrayIndexKey)


19-23: Use import type for type-only imports.

The SaveRulesPromptBody import is only used as a type. Using import type ensures that the type is removed by transpilers and avoids loading unnecessary modules.

Apply this diff to fix the import:

-import {
-  saveRulesPromptBody,
-  SaveRulesPromptBody,
-} from "@/utils/actions/validation";
+import { saveRulesPromptBody } from "@/utils/actions/validation";
+import type { SaveRulesPromptBody } from "@/utils/actions/validation";

Likely invalid or redundant comment.

Tools
Biome

[error] 19-23: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

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

Outside diff range and nitpick comments (1)
apps/web/app/(app)/automation/RulesPrompt.tsx (1)

55-58: Replace the template literal with a string literal.

Since there is no interpolation or special-character handling required, replace the template literal with a string literal for improved readability and performance.

Apply this diff to fix the SWR key:

-  >(`/api/user/rules/prompt`);
+  >('/api/user/rules/prompt');
Tools
Biome

[error] 58-58: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between f769a44 and 8bdb6eb.

Files selected for processing (5)
  • apps/web/app/(app)/automation/BulkRunRules.tsx (2 hunks)
  • apps/web/app/(app)/automation/Rules.tsx (2 hunks)
  • apps/web/app/(app)/automation/RulesPrompt.tsx (1 hunks)
  • apps/web/app/(app)/automation/page.tsx (1 hunks)
  • apps/web/app/api/user/rules/prompt/route.ts (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • apps/web/app/(app)/automation/page.tsx
Additional context used
Biome
apps/web/app/(app)/automation/RulesPrompt.tsx

[error] 58-58: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)


[error] 21-25: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 27-28: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 106-106: This hook does not specify all of its dependencies: getValues

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 106-106: This hook does not specify all of its dependencies: setValue

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 181-181: Avoid using the index of an array as key property in an element.

This is the source of the key value.

The order of the items may change, and this also affects performances and component state.
Check the React documentation.

(lint/suspicious/noArrayIndexKey)

Additional comments not posted (9)
apps/web/app/api/user/rules/prompt/route.ts (2)

8-13: LGTM!

The function correctly retrieves the user's rules prompt from the database using the provided userId. The Prisma query is well-structured and selects only the required field.


15-23: LGTM!

The GET function serves as a well-structured API endpoint for retrieving a user's rules prompt. It properly handles user authentication, returns appropriate error responses, and calls the getRulesPrompt function with the authenticated user's ID. The result is correctly returned as a JSON response.

apps/web/app/(app)/automation/BulkRunRules.tsx (2)

6-6: LGTM!

The import statement for LayersIcon is syntactically correct.


44-45: The button changes look good!

The addition of the LayersIcon and the updated button text enhance the user interface by providing a clearer indication of the button's purpose. The icon is added with appropriate class names for margin and size.

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

1-194: LGTM!

The overall structure and logic of the RulesPrompt component are well-organized and follow best practices. The component effectively utilizes libraries such as react-hook-form and swr for form handling and data fetching. It provides a user-friendly interface for creating and managing email handling prompts.

Tools
Biome

[error] 58-58: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)


[error] 21-25: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 27-28: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 106-106: This hook does not specify all of its dependencies: getValues

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 106-106: This hook does not specify all of its dependencies: setValue

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 181-181: Avoid using the index of an array as key property in an element.

This is the source of the key value.

The order of the items may change, and this also affects performances and component state.
Check the React documentation.

(lint/suspicious/noArrayIndexKey)


21-25: Use import type for type-only imports.

The SaveRulesPromptBody import is only used as a type. Using import type ensures that the type is removed by transpilers and avoids loading unnecessary modules.

Apply this diff to fix the import:

-import {
-  saveRulesPromptBody,
-  SaveRulesPromptBody,
-} from "@/utils/actions/validation";
+import { saveRulesPromptBody } from "@/utils/actions/validation";
+import type { SaveRulesPromptBody } from "@/utils/actions/validation";

Likely invalid or redundant comment.

Tools
Biome

[error] 21-25: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


106-111: Add missing dependencies to the useCallback hook.

The addExamplePrompt function uses getValues and setValue from the react-hook-form context. These dependencies should be specified in the useCallback hook's dependency array to ensure that the function is updated when their values change.

Apply this diff to fix the hook dependencies:

-  const addExamplePrompt = useCallback((example: string) => {
+  const addExamplePrompt = useCallback((example: string) => {
     setValue(
       "rulesPrompt",
       `${getValues("rulesPrompt")}\n* ${example.trim()}`.trim(),
     );
-  }, []);
+  }, [getValues, setValue]);

Likely invalid or redundant comment.

Tools
Biome

[error] 106-106: This hook does not specify all of its dependencies: getValues

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 106-106: This hook does not specify all of its dependencies: setValue

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)

apps/web/app/(app)/automation/Rules.tsx (2)

6-6: LGTM!

The changes to the icon imports are consistent with the PR objectives. The removal of SparklesIcon and addition of PenIcon suggest a shift towards prompt-related functionality in the component.


203-205: Changes look good and align with the PR objectives!

The updates to the Button component, including the Link URL, icon, and text, effectively communicate the new prompt-setting functionality and direct users to the appropriate section. This aligns perfectly with the PR title and objectives of adding UI for cursor rules style prompt.

The changes enhance the user experience by providing a clear and intuitive way to access the prompt feature.

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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 8bdb6eb and 84e5c6c.

Files selected for processing (2)
  • apps/web/app/(app)/automation/RulesPrompt.tsx (1 hunks)
  • apps/web/utils/actions/ai-rule.ts (6 hunks)
Additional context used
Biome
apps/web/app/(app)/automation/RulesPrompt.tsx

[error] 58-58: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)


[error] 21-25: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 27-28: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 108-108: This hook does not specify all of its dependencies: getValues

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 108-108: This hook does not specify all of its dependencies: setValue

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 183-183: Avoid using the index of an array as key property in an element.

This is the source of the key value.

The order of the items may change, and this also affects performances and component state.
Check the React documentation.

(lint/suspicious/noArrayIndexKey)

apps/web/utils/actions/ai-rule.ts

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 251-251: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

Additional comments not posted (16)
apps/web/app/(app)/automation/RulesPrompt.tsx (4)

58-58: Using a template literal for the API endpoint is acceptable.

Although the static analysis hint suggests using a string literal instead of a template literal, using a template literal for an API endpoint is a common and acceptable practice. It provides consistency and allows for easier future modifications if needed.

Tools
Biome

[error] 58-58: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)


31-52: The example prompts are comprehensive and helpful.

The provided example prompts cover a wide range of common email handling scenarios and serve as a helpful reference for users to understand the format and possibilities of the rules prompt. No changes are necessary.


1-196: The RulesPrompt component is well-implemented and follows best practices.

The component provides a user-friendly interface for managing email handling prompts. It utilizes react-hook-form for efficient form handling and zod for validation. The integration with the API is implemented using useSWR for data fetching and mutation.

The code is modular, reusable, and follows best practices. It handles form submission correctly, with proper error handling and user feedback. The use of custom hooks and utility functions enhances the maintainability and readability of the code.

Overall, the RulesPrompt component is a solid implementation that effectively fulfills its purpose.

Tools
Biome

[error] 58-58: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)


[error] 21-25: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 27-28: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 108-108: This hook does not specify all of its dependencies: getValues

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 108-108: This hook does not specify all of its dependencies: setValue

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 183-183: Avoid using the index of an array as key property in an element.

This is the source of the key value.

The order of the items may change, and this also affects performances and component state.
Check the React documentation.

(lint/suspicious/noArrayIndexKey)


21-25: Use import type for type-only imports.

The SaveRulesPromptBody import is only used as a type. Using import type ensures that the type is removed by transpilers and avoids loading unnecessary modules.

Apply this diff to fix the import:

-import {
-  saveRulesPromptBody,
-  SaveRulesPromptBody,
-} from "@/utils/actions/validation";
+import { saveRulesPromptBody } from "@/utils/actions/validation";
+import type { SaveRulesPromptBody } from "@/utils/actions/validation";

Likely invalid or redundant comment.

Tools
Biome

[error] 21-25: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

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

407-447: LGTM!

The saveRulesPromptAction function follows a logical flow and handles errors appropriately. It leverages the new aiPromptToRules utility and the existing safeCreateRule function to process and create rules.


212-215: Refactoring looks good!

The changes to the createAutomationAction function improve its readability and maintainability by leveraging the new getGroupId and safeCreateRule functions. The function now handles the group ID for the rule, which is a nice addition.


217-237: LGTM!

The createRule function creates a rule in the database using the provided data. It leverages the shouldAutomate utility to determine if the rule should be automated and returns the created rule.


239-260: LGTM!

The safeCreateRule function provides a safe way to create a rule by handling duplicate rule name errors. It uses a try-catch block to handle errors and appends a timestamp to the rule name if a duplicate rule name error occurs.

Tools
Biome

[error] 251-251: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


Line range hint 262-324: LGTM!

The getGroupId function provides a way to get the group ID for a rule based on the rule's condition type and group. It handles newsletter and receipt groups, checks if the group already exists, creates the group if it doesn't exist, and returns an error if the group already has a rule.

Tools
Biome

[error] 251-251: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


449-462: LGTM!

The shouldAutomate function provides a way to determine if a rule should be automated based on its action types. It returns false if the action types include REPLY, FORWARD, or SEND_EMAIL, and true otherwise.


Line range hint 38-75: Skipped review.

The runRulesAction function has not been modified in this changeset.

Tools
Biome

[error] 30-34: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


Line range hint 77-113: Skipped review.

The testAiAction function has not been modified in this changeset.

Tools
Biome

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


Line range hint 115-153: Skipped review.

The testAiCustomContentAction function has not been modified in this changeset.

Tools
Biome

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


Line range hint 326-336: Skipped review.

The deleteRuleAction function has not been modified in this changeset.


Line range hint 338-350: Skipped review.

The setRuleAutomatedAction function has not been modified in this changeset.

Tools
Biome

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


Line range hint 352-364: Skipped review.

The setRuleRunOnThreadsAction function has not been modified in this changeset.

Tools
Biome

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

Comment on lines 27 to 28
import { SectionHeader } from "@/components/Typography";
import { RulesPromptResponse } from "@/app/api/user/rules/prompt/route";
Copy link
Contributor

Choose a reason for hiding this comment

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

Use import type for type-only imports.

The SectionHeader and RulesPromptResponse imports are only used as types. Using import type ensures that the types are removed by transpilers and avoids loading unnecessary modules.

Apply this diff to fix the imports:

-import { SectionHeader } from "@/components/Typography";
-import { RulesPromptResponse } from "@/app/api/user/rules/prompt/route";
+import type { SectionHeader } from "@/components/Typography";
+import type { RulesPromptResponse } from "@/app/api/user/rules/prompt/route";
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
import { SectionHeader } from "@/components/Typography";
import { RulesPromptResponse } from "@/app/api/user/rules/prompt/route";
import type { SectionHeader } from "@/components/Typography";
import type { RulesPromptResponse } from "@/app/api/user/rules/prompt/route";
Tools
Biome

[error] 27-28: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

Comment on lines 181 to 190
{examplePrompts.map((example, index) => (
<Button
key={index}
variant="outline"
onClick={() => addExamplePrompt(example)}
className="h-auto w-full justify-start text-wrap py-2 text-left"
>
{example}
</Button>
))}
Copy link
Contributor

Choose a reason for hiding this comment

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

Use a unique and stable identifier for the key prop.

Avoid using the array index as the key prop when rendering the example prompt buttons. Using the index can lead to issues when the order of items changes or when items are added/removed from the array.

Since the examplePrompts array contains unique string values, you can use the example prompt itself as the key prop to ensure proper component rendering and state management.

Apply this diff to fix the key prop:

-            {examplePrompts.map((example, index) => (
+            {examplePrompts.map((example) => (
               <Button
-                key={index}
+                key={example}
                 variant="outline"
                 onClick={() => addExamplePrompt(example)}
                 className="h-auto w-full justify-start text-wrap py-2 text-left"
               >
                 {example}
               </Button>
             ))}
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
{examplePrompts.map((example, index) => (
<Button
key={index}
variant="outline"
onClick={() => addExamplePrompt(example)}
className="h-auto w-full justify-start text-wrap py-2 text-left"
>
{example}
</Button>
))}
{examplePrompts.map((example) => (
<Button
key={example}
variant="outline"
onClick={() => addExamplePrompt(example)}
className="h-auto w-full justify-start text-wrap py-2 text-left"
>
{example}
</Button>
))}
Tools
Biome

[error] 183-183: Avoid using the index of an array as key property in an element.

This is the source of the key value.

The order of the items may change, and this also affects performances and component state.
Check the React documentation.

(lint/suspicious/noArrayIndexKey)

Comment on lines 108 to 113
const addExamplePrompt = useCallback((example: string) => {
setValue(
"rulesPrompt",
`${getValues("rulesPrompt")}\n* ${example.trim()}`.trim(),
);
}, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

Add missing dependencies to the useCallback hook.

The addExamplePrompt function uses getValues and setValue from the react-hook-form context. These dependencies should be specified in the useCallback hook's dependency array to ensure that the function is updated when their values change.

Apply this diff to fix the hook dependencies:

-  const addExamplePrompt = useCallback((example: string) => {
+  const addExamplePrompt = useCallback((example: string) => {
     setValue(
       "rulesPrompt",
       `${getValues("rulesPrompt")}\n* ${example.trim()}`.trim(),
     );
-  }, []);
+  }, [getValues, setValue]);
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 addExamplePrompt = useCallback((example: string) => {
setValue(
"rulesPrompt",
`${getValues("rulesPrompt")}\n* ${example.trim()}`.trim(),
);
}, []);
const addExamplePrompt = useCallback((example: string) => {
setValue(
"rulesPrompt",
`${getValues("rulesPrompt")}\n* ${example.trim()}`.trim(),
);
}, [getValues, setValue]);
Tools
Biome

[error] 108-108: This hook does not specify all of its dependencies: getValues

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 108-108: This hook does not specify all of its dependencies: setValue

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)

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

Outside diff range and nitpick comments (1)
apps/web/utils/ai/rule/find-existing-rules.ts (1)

2-4: Use import type for imports that are only used as types.

The static analysis hints correctly suggest using import type for imports that are only used as types. This ensures that the types are removed by the transpilers and avoids loading unnecessary modules.

Apply this diff to use import type:

-import { chatCompletionTools } from "@/utils/llms";
-import { UserAIFields } from "@/utils/llms/types";
-import { Action, Rule } from "@prisma/client";
+import type { chatCompletionTools } from "@/utils/llms";
+import type { UserAIFields } from "@/utils/llms/types";
+import type { Action, Rule } from "@prisma/client";
Tools
Biome

[error] 2-3: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 3-4: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 84e5c6c and c645791.

Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
Files selected for processing (18)
  • apps/web/tests/ai-diff-rules.test.ts (1 hunks)
  • apps/web/tests/ai-prompt-to-rules.test.ts (1 hunks)
  • apps/web/app/(app)/automation/History.tsx (1 hunks)
  • apps/web/app/(app)/automation/RuleForm.tsx (1 hunks)
  • apps/web/app/(app)/automation/Rules.tsx (4 hunks)
  • apps/web/app/(app)/automation/create/page.tsx (1 hunks)
  • apps/web/app/(app)/premium/config.ts (2 hunks)
  • apps/web/app/(landing)/ai-automation/page.tsx (1 hunks)
  • apps/web/app/api/google/webhook/process-history.ts (2 hunks)
  • apps/web/components/NavBottom.tsx (1 hunks)
  • apps/web/components/SideNav.tsx (1 hunks)
  • apps/web/package.json (3 hunks)
  • apps/web/prisma/migrations/20240917232302_disable_rule/migration.sql (1 hunks)
  • apps/web/prisma/schema.prisma (2 hunks)
  • apps/web/utils/actions/ai-rule.ts (9 hunks)
  • apps/web/utils/ai/rule/diff-rules.ts (1 hunks)
  • apps/web/utils/ai/rule/find-existing-rules.ts (1 hunks)
  • apps/web/utils/ai/rule/prompt-to-rules.ts (1 hunks)
Files skipped from review due to trivial changes (7)
  • apps/web/app/(app)/automation/History.tsx
  • apps/web/app/(app)/automation/RuleForm.tsx
  • apps/web/app/(app)/automation/create/page.tsx
  • apps/web/app/(app)/premium/config.ts
  • apps/web/app/(landing)/ai-automation/page.tsx
  • apps/web/components/NavBottom.tsx
  • apps/web/components/SideNav.tsx
Files skipped from review as they are similar to previous changes (2)
  • apps/web/app/(app)/automation/Rules.tsx
  • apps/web/package.json
Additional context used
Biome
apps/web/utils/ai/rule/prompt-to-rules.ts

[error] 2-3: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

apps/web/utils/ai/rule/diff-rules.ts

[error] 3-4: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

apps/web/utils/ai/rule/find-existing-rules.ts

[error] 2-3: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 3-4: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

apps/web/__tests__/ai-prompt-to-rules.test.ts

[error] 134-136: Prefer for...of instead of forEach.

forEach may lead to performance issues when working with large arrays. When combined with functions like filter or map, this causes multiple iterations over the same type.

(lint/complexity/noForEach)

apps/web/utils/actions/ai-rule.ts

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 289-289: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 313-313: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

Additional comments not posted (23)
apps/web/prisma/migrations/20240917232302_disable_rule/migration.sql (2)

1-2: LGTM!

The SQL migration script is well-structured and follows the standard syntax for altering a table. Adding a boolean column to manage the enabled state of rules is a common and effective approach for dynamic rule management.


1-2: Verify the impact on the application code.

Ensure that the application code that interacts with the "Rule" table is updated to handle the new "enabled" column. This may include:

  • Updating queries to filter rules based on the "enabled" state.
  • Modifying rule creation and update logic to set the "enabled" value.
  • Adjusting any business logic that relies on the "Rule" table to consider the "enabled" state.

Run the following script to verify the usage of the "enabled" column:

apps/web/utils/ai/rule/prompt-to-rules.ts (2)

10-49: LGTM!

The aiPromptToRules function is well-implemented and follows best practices:

  • The function signature and parameters are well-defined and typed.
  • The selection of the appropriate Zod schema based on the isEditing flag is a good approach for handling different scenarios.
  • The construction of the system message and prompt is clear and concise.
  • The usage of chatCompletionTools to interact with the AI model is a good abstraction.
  • The parsing and validation of the AI model's response using the defined parameters ensure the returned data is structured correctly.
  • The function is asynchronous, which is appropriate for handling the AI model interaction.
  • The function has a single responsibility and follows the Single Responsibility Principle (SRP).
  • The function name accurately describes its purpose.
  • The code is readable and well-organized with clear variable names and comments.

Overall, the function enhances the application's functionality by automating the rule conversion process, thereby improving efficiency in email management. Great job!


2-3: Skip the static analysis hint.

The imports on lines 2-3 (chatCompletionTools and UserAIFields) are used within the function body and not just as types, so they should not be changed to import type. The static analysis hint can be skipped in this case.

Tools
Biome

[error] 2-3: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

apps/web/utils/ai/rule/diff-rules.ts (1)

12-57: LGTM!

The implementation of the aiDiffRules function looks good:

  • It correctly generates a diff between the old and new prompt files using the createPatch function from the diff library.
  • The prompt constructed for the AI assistant provides clear instructions and the necessary context for analyzing the differences between the prompt files.
  • The response from the AI is properly validated against the defined schema using zod.

The function enhances the ability to track changes in prompt files, making it easier for users to understand modifications in rules.

apps/web/__tests__/ai-diff-rules.test.ts (2)

7-38: LGTM!

The test case is well-structured and covers the expected behavior of the aiDiffRules function. It correctly sets up the input data (user object and prompt files) and asserts the output against the expected result.


40-53: LGTM!

The test case correctly validates the error handling behavior of the aiDiffRules function when provided with an invalid API key. It uses the appropriate assertion (rejects.toThrow()) to ensure that the function throws an error in this scenario.

apps/web/utils/ai/rule/find-existing-rules.ts (1)

19-75: LGTM!

The aiFindExistingRules function is a well-implemented component of the rule management system. It leverages AI to identify existing rules in a database that match a set of prompt rules provided by the user.

The function correctly combines the prompt rules to edit and remove into a single array, constructs a clear and well-structured prompt for the AI assistant, and parses the AI response to map the existing rules with additional context. This enhances the usability of the returned data.

The use of the z library for parsing and validation is a good practice, and the function is well-documented with clear parameter types and descriptions.

apps/web/__tests__/ai-prompt-to-rules.test.ts (3)

9-137: LGTM!

The test case is comprehensive and covers all the important aspects of the aiPromptToRules function. It validates the output against expected values and schemas, which is good for correctness. The test case is not focused, has a reasonable timeout, and mocks the server-only module for isolation.

Tools
Biome

[error] 134-136: Prefer for...of instead of forEach.

forEach may lead to performance issues when working with large arrays. When combined with functions like filter or map, this causes multiple iterations over the same type.

(lint/complexity/noForEach)


139-149: LGTM!

The test case is good for validating the error handling of the aiPromptToRules function. It sets up a user object with an invalid API key and a prompt file, calls the function, and expects it to reject with an error.


134-136: Skip the static analysis suggestion.

The code uses forEach to iterate over the result.rules array and validate each rule against the createRuleSchema schema. The code does not use filter or map with forEach, which is the main concern of the static analysis tool. The code is not working with large arrays, so the performance impact of forEach is negligible. The code is readable and maintainable with forEach.

Tools
Biome

[error] 134-136: Prefer for...of instead of forEach.

forEach may lead to performance issues when working with large arrays. When combined with functions like filter or map, this causes multiple iterations over the same type.

(lint/complexity/noForEach)

apps/web/prisma/schema.prisma (2)

73-73: Verify the usage of the new rulesPrompt field.

The addition of the optional rulesPrompt field to the User model is a good change that allows for storing user-defined prompts for generating rules.

Please ensure that this new field is being utilized correctly in other parts of the codebase, such as in the API layer, services, and UI components.

Run the following script to verify the field usage:

Verification successful

The rulesPrompt field is correctly integrated and utilized across the codebase.

The verification process has confirmed that the new rulesPrompt field is being used appropriately in various parts of the application:

  • It's properly validated using Zod schema in the validation utility.
  • Database operations (select and update) are implemented correctly.
  • The field is integrated into React components for form handling and UI display.
  • API routes are utilizing the field for user rules management.

The usage is consistent with the field's purpose as defined in the Prisma schema, and no issues were found in its implementation.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of the `rulesPrompt` field in the codebase.

# Test: Search for the field usage in TypeScript files. Expect: At least one occurrence.
rg --type ts $'rulesPrompt'

Length of output: 1548


168-168: Verify the usage of the new enabled field in the rule execution logic.

The addition of the enabled field to the Rule model with a default value of true is a good change that allows for more control over the execution of rules.

Please ensure that this new field is being utilized correctly in the rule execution logic to prevent the execution of disabled rules.

Run the following script to verify the field usage:

Verification successful

Verification successful: 'enabled' field is correctly implemented

The new enabled field in the Rule model is being properly utilized in the rule execution logic. The recent commit (c645791) implements the following changes:

  • In apps/web/app/api/google/webhook/process-history.ts and apps/web/utils/actions/ai-rule.ts, a where: { enabled: true } clause has been added to the rules query.
  • This ensures that only enabled rules are fetched and processed, effectively skipping disabled rules.

The implementation is consistent across multiple functions and files, indicating a thorough integration of the new field.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash 
# Description: Verify the usage of the `enabled` field in the rule execution logic.

# Test: Search for the field usage in the rule execution logic. Expect: At least one occurrence.
rg --type ts $'rule.enabled'

Length of output: 27


Script:

#!/bin/bash
# Description: Search for rule-related code and recent changes

# Search for rule-related functions or methods
echo "Searching for rule-related functions:"
rg --type ts "function.*rule|class.*Rule|interface.*Rule" -g "!*.test.ts" -g "!*.spec.ts"

# Search for recent changes related to rules
echo -e "\nSearching for recent changes related to rules:"
git log -n 5 --pretty=format:"%h - %s" --grep="rule"

# Search for TODOs related to rule implementation
echo -e "\nSearching for TODOs related to rule implementation:"
rg --type ts "TODO.*rule" -g "!*.test.ts" -g "!*.spec.ts"

# Search for any usage of 'Rule' type from Prisma
echo -e "\nSearching for usage of 'Rule' type from Prisma:"
rg --type ts "Rule.*from.*'@prisma/client'"

Length of output: 1450


Script:

#!/bin/bash
# Description: Search for implementation of skipping disabled rules and usage of 'enabled' field

# Search for code related to skipping disabled rules
echo "Searching for code related to skipping disabled rules:"
rg --type ts "skip.*disabled.*rule|disabled.*rule.*skip"

# Search for usage of 'enabled' field in rule-related code
echo -e "\nSearching for usage of 'enabled' field in rule-related code:"
rg --type ts "rule.*enabled|enabled.*rule"

# Search for Rule import from Prisma (might be imported differently)
echo -e "\nSearching for Rule import from Prisma:"
rg --type ts "import.*Rule.*from.*'@prisma/client'"

# Get the content of the most recent commit that mentions skipping disabled rules
echo -e "\nContent of the most recent commit that mentions skipping disabled rules:"
git show $(git log --grep="skip disabled rules" -n 1 --format="%H") --unified=0

Length of output: 2868

apps/web/app/api/google/webhook/process-history.ts (2)

45-48: LGTM!

The addition of the where clause to filter for enabled rules is a good improvement. It ensures that only active rules are considered for processing, enhancing the specificity of the rules being processed.


255-266: Looks good!

The adjustment to the destructuring of the options parameter improves code clarity without altering the fundamental logic of the function. Moving the destructuring directly into the function signature makes it clear which properties are being utilized from the options object.

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

5-10: Use import type for type-only imports.

The imports at line range 5-10 are only used as types. Using import type ensures that the types are removed by transpilers and avoids loading unnecessary modules, which can improve the performance of the application.

Apply this diff to use import type:

-import {
+import type {
   RuleType,
   ExecutedRuleStatus,
   Action,
   ActionType,
 } from "@prisma/client";
Tools
Biome

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


31-36: LGTM!

The new imports are relevant to the functionality of saving rules prompts and converting prompts to rules. The naming is clear and follows the existing conventions.


56-59: LGTM!

Including the actions relation when fetching the user's rules is a good practice to avoid unnecessary database queries and improve performance.


223-226: LGTM!

The changes introduce a new flow for creating rules:

  1. Get the groupId based on the result and userId using the getGroupId function.
  2. Safely create the rule using the result, userId, and groupIdResult with the safeCreateRule function.

This aligns with the AI-generated summary, which mentions the introduction of a new schema for rule creation and a utility function for converting prompts.


228-248: LGTM!

The createRule function encapsulates the logic for creating a new rule using the provided result, userId, and groupId. It follows the new schema for rule creation mentioned in the AI-generated summary.

The function uses Prisma's create method to create the rule with the specified data, which includes various fields from the result object, along with the userId and groupId.

The shouldAutomate function is used to determine the value of the automate field based on the result.actions.

The code is well-structured, follows a clear naming convention, and aligns with the AI-generated summary, improving the rule creation process.


250-275: LGTM!

The updateRule function encapsulates the logic for updating an existing rule using the provided ruleId, result, userId, and groupId. It follows a similar structure to the createRule function.

The function uses Prisma's update method to update the rule with the specified data, which includes various fields from the result object, along with the userId and groupId.

The actions field is updated by first deleting all existing actions using deleteMany and then creating new actions based on the result.actions using createMany. This ensures that the rule's actions are completely replaced with the new actions from the result.

The shouldAutomate function is used to determine the value of the automate field based on the result.actions.

The code is well-structured, follows a clear naming convention, and aligns with the AI-generated summary, improving the rule update process.


277-298: LGTM!

The safeCreateRule function provides a safe way to create a rule by handling potential errors, particularly duplicate name errors.

The function first attempts to create the rule using the createRule function with the provided result, userId, and groupId. If the creation is successful, it returns the created rule's id.

If the creation fails due to a duplicate name error (detected using the isDuplicateError function), the function appends a timestamp to the rule's name to make it unique and retries the creation. This ensures that rules with duplicate names can still be created by automatically generating a unique name.

If the creation fails due to any other error, the function returns a generic error message.

The code provides a robust way to create rules while handling potential errors and ensuring uniqueness of rule names.

Tools
Biome

[error] 289-289: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


300-322: LGTM!

The safeUpdateRule function provides a safe way to update a rule by handling potential errors, particularly duplicate name errors.

The function first attempts to update the rule using the updateRule function with the provided ruleId, result, userId, and groupId. If the update is successful, it returns the updated rule's id.

If the update fails due to a duplicate name error (detected using the isDuplicateError function), the function appends a timestamp to the rule's name to make it unique and creates a new rule with the updated name using the createRule function. This ensures that rules with duplicate names can still be handled by creating a new rule with a unique name.

If the update fails due to any other error, the function returns a generic error message.

Tools
Biome

[error] 313-313: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

Comment on lines +1 to +4
import { z } from "zod";
import { createPatch } from "diff";
import { chatCompletionTools } from "@/utils/llms";
import { UserAIFields } from "@/utils/llms/types";
Copy link
Contributor

Choose a reason for hiding this comment

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

Use import type for type-only imports.

The static analysis tool suggests using import type for imports that are only used as types. This ensures that the types are removed by the transpilers and avoids loading unnecessary modules.

Apply this diff to fix the imports:

-import { z } from "zod";
+import { z } from "zod";
 import { createPatch } from "diff";
-import { chatCompletionTools } from "@/utils/llms";
-import { UserAIFields } from "@/utils/llms/types";
+import type { chatCompletionTools } from "@/utils/llms";
+import type { UserAIFields } from "@/utils/llms/types";
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
import { z } from "zod";
import { createPatch } from "diff";
import { chatCompletionTools } from "@/utils/llms";
import { UserAIFields } from "@/utils/llms/types";
import { z } from "zod";
import { createPatch } from "diff";
import type { chatCompletionTools } from "@/utils/llms";
import type { UserAIFields } from "@/utils/llms/types";
Tools
Biome

[error] 3-4: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

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

Outside diff range and nitpick comments (2)
apps/web/utils/ai/rule/find-existing-rules.ts (1)

19-92: LGTM!

The aiFindExistingRules function is well-implemented and follows a clear logic flow. It effectively utilizes an AI assistant to identify existing rules in the database that match the prompt rules. The function consolidates the prompt rules, formulates a prompt for the AI assistant, parses the response, and maps additional context to the existing rules. The returned edited and removed rules facilitate user-driven rule management.

Do you want me to add documentation comments to the function to improve its readability and maintainability?

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

288-290: Nitpick: Use template literals instead of string concatenation.

Consider using template literals instead of string concatenation for better readability and consistency with the rest of the codebase.

Apply this diff to use template literals:

-{ ...result, name: result.name + " - " + Date.now() },
+{ ...result, name: `${result.name} - ${Date.now()}` },

Also applies to: 312-314

Tools
Biome

[error] 289-289: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 6b8bf4a and 7c5875d.

Files selected for processing (8)
  • apps/web/tests/ai-diff-rules.test.ts (1 hunks)
  • apps/web/tests/ai-prompt-to-rules.test.ts (1 hunks)
  • apps/web/app/(app)/automation/RulesPrompt.tsx (1 hunks)
  • apps/web/utils/actions/ai-rule.ts (9 hunks)
  • apps/web/utils/actions/validation.ts (1 hunks)
  • apps/web/utils/ai/rule/diff-rules.ts (1 hunks)
  • apps/web/utils/ai/rule/find-existing-rules.ts (1 hunks)
  • apps/web/utils/ai/rule/prompt-to-rules.ts (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • apps/web/tests/ai-diff-rules.test.ts
  • apps/web/utils/actions/validation.ts
Additional context used
Biome
apps/web/utils/ai/rule/prompt-to-rules.ts

[error] 2-3: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

apps/web/utils/ai/rule/diff-rules.ts

[error] 3-4: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

apps/web/utils/ai/rule/find-existing-rules.ts

[error] 2-3: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 3-4: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

apps/web/__tests__/ai-prompt-to-rules.test.ts

[error] 138-140: Prefer for...of instead of forEach.

forEach may lead to performance issues when working with large arrays. When combined with functions like filter or map, this causes multiple iterations over the same type.

(lint/complexity/noForEach)

apps/web/app/(app)/automation/RulesPrompt.tsx

[error] 58-58: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)


[error] 102-107: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 102-102: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)


[error] 21-25: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 27-28: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 116-116: This hook does not specify all of its dependencies: getValues

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 116-116: This hook does not specify all of its dependencies: setValue

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 179-179: Avoid using the index of an array as key property in an element.

This is the source of the key value.

The order of the items may change, and this also affects performances and component state.
Check the React documentation.

(lint/suspicious/noArrayIndexKey)

apps/web/utils/actions/ai-rule.ts

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 289-289: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 313-313: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

Additional comments not posted (11)
apps/web/utils/ai/rule/prompt-to-rules.ts (1)

10-49: LGTM!

The aiPromptToRules function is well-implemented and follows a clear logical flow. It effectively converts email management rules from a prompt file into a structured format using appropriate schemas for validation and type inference. The interaction with the AI model is handled through the chatCompletionTools function, and the parsed rules are returned as expected.

This function enhances the application's functionality and improves efficiency in email management by automating the rule conversion process.

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

1-4: Use import type for type-only imports.

The imports chatCompletionTools and UserAIFields are only used as types in this file. Use import type to ensure that the types are removed by the transpilers and to avoid loading unnecessary modules.

Apply this diff to fix the imports:

 import { z } from "zod";
 import { createPatch } from "diff";
-import { chatCompletionTools } from "@/utils/llms";
-import { UserAIFields } from "@/utils/llms/types";
+import type { chatCompletionTools } from "@/utils/llms";
+import type { UserAIFields } from "@/utils/llms/types";
Tools
Biome

[error] 3-4: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


19-76: LGTM!

The aiDiffRules function is well-implemented and provides a useful functionality for analyzing differences between prompt files and identifying added, edited, and removed rules. Here are some key points:

  • It effectively utilizes the createPatch function from the diff library to generate a diff representation of the old and new prompt files.
  • The constructed prompt for the AI assistant is detailed and provides clear instructions on how to analyze the differences and return the actual content of the rules.
  • The use of zod for schema validation ensures that the AI assistant's response adheres to the expected structure, improving the reliability and consistency of the output.
  • The function enhances the ability to track changes in prompt files, making it easier for users to understand modifications in rules.

Overall, the implementation looks good and serves its purpose effectively.

apps/web/__tests__/ai-prompt-to-rules.test.ts (3)

9-141: LGTM!

The test case is comprehensive and covers the core functionality of the aiPromptToRules function. It validates the returned result object thoroughly, checking the structure and values of each rule object and validating them against the createRuleSchema schema.

The test case is not focused, which is good. The timeout of 15 seconds is reasonable for an async test.

Tools
Biome

[error] 138-140: Prefer for...of instead of forEach.

forEach may lead to performance issues when working with large arrays. When combined with functions like filter or map, this causes multiple iterations over the same type.

(lint/complexity/noForEach)


143-155: LGTM!

The test case is simple but effective in validating the error handling of the aiPromptToRules function. It sets up a user object with an invalid API key and expects the function to reject with an error.


138-140: Skip the static analysis hint.

The code is using forEach to iterate over the result.rules array and validate each rule object against the createRuleSchema schema. It is not using filter or map in combination with forEach, which is the main concern raised by the hint.

The code is not working with a large array, so the performance impact of using forEach is negligible. The code is readable and concise with forEach.

Tools
Biome

[error] 138-140: Prefer for...of instead of forEach.

forEach may lead to performance issues when working with large arrays. When combined with functions like filter or map, this causes multiple iterations over the same type.

(lint/complexity/noForEach)

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

1-192: LGTM!

The RulesPrompt component is well-implemented and follows best practices. Here are some positive aspects of the component:

  • The component is modular and follows a clear separation of concerns.
  • It utilizes libraries like react-hook-form, useSWR, and zod for efficient form handling, data fetching, and validation.
  • The component incorporates error handling, loading states, and user feedback through toast notifications, ensuring a smooth user experience.
  • The layout is organized using a card component, which separates the form and examples into distinct sections for a clean interface.
  • The component integrates a predefined list of example prompts that users can easily add to their input, enhancing user experience and efficiency.

Overall, the component is well-structured, maintainable, and provides a user-friendly interface for managing email handling prompts.

Tools
Biome

[error] 58-58: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)


[error] 102-107: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 102-102: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)


[error] 21-25: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 27-28: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 116-116: This hook does not specify all of its dependencies: getValues

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 116-116: This hook does not specify all of its dependencies: setValue

This dependency is not specified in the hook dependency list.

Either include it or remove the dependency array

(lint/correctness/useExhaustiveDependencies)


[error] 179-179: Avoid using the index of an array as key property in an element.

This is the source of the key value.

The order of the items may change, and this also affects performances and component state.
Check the React documentation.

(lint/suspicious/noArrayIndexKey)

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

5-10: Use import type for type-only imports.

The imports at line range 5-10 are only used as types. Using import type ensures that the types are removed by the transpilers and avoids loading unnecessary modules, which can improve the performance of the application.

Apply this diff to use import type:

-import {
+import type {
   RuleType,
   ExecutedRuleStatus,
   Action,
   ActionType,
 } from "@prisma/client";
Tools
Biome

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


31-36: LGTM!

The imports are necessary for the code to function properly and there are no apparent issues.


56-59: LGTM!

The Prisma query correctly includes the enabled rules and their actions for the user.


Line range hint 223-662: Significant improvements to rule management and automation!

The refactoring and addition of new functions for creating, updating, and managing rules are significant improvements that enhance the functionality and maintainability of the codebase. Some key highlights:

  • The refactoring of the createAutomationAction function to use the new safeCreateRule function handles duplicate rule names.
  • The addition of the groupId parameter to the createRule and updateRule functions allows for better organization of rules based on their conditions.
  • The new safeCreateRule and safeUpdateRule functions provide a safer way to create and update rules by handling duplicate rule names.
  • The new getGroupId function is a useful utility for determining the group ID for a rule based on its condition.
  • The new saveRulesPromptAction function is a significant addition that allows users to save their rules prompt and updates the rules accordingly. It handles added, edited, and removed rules based on the diff between the old and new prompts.
  • The modification to the shouldAutomate function to exclude replies, forwards, and send email actions from being automated prevents unintended actions from being automated.

Great work on these enhancements!

Comment on lines +2 to +3
import { chatCompletionTools } from "@/utils/llms";
import { UserAIFields } from "@/utils/llms/types";
Copy link
Contributor

Choose a reason for hiding this comment

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

Use import type for imports used only as types.

The static analysis tool suggests using import type for the following imports:

import { chatCompletionTools } from "@/utils/llms";
import { UserAIFields } from "@/utils/llms/types";

Using import type ensures that these imports are removed by the transpilers and avoids loading unnecessary modules. This can help optimize the bundle size and improve performance.

Apply this diff to fix the imports:

-import { chatCompletionTools } from "@/utils/llms";
-import { UserAIFields } from "@/utils/llms/types";
+import type { chatCompletionTools } from "@/utils/llms";
+import type { UserAIFields } from "@/utils/llms/types";
Tools
Biome

[error] 2-3: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

Comment on lines +2 to +4
import { chatCompletionTools } from "@/utils/llms";
import { UserAIFields } from "@/utils/llms/types";
import { Action, Rule } from "@prisma/client";
Copy link
Contributor

Choose a reason for hiding this comment

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

Use import type for imports that are only used as types.

The static analysis tool suggests using import type for imports that are only used as types. This ensures that the types are removed by the transpilers and avoids loading unnecessary modules.

Apply this diff to fix the imports:

-import { chatCompletionTools } from "@/utils/llms";
-import { UserAIFields } from "@/utils/llms/types";
-import { Action, Rule } from "@prisma/client";
+import type { chatCompletionTools } from "@/utils/llms";
+import type { UserAIFields } from "@/utils/llms/types";
+import type { Action, Rule } from "@prisma/client";
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
import { chatCompletionTools } from "@/utils/llms";
import { UserAIFields } from "@/utils/llms/types";
import { Action, Rule } from "@prisma/client";
import type { chatCompletionTools } from "@/utils/llms";
import type { UserAIFields } from "@/utils/llms/types";
import type { Action, Rule } from "@prisma/client";
Tools
Biome

[error] 2-3: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 3-4: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

const { data, isLoading, error, mutate } = useSWR<
RulesPromptResponse,
{ error: string }
>(`/api/user/rules/prompt`);
Copy link
Contributor

Choose a reason for hiding this comment

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

Use a string literal instead of a template literal.

Since no interpolation or special-character handling is needed for the URL string, replace the template literal with a string literal for improved code readability and performance.

Apply this diff to fix the issue:

- >(`/api/user/rules/prompt`);
+ >("/api/user/rules/prompt");
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
>(`/api/user/rules/prompt`);
>("/api/user/rules/prompt");
Tools
Biome

[error] 58-58: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)

Comment on lines +102 to +107
`Rules saved successfully! ` +
[
createdRules ? `${createdRules} rules created. ` : "",
editedRules ? `${editedRules} rules edited. ` : "",
removedRules ? `${removedRules} rules removed. ` : "",
].join(""),
Copy link
Contributor

Choose a reason for hiding this comment

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

Use a single template literal for the success message.

Refactor the code to use a single template literal instead of string concatenation and an unnecessary template literal. This improves code readability and maintainability.

Apply this diff to fix the issue:

- description:
-   `Rules saved successfully! ` +
-   [
-     createdRules ? `${createdRules} rules created. ` : "",
-     editedRules ? `${editedRules} rules edited. ` : "",
-     removedRules ? `${removedRules} rules removed. ` : "",
-   ].join(""),
+ description: `Rules saved successfully! ${
+   createdRules ? `${createdRules} rules created. ` : ""
+ }${
+   editedRules ? `${editedRules} rules edited. ` : ""
+ }${
+   removedRules ? `${removedRules} rules removed. ` : ""
+ }`.trim(),
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
`Rules saved successfully! ` +
[
createdRules ? `${createdRules} rules created. ` : "",
editedRules ? `${editedRules} rules edited. ` : "",
removedRules ? `${removedRules} rules removed. ` : "",
].join(""),
description: `Rules saved successfully! ${
createdRules ? `${createdRules} rules created. ` : ""
}${
editedRules ? `${editedRules} rules edited. ` : ""
}${
removedRules ? `${removedRules} rules removed. ` : ""
}`.trim(),
Tools
Biome

[error] 102-107: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 102-102: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)

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

Outside diff range and nitpick comments (1)
apps/web/app/(app)/automation/RuleForm.tsx (1)

112-112: Consider replacing the template literals with string literals.

The static analysis tool has flagged the usage of template literals in the following lines:

Since no interpolation or special-character handling is needed, it's recommended to replace the template literals with string literals for better performance and readability.

Apply this diff to fix the lint errors:

-router.push(`/automation?tab=rules`);
+router.push('/automation?tab=rules');

Also applies to: 133-133

Tools
Biome

[error] 112-112: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 7c5875d and 9716cb0.

Files selected for processing (1)
  • apps/web/app/(app)/automation/RuleForm.tsx (7 hunks)
Additional context used
Biome
apps/web/app/(app)/automation/RuleForm.tsx

[error] 112-112: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)


[error] 133-133: Do not use template literals if interpolation and special-character handling are not needed.

Unsafe fix: Replace with string literal

(lint/style/noUnusedTemplateLiteral)

Additional comments not posted (4)
apps/web/app/(app)/automation/RuleForm.tsx (4)

153-167: LGTM! The rule type selection has been improved.

The changes simplify the form layout by replacing the tabbed interface with a dropdown Select component. This enhances the usability and makes the rule type selection more intuitive.


Line range hint 401-485: LGTM!

The GroupsTab function is well-structured and handles the group selection and creation of predefined groups correctly. The usage of SWR for data fetching and the Select component for group selection is appropriate.


Line range hint 487-550: LGTM!

The LabelCombobox function is well-implemented and provides a user-friendly way to select or create labels. The usage of the Combobox component and the ability to create new labels based on the search query enhances the user experience.


Line range hint 552-583: LGTM! The cleanRule function has been improved.

The changes to the cleanRule function are valid and improve the code quality:

  • The removal of the type parameter from the function signature is a good decision since the rule type can be determined from the rule object itself.
  • The logic for removing unnecessary properties based on the rule type is implemented correctly.

The function is now more concise and easier to understand.

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

Outside diff range and nitpick comments (1)
apps/web/utils/actions/ai-rule.ts (1)

Line range hint 277-666: LGTM with a minor suggestion!

The code segment defining the safeCreateRule, safeUpdateRule, getGroupId, saveRulesPromptAction, and shouldAutomate functions looks good. The functions are well-structured and follow a clear flow. The saveRulesPromptAction function handles the complex flow of saving the user's rules prompt and updating the rules accordingly.

However, consider using template literals instead of string concatenation in the safeCreateRule and safeUpdateRule functions to improve the code readability.

Apply this diff to use template literals:

-      const rule = await createRule(
-        { ...result, name: result.name + " - " + Date.now() },
+      const rule = await createRule(
+        { ...result, name: `${result.name} - ${Date.now()}` },
         userId,
         groupId,
       );
-      const rule = await createRule(
-        { ...result, name: result.name + " - " + Date.now() },
+      const rule = await createRule(
+        { ...result, name: `${result.name} - ${Date.now()}` },
         userId,
         groupId,
       );
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 9716cb0 and 099ac59.

Files selected for processing (6)
  • apps/web/tests/ai-diff-rules.test.ts (1 hunks)
  • apps/web/tests/ai-prompt-to-rules.test.ts (1 hunks)
  • apps/web/utils/actions/ai-rule.ts (9 hunks)
  • apps/web/utils/ai/rule/create-rule-schema.ts (1 hunks)
  • apps/web/utils/ai/rule/create-rule.ts (2 hunks)
  • apps/web/utils/ai/rule/prompt-to-rules.ts (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • apps/web/tests/ai-diff-rules.test.ts
  • apps/web/utils/ai/rule/create-rule-schema.ts
Additional context used
Biome
apps/web/utils/ai/rule/prompt-to-rules.ts

[error] 2-3: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)

apps/web/__tests__/ai-prompt-to-rules.test.ts

[error] 106-108: Prefer for...of instead of forEach.

forEach may lead to performance issues when working with large arrays. When combined with functions like filter or map, this causes multiple iterations over the same type.

(lint/complexity/noForEach)

apps/web/utils/actions/ai-rule.ts

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


[error] 289-289: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 315-315: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

Additional comments not posted (15)
apps/web/utils/ai/rule/create-rule.ts (3)

4-4: Modularizing the schema definition is a good practice.

Extracting the createRuleSchema to a separate module improves code organization and allows for better reusability of the schema across the application.


28-30: Type inference using the schema is a good practice.

Inferring the type of result using the imported createRuleSchema ensures type safety and consistency between the schema definition and the actual data structure.


32-51: The restructured return object enhances clarity and functionality.

The changes made to the return object of the aiCreateRule function provide a clearer distinction between static and AI-generated properties for each action. This structured approach improves the overall functionality and maintainability of the code.

The use of optional chaining and nullish coalescing ensures proper handling of potentially undefined properties, preventing unexpected errors.

The code is well-formatted and follows a consistent structure, enhancing readability.

apps/web/utils/ai/rule/prompt-to-rules.ts (2)

2-3: Use import type for imports used only as types.

The static analysis tool suggests using import type for the following imports:

import { chatCompletionTools } from "@/utils/llms";
import { UserAIFields } from "@/utils/llms/types";

Using import type ensures that these imports are removed by the transpilers and avoids loading unnecessary modules. This can help optimize the bundle size and improve performance.

Apply this diff to fix the imports:

-import { chatCompletionTools } from "@/utils/llms";
-import { UserAIFields } from "@/utils/llms/types";
+import type { chatCompletionTools } from "@/utils/llms";
+import type { UserAIFields } from "@/utils/llms/types";
Tools
Biome

[error] 2-3: All these imports are only used as types.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


10-69: LGTM!

The aiPromptToRules function is well-implemented and provides a valuable automation feature for converting email management rules from a prompt file into a structured format. It leverages the power of an AI model to parse the prompt file and generate structured rule data based on the defined schema.

The function's design is clean and modular, with clear separation of concerns. It handles the selection of the appropriate schema based on the isEditing flag, constructs the necessary system message and prompt, interacts with the AI model using chatCompletionTools, and returns the parsed rules after type inference.

This implementation enhances the application's functionality by streamlining the rule conversion process, improving efficiency in email management. The use of type inference ensures that the returned data adheres to the defined schema, promoting type safety and reducing the likelihood of errors.

Overall, the aiPromptToRules function is a valuable addition to the codebase, automating a critical task and improving the user experience in managing email rules.

apps/web/__tests__/ai-prompt-to-rules.test.ts (2)

9-109: LGTM!

The test case is comprehensive and covers various scenarios. It validates the conversion of a prompt file to rules and checks the structure of each rule object. It also validates each rule against the schema using createRuleSchema.

The test case is not focused, which is good. The timeout of 15 seconds is reasonable for a large test case.

Tools
Biome

[error] 106-108: Prefer for...of instead of forEach.

forEach may lead to performance issues when working with large arrays. When combined with functions like filter or map, this causes multiple iterations over the same type.

(lint/complexity/noForEach)


111-123: LGTM!

The test case is simple but effective in validating the error handling of the aiPromptToRules function. It sets up a user object with an invalid API key and a prompt file, calls the function, and expects it to throw an error.

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

5-10: ** Use import type for type-only imports.**

The imports at line range 5-10 are only used as types. Using import type ensures that the types are removed by the transpilers and avoids loading unnecessary modules, which can improve the performance of the application.

Apply this diff to use import type:

-import {
+import type {
   RuleType,
   ExecutedRuleStatus,
   Action,
   ActionType,
 } from "@prisma/client";
Tools
Biome

[error] 4-10: Some named imports are only used as types.

This import is only used as a type.

Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.

(lint/style/useImportType)


31-36: LGTM!

The imports look good.


56-59: LGTM!

The Prisma query to find a user and include their enabled rules and actions looks good.


116-119: This code segment is similar to the previous one and has no issues.


161-164: This code segment is similar to the previous ones and has no issues.


223-226: LGTM!

The code segment in the createAutomationAction function looks good. It correctly calls the getGroupId function to get the group ID for the rule and then calls the safeCreateRule function to create the rule.


228-248: LGTM!

The createRule function looks good. It correctly creates a new rule using Prisma and sets the automate field based on the result of the shouldAutomate function.


250-275: LGTM!

The updateRule function looks good. It correctly updates an existing rule using Prisma and sets the automate field based on the result of the shouldAutomate function.

@elie222 elie222 changed the title WIP: Add UI for cursor rules style prompt Add UI for cursor rules style prompt Sep 19, 2024
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

Comments