Skip to content

Conversation

@ZHallen122
Copy link
Collaborator

@ZHallen122 ZHallen122 commented Mar 18, 2025

Summary by CodeRabbit

  • New Features
    • Introduced a new modal dialog that notifies users when they reach their daily project creation limit, offering clear guidance and next steps.
    • Enhanced the project creation flow to provide more reliable operations and improved error feedback, ensuring a smoother user experience overall.

@ZHallen122 ZHallen122 requested a review from Sma1lboy March 18, 2025 14:43
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 18, 2025

Walkthrough

This pull request updates the project creation flow across backend and frontend components. In the backend, the ProjectService now instantiates a structured project entity, includes error handling for package processing, and updates the background process to use the saved project for path updates. On the frontend, the project creation flow now returns a structured result via a new type and integrates a rate limit modal to inform users when they hit the daily project creation limit. These changes enhance error logging and provide clearer feedback to the user.

Changes

File(s) Change Summary
backend/src/.../project.service.ts Refactored createProject to instantiate a new Project, added try-catch for package processing errors, improved logging, and updated createProjectInBackground to accept a saved project for path updates.
frontend/src/components/chat/.../project-context.tsx
frontend/src/app/(main)/page.tsx
Introduced the new type CreateProjectResult and updated function signatures to return structured results. Modified the UI logic in page.tsx to handle rate limit responses by adding the isRateLimitResult function.
frontend/src/components/rate-limit-modal.tsx Added the RateLimitModal component with props for visibility, a close function, and a configurable daily limit, displaying an alert and explanatory text when the limit is reached.

Sequence Diagram(s)

sequenceDiagram
    participant C as Client
    participant PS as ProjectService
    participant R as Repository
    C->>PS: Call createProject
    PS->>PS: Instantiate Project entity with properties
    PS->>PS: Process project packages (try-catch)
    alt Package processing error
        PS->>PS: Log error and set empty packages
    end
    PS->>R: Save Project and log ID
    PS->>PS: Call createProjectInBackground(savedProject)
    PS->>PS: Retrieve project path in background
    alt Path retrieved
        PS->>R: Update and save project with new path
        PS->>PS: Log update
    else 
        PS->>PS: Log error for missing path
    end
Loading
sequenceDiagram
    participant U as User
    participant H as HomePage
    participant PC as ProjectContext
    U->>H: Submit project creation prompt
    H->>PC: Call createProjectFromPrompt(prompt, isPublic, model)
    PC-->>H: Return CreateProjectResult (success or rate limit)
    alt Rate Limit Reached
        H->>H: Set state with rate limit flag and limit number
        H->>U: Display RateLimitModal
    else Success
        H->>H: Clear message and navigate to chat page
    end
Loading

Possibly related PRs

  • Project create limit #148: Involved similar adjustments in the project creation process, particularly addressing rate limiting and error handling in the createProject method.

Poem

I hopped through lines of code so neat,
Adding checks to make the process complete,
Projects now born with structured grace,
And a modal to slow the rapid pace,
With logs that twinkle like stars at night,
I, the rabbit, dance in delight!
🐰✨

Warning

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

🔧 ESLint

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

frontend/src/components/chat/code-engine/project-context.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the config "next/core-web-vitals" to extend from. Please check that the name of the config is correct.

The config "next/core-web-vitals" was referenced from the config file in "/frontend/.eslintrc.json".

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

frontend/src/components/rate-limit-modal.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the config "next/core-web-vitals" to extend from. Please check that the name of the config is correct.

The config "next/core-web-vitals" was referenced from the config file in "/frontend/.eslintrc.json".

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

frontend/src/app/(main)/page.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the config "next/core-web-vitals" to extend from. Please check that the name of the config is correct.

The config "next/core-web-vitals" was referenced from the config file in "/frontend/.eslintrc.json".

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

  • 1 others
✨ Finishing Touches
  • 📝 Generate Docstrings

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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @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.

@ZHallen122 ZHallen122 changed the title Fix project rate limit Fix backend project rate limit and feat(frontend) project limit pop up Mar 18, 2025
@ZHallen122 ZHallen122 marked this pull request as ready for review March 18, 2025 14:44
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: 6

🧹 Nitpick comments (1)
frontend/src/components/chat/code-engine/project-context.tsx (1)

145-146: Fix React Hook cleanup dependencies warning

The effect cleanup function might use stale ref values. Store the ref values in variables inside the effect.

useEffect(() => {
+  const chatProjectCacheRef = chatProjectCache.current;
+  const pendingOperationsRef = pendingOperations.current;
  return () => {
    isMounted.current = false;
-    chatProjectCache.current.clear();
-    pendingOperations.current.clear();
+    chatProjectCacheRef.clear();
+    pendingOperationsRef.clear();
  };
}, []);
🧰 Tools
🪛 GitHub Actions: autofix.ci

[warning] 145-145: The ref value 'chatProjectCache.current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy 'chatProjectCache.current' to a variable inside the effect, and use that variable in the cleanup function react-hooks/exhaustive-deps


[warning] 146-146: The ref value 'pendingOperations.current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy 'pendingOperations.current' to a variable inside the effect, and use that variable in the cleanup function react-hooks/exhaustive-deps

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 17ea0df and 443ebb7.

📒 Files selected for processing (4)
  • backend/src/project/project.service.ts (3 hunks)
  • frontend/src/app/(main)/page.tsx (2 hunks)
  • frontend/src/components/chat/code-engine/project-context.tsx (6 hunks)
  • frontend/src/components/rate-limit-modal.tsx (1 hunks)
🧰 Additional context used
🧬 Code Definitions (2)
backend/src/project/project.service.ts (1)
frontend/src/graphql/type.tsx (1) (1)
  • Project (255:277)
frontend/src/components/chat/code-engine/project-context.tsx (1)
frontend/src/app/log/logger.ts (1) (1)
  • logger (3:19)
🪛 GitHub Actions: autofix.ci
frontend/src/app/(main)/page.tsx

[warning] 56-56: Unexpected console statement no-console

backend/src/project/project.service.ts

[warning] 393-393: 'error' is defined but never used unused-imports/no-unused-vars

frontend/src/components/rate-limit-modal.tsx

[error] 35-35: 'can be escaped with', , ', ’` react/no-unescaped-entities

frontend/src/components/chat/code-engine/project-context.tsx

[warning] 145-145: The ref value 'chatProjectCache.current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy 'chatProjectCache.current' to a variable inside the effect, and use that variable in the cleanup function react-hooks/exhaustive-deps


[warning] 146-146: The ref value 'pendingOperations.current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy 'pendingOperations.current' to a variable inside the effect, and use that variable in the cleanup function react-hooks/exhaustive-deps


[warning] 276-276: React Hook useEffect has a missing dependency: 'refetch'. Either include it or remove the dependency array react-hooks/exhaustive-deps


[warning] 411-411: 'data' is defined but never used. Allowed unused args must match /^_/u @typescript-eslint/no-unused-vars


[warning] 412-412: Unexpected console statement no-console

🪛 GitHub Check: autofix
frontend/src/components/rate-limit-modal.tsx

[failure] 35-35:
' can be escaped with &apos;, &lsquo;, &#39;, &rsquo;

🔇 Additional comments (14)
frontend/src/components/rate-limit-modal.tsx (4)

1-19: Well-structured component interface

The props interface is clear and provides good flexibility with the optional limit parameter and required callbacks.


30-43: LGTM: Clear heading and description

The dialog header provides clear information about the rate limit situation with appropriate icon and description.

🧰 Tools
🪛 GitHub Check: autofix

[failure] 35-35:
' can be escaped with &apos;, &lsquo;, &#39;, &rsquo;

🪛 GitHub Actions: autofix.ci

[error] 35-35: 'can be escaped with', , ', ’` react/no-unescaped-entities


44-50: Good use of color-coding for emphasized information

The amber-colored alert box effectively highlights the alternative options for the user.


52-54: Simple and clear action button

The footer button provides a straightforward way for users to acknowledge the message.

frontend/src/app/(main)/page.tsx (2)

10-14: Good import organization

The imports are well-organized with the new type import properly grouped.


19-19: Good component import

The RateLimitModal import is correctly added.

backend/src/project/project.service.ts (4)

198-220: Good structured project creation approach

The code now creates a proper Project entity with all required properties before saving, which is a better practice than directly using the repository.save() with an object literal.


207-215: Improved error handling for package processing

Adding a try-catch block for package processing allows the project creation to continue even if package transformation fails, with proper logging.


222-227: Better parameter passing for background processing

Using the saved project entity instead of just the user ID allows for proper updates to the project in the background process.


259-272: Good error handling and logging for project path updates

The code properly handles the project path update with clear logging for both success and failure cases.

frontend/src/components/chat/code-engine/project-context.tsx (4)

26-29: Well-defined result type for project creation

The new CreateProjectResult type provides a clear contract for what can be returned from the project creation process, making error handling more robust.


110-112: Good use of refs for rate limit tracking

Using refs to track rate limit status is appropriate as it doesn't need to trigger re-renders but needs to be accessible across function calls.


416-430: Improved error handling for rate limits

The enhanced error handling properly identifies and processes rate limit errors from GraphQL, setting the appropriate refs.


739-756: Well-structured result handling

The code now properly checks for rate limits and returns structured results that match the CreateProjectResult type, improving error handling throughout the application.

Comment on lines +21 to +58
export const RateLimitModal = ({
isOpen,
onClose,
limit = 3,
}: RateLimitModalProps) => {
return (
<Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<div className="flex items-center gap-2">
<AlertTriangle className="h-5 w-5 text-amber-500" />
<DialogTitle>Daily Limit Reached</DialogTitle>
</div>
<DialogDescription>
You've reached your daily project creation limit.
</DialogDescription>
</DialogHeader>

<div className="py-4">
<p className="mb-4">
Your current plan allows creating up to {limit} projects per day.
This limit resets at midnight UTC.
</p>
<div className="bg-amber-50 dark:bg-amber-950/30 p-3 rounded-md border border-amber-200 dark:border-amber-800">
<p className="text-sm text-amber-800 dark:text-amber-300">
Try editing or reusing one of your existing projects, or wait
until tomorrow to create a new one.
</p>
</div>
</div>

<DialogFooter>
<Button onClick={onClose}>I understand</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix unescaped apostrophe in JSX content

The JSX content contains an unescaped apostrophe that's causing a pipeline failure.

-            You've reached your daily project creation limit.
+            You&apos;ve reached your daily project creation limit.
📝 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
export const RateLimitModal = ({
isOpen,
onClose,
limit = 3,
}: RateLimitModalProps) => {
return (
<Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<div className="flex items-center gap-2">
<AlertTriangle className="h-5 w-5 text-amber-500" />
<DialogTitle>Daily Limit Reached</DialogTitle>
</div>
<DialogDescription>
You've reached your daily project creation limit.
</DialogDescription>
</DialogHeader>
<div className="py-4">
<p className="mb-4">
Your current plan allows creating up to {limit} projects per day.
This limit resets at midnight UTC.
</p>
<div className="bg-amber-50 dark:bg-amber-950/30 p-3 rounded-md border border-amber-200 dark:border-amber-800">
<p className="text-sm text-amber-800 dark:text-amber-300">
Try editing or reusing one of your existing projects, or wait
until tomorrow to create a new one.
</p>
</div>
</div>
<DialogFooter>
<Button onClick={onClose}>I understand</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
};
export const RateLimitModal = ({
isOpen,
onClose,
limit = 3,
}: RateLimitModalProps) => {
return (
<Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<div className="flex items-center gap-2">
<AlertTriangle className="h-5 w-5 text-amber-500" />
<DialogTitle>Daily Limit Reached</DialogTitle>
</div>
<DialogDescription>
You&apos;ve reached your daily project creation limit.
</DialogDescription>
</DialogHeader>
<div className="py-4">
<p className="mb-4">
Your current plan allows creating up to {limit} projects per day.
This limit resets at midnight UTC.
</p>
<div className="bg-amber-50 dark:bg-amber-950/30 p-3 rounded-md border border-amber-200 dark:border-amber-800">
<p className="text-sm text-amber-800 dark:text-amber-300">
Try editing or reusing one of your existing projects, or wait
until tomorrow to create a new one.
</p>
</div>
</div>
<DialogFooter>
<Button onClick={onClose}>I understand</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
};
🧰 Tools
🪛 GitHub Check: autofix

[failure] 35-35:
' can be escaped with &apos;, &lsquo;, &#39;, &rsquo;

🪛 GitHub Actions: autofix.ci

[error] 35-35: 'can be escaped with', , ', ’` react/no-unescaped-entities

Comment on lines +26 to +29
const [showRateLimitModal, setShowRateLimitModal] = useState(false);
const [rateLimiNumber, setRateLimiNumber] = useState<number | undefined>(
undefined
);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix typo in state variable name

There's a typo in the state variable name which should be corrected for consistency.

-  const [rateLimiNumber, setRateLimiNumber] = useState<number | undefined>(
+  const [rateLimitNumber, setRateLimitNumber] = useState<number | undefined>(
   undefined
  );
📝 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 [showRateLimitModal, setShowRateLimitModal] = useState(false);
const [rateLimiNumber, setRateLimiNumber] = useState<number | undefined>(
undefined
);
const [showRateLimitModal, setShowRateLimitModal] = useState(false);
const [rateLimitNumber, setRateLimitNumber] = useState<number | undefined>(
undefined
);

Comment on lines +202 to +206
<RateLimitModal
isOpen={showRateLimitModal}
limit={rateLimiNumber ?? 3}
onClose={() => setShowRateLimitModal(false)}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix variable name in component props

Fix the variable name in the RateLimitModal component props to match the state variable name change.

<RateLimitModal
  isOpen={showRateLimitModal}
- limit={rateLimiNumber ?? 3}
+ limit={rateLimitNumber ?? 3}
  onClose={() => setShowRateLimitModal(false)}
/>
📝 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
<RateLimitModal
isOpen={showRateLimitModal}
limit={rateLimiNumber ?? 3}
onClose={() => setShowRateLimitModal(false)}
/>
<RateLimitModal
isOpen={showRateLimitModal}
limit={rateLimitNumber ?? 3}
onClose={() => setShowRateLimitModal(false)}
/>

Comment on lines +53 to +57
} else if (isRateLimitResult(result) && result.rateLimit) {
setShowRateLimitModal(true);
setRateLimiNumber(result.limitNumber);
console.log('Rate limit reached ' + result.limitNumber);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove console.log and fix state setter name

There's a console.log that should be removed, and the state setter name needs to be fixed.

  } else if (isRateLimitResult(result) && result.rateLimit) {
    setShowRateLimitModal(true);
-   setRateLimiNumber(result.limitNumber);
-   console.log('Rate limit reached ' + result.limitNumber);
+   setRateLimitNumber(result.limitNumber);
  }
📝 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
} else if (isRateLimitResult(result) && result.rateLimit) {
setShowRateLimitModal(true);
setRateLimiNumber(result.limitNumber);
console.log('Rate limit reached ' + result.limitNumber);
}
} else if (isRateLimitResult(result) && result.rateLimit) {
setShowRateLimitModal(true);
setRateLimitNumber(result.limitNumber);
}
🧰 Tools
🪛 GitHub Actions: autofix.ci

[warning] 56-56: Unexpected console statement no-console

Comment on lines +35 to +39
function isRateLimitResult(
result: CreateProjectResult
): result is { success: false; rateLimit?: boolean; limitNumber?: number } {
return result.success === false;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve type guard function

The isRateLimitResult type guard is checking the success property, but does not specifically check for rate limit conditions, which can lead to incorrect behavior.

function isRateLimitResult(
  result: CreateProjectResult
): result is { success: false; rateLimit?: boolean; limitNumber?: number } {
-  return result.success === false;
+  return result.success === false && result.rateLimit === true;
}
📝 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
function isRateLimitResult(
result: CreateProjectResult
): result is { success: false; rateLimit?: boolean; limitNumber?: number } {
return result.success === false;
}
function isRateLimitResult(
result: CreateProjectResult
): result is { success: false; rateLimit?: boolean; limitNumber?: number } {
- return result.success === false;
+ return result.success === false && result.rateLimit === true;
}

// Create project mutation
const [createProject] = useMutation(CREATE_PROJECT, {
onCompleted: (data) => {
console.log('createProject have yes');
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove console.log statement

There's an unnecessary console.log statement that should be removed.

-      console.log('createProject have yes');
📝 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
console.log('createProject have yes');
🧰 Tools
🪛 GitHub Actions: autofix.ci

[warning] 412-412: Unexpected console statement no-console

@ZHallen122 ZHallen122 closed this Mar 18, 2025
@ZHallen122 ZHallen122 reopened this Mar 18, 2025
@ZHallen122 ZHallen122 marked this pull request as draft March 18, 2025 18:26
@Sma1lboy Sma1lboy changed the title Fix backend project rate limit and feat(frontend) project limit pop up fix(backend): backend project rate limit and feat(frontend) project limit pop up Mar 22, 2025
@autofix-troubleshooter
Copy link

Hi! I'm the autofix logoautofix.ci troubleshooter bot.

It looks like you correctly set up a CI job that uses the autofix.ci GitHub Action, but the autofix.ci GitHub App has not been installed for this repository. This means that autofix.ci unfortunately does not have the permissions to fix this pull request. If you are the repository owner, please install the app and then restart the CI workflow! 😃

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.

4 participants