Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughThis PR adds a rate-limiting feature system for oRPC with a testable UI component, corresponding backend procedures and middleware, and a new comprehensive code-block component system with syntax highlighting. Additionally, UI components are updated for consistency, article markdown rendering is extended, and dependencies are added for enhanced component capabilities. Changes
Sequence Diagram(s)sequenceDiagram
participant User as User<br/>(Browser)
participant Component as MarketingArticlesRateLimitTest
participant Mutation as useTestRateLimit<br/>(React Query)
participant Endpoint as oRPC<br/>test.testRateLimit
participant RateLimit as checkRateLimit<br/>Logic
rect rgb(200, 220, 255)
Note over User,RateLimit: Rate-Limit Test Flow
end
User->>Component: Click "Send Request"
activate Component
Component->>Mutation: mutate({endpoint, timestamp})
activate Mutation
Mutation->>Endpoint: Call with payload
activate Endpoint
Endpoint->>RateLimit: Check rate limit for IP
activate RateLimit
alt Within Limit
RateLimit-->>Endpoint: {allowed: true, remaining}
Endpoint-->>Mutation: {success: true, remaining, limit, resetAt}
rect rgb(200, 240, 200)
Note over Component: Log success<br/>Show toast
end
else Limit Exceeded
RateLimit-->>Endpoint: {allowed: false, retryAfter}
Endpoint-->>Mutation: Error: TOO_MANY_REQUESTS
rect rgb(240, 200, 200)
Note over Component: Log error<br/>Show error toast<br/>Display Retry in Xs
end
end
deactivate RateLimit
deactivate Endpoint
Mutation-->>Component: onSuccess/onError
deactivate Mutation
Component->>Component: Increment requestCount<br/>Update status badge<br/>Render progress
Component-->>User: Visual feedback
deactivate Component
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Areas requiring extra attention:
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (12)
components/app/marketing-subscription.tsx (2)
3-11: Reorder imports to follow project conventions.The import order doesn't follow the established guideline: React imports, third-party imports, internal absolute imports, relative imports, then type-only imports. Currently, internal absolute imports (lines 4-8) appear before third-party imports (lines 9-11).
Apply this diff to fix the import order:
import { useEffect, useState } from "react" -import { useSubscribeToUpdates } from "@/orpc/hooks/use-users" -import { - subscriptionInputSchema, - type SubscriptionInput, -} from "@/schemas/user/roadmap" import { zodResolver } from "@hookform/resolvers/zod" import { useForm } from "react-hook-form" import { toast } from "sonner" + +import { useSubscribeToUpdates } from "@/orpc/hooks/use-users" +import { + subscriptionInputSchema, + type SubscriptionInput, +} from "@/schemas/user/roadmap"Based on coding guidelines.
109-125: Consider adding a FormLabel for better accessibility.The email input field lacks an explicit label, relying only on the placeholder text. For improved accessibility, consider adding a
FormLabelcomponent (which can be visually hidden if needed) so screen readers can properly identify the input field.Example with a visually hidden label:
<FormField control={form.control} name="email" render={({ field }) => ( <FormItem className="w-full sm:flex-1"> + <FormLabel className="sr-only">Email address</FormLabel> <FormControl> <Input type="email" placeholder="your@email.com" disabled={subscribeToUpdatesMutation.isPending} {...field} /> </FormControl> <FormMessage /> </FormItem> )} />Based on coding guidelines.
data/articles/building-bulletproof-apis-rate-limiting-orpc.mdx (1)
1-434: Consider addressing hyphenation in compound adjectives.Static analysis tools suggest using hyphens in compound adjectives like "rate-limiting system" and "open-source implementation" for grammatical correctness. While this is a minor stylistic issue, consistency in technical writing can improve readability.
components/ui/code-block.tsx (1)
580-581: Consider improving type safety instead of suppressing errors.Using
@ts-expect-errorsuppresses type checking. Consider properly typing the cloneElement props or using type assertion for better type safety.Consider this alternative:
if (asChild) { - return cloneElement(children as ReactElement, { - // @ts-expect-error - we know this is a button + return cloneElement(children as ReactElement<{ onClick?: () => void }>, { onClick: copyToClipboard, }); }components/app/marketing-articles-rate-limit-test.tsx (8)
3-6: Fix import order to match guidelinesPlace third-party imports before internal absolute imports.
import { useState } from "react" -import { useTestRateLimit } from "@/orpc/hooks/use-test" -import { toast } from "sonner" +import { toast } from "sonner" +import { useTestRateLimit } from "@/orpc/hooks/use-test"
95-100: Mark decorative icons as aria-hiddenPrevents screen readers from announcing purely visual status glyphs.
- return success ? ( - <Icons.check className="size-3" /> - ) : ( - <Icons.close className="size-3" /> - ) + return success ? ( + <Icons.check aria-hidden="true" className="size-3" /> + ) : ( + <Icons.close aria-hidden="true" className="size-3" /> + )
102-106: Tighten endpoint typingUse the component prop union for stronger type-safety and exhaustiveness.
-const getEndpointColor = (endpoint: string) => { +const getEndpointColor = (endpoint: MarketingArticlesRateLimitTestProps["endpoint"]) => { return endpoint === "strict" ? "bg-red-100 text-red-800 dark:bg-red-900/20 dark:text-red-300" : "bg-blue-100 text-blue-800 dark:bg-blue-900/20 dark:text-blue-300" }
55-56: Use collision‑resistant ids for log keysDate.now() can collide under fast events; prefer randomUUID with a safe fallback.
- id: Date.now().toString(), + id: globalThis.crypto?.randomUUID?.() + ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`,Also applies to: 73-74
173-185: Buttons: add type and disabled opacity classMeets “type attribute for button” and disabled style guidance.
<Button + type="button" onClick={handleTest} disabled={testMutation.isPending} variant={isAtLimit ? "destructive" : "default"} - className="flex items-center gap-2" + className="flex items-center gap-2 disabled:opacity-50" size="lg" ><Button + type="button" onClick={resetTest} variant="outline" size="lg" - className="flex items-center gap-2" + className="flex items-center gap-2 disabled:opacity-50" >Also applies to: 187-195
199-209: Improve log semantics and announcementsUse ul/li for the list and announce updates to assistive tech with aria-live.
- <div className="bg-muted/50 max-h-40 overflow-y-auto rounded-lg border p-3"> - <div className="space-y-2"> - {requestLogs.map((log) => ( - <div + <div + className="bg-muted/50 max-h-40 overflow-y-auto rounded-lg border p-3" + role="region" + aria-live="polite" + aria-relevant="additions" + aria-label="Recent requests" + > + <ul className="space-y-2"> + {requestLogs.map((log) => ( + <li key={log.id} className={`flex items-center gap-3 rounded-md px-3 py-2 text-sm transition-colors ${ log.success ? "bg-emerald-50 text-emerald-900 dark:bg-emerald-950/20 dark:text-emerald-100" : "bg-red-50 text-red-900 dark:bg-red-950/20 dark:text-red-100" }`} > @@ - </div> + </li> ))} - </div> + </ul> </div>Also applies to: 211-246
253-261: Announce status changesExpose the status block as a live region so screen readers get updates.
- <div + <div className={`rounded-lg p-4 ${ isAtLimit ? "border border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950/20" : isNearLimit ? "border border-yellow-200 bg-yellow-50 dark:border-yellow-800 dark:bg-yellow-950/20" : "border border-emerald-200 bg-emerald-50 dark:border-emerald-800 dark:bg-emerald-950/20" }`} + role="status" + aria-live="polite" >
145-148: Adopt cn() for conditional class logic (readability/consistency)Prefer cn() over nested template expressions for Tailwind conditionals.
Example (illustrative):
import { cn } from "@/lib/utils" // Progress <Progress value={progressPercentage} className={cn( "h-2", isAtLimit ? "bg-red-100" : isNearLimit ? "bg-yellow-100" : "bg-green-100", )} /> // Log item <li className={cn( "flex items-center gap-3 rounded-md px-3 py-2 text-sm transition-colors", log.success ? "bg-emerald-50 text-emerald-900 dark:bg-emerald-950/20 dark:text-emerald-100" : "bg-red-50 text-red-900 dark:bg-red-950/20 dark:text-red-100", )}>Also applies to: 214-218
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (12)
app/(marketing)/articles/[slug]/page.tsx(2 hunks)components.json(1 hunks)components/app/marketing-articles-rate-limit-test.tsx(1 hunks)components/app/marketing-subscription.tsx(1 hunks)components/ui/button.tsx(2 hunks)components/ui/code-block.tsx(1 hunks)components/ui/select.tsx(4 hunks)data/articles/building-bulletproof-apis-rate-limiting-orpc.mdx(1 hunks)orpc/hooks/use-test.ts(1 hunks)orpc/routers/index.ts(2 hunks)orpc/routers/test.ts(1 hunks)package.json(2 hunks)
🧰 Additional context used
📓 Path-based instructions (31)
**/*.{html,jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
**/*.{html,jsx,tsx}: Don't use the accessKey attribute on any HTML element
Don't set aria-hidden="true" on focusable elements
Don't add ARIA roles, states, and properties to elements that don't support them
Don't use distracting elements like or
Only use the scope prop on elements
Don't assign non-interactive ARIA roles to interactive HTML elements
Make sure label elements have text content and are associated with an input
Don't assign interactive ARIA roles to non-interactive HTML elements
Don't assign tabIndex to non-interactive HTML elements
Don't use positive integers for the tabIndex property
Don't include "image", "picture", or "photo" in img alt prop
Don't use an explicit role property that's the same as the implicit/default role
Make static elements with click handlers use a valid role attribute
Give all elements requiring alt text meaningful information for screen readers
Make sure anchors have content that's accessible to screen readers
Assign tabIndex to non-interactive HTML elements with aria-activedescendant
Include all required ARIA attributes for elements with ARIA roles
Make sure ARIA properties are valid for the element's supported roles
Always include a type attribute for button elements
Make elements with interactive roles and handlers focusable
Give heading elements content that's accessible to screen readers (not hidden with aria-hidden)
Always include a title attribute for iframe elements
Include caption tracks for audio and video elements
Make sure all anchors are valid and navigable
Ensure all ARIA properties (aria-*) are valid
Use valid, non-abstract ARIA roles for elements with ARIA roles
Use valid ARIA state and property values
Use valid values for the autocomplete attribute on input elements
Use correct ISO language/country codes for the lang attribute
Don't use variables that haven't been declared in the document
Make sure void (self-closing) elements don't have children
Don't use event handlers on non-interactiv...Files:
app/(marketing)/articles/[slug]/page.tsxcomponents/ui/select.tsxcomponents/app/marketing-articles-rate-limit-test.tsxcomponents/app/marketing-subscription.tsxcomponents/ui/button.tsxcomponents/ui/code-block.tsx**/*.{jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
**/*.{jsx,tsx}: Accompany onClick with at least one of: onKeyUp, onKeyDown, or onKeyPress
Accompany onMouseOver/onMouseOut with onFocus/onBlur
Use semantic elements instead of role attributes in JSX
Don't use unnecessary fragments
Don't pass children as props
Don't use the return value of React.render
Make sure all dependencies are correctly specified in React hooks
Make sure all React hooks are called from the top level of component functions
Don't forget key props in iterators and collection literals
Don't define React components inside other components
Don't assign to React component props
Don't use dangerous JSX props
Don't use both children and dangerouslySetInnerHTML props on the same element
Use <>...</> instead of ...
Don't add extra closing tags for components without children
Don't use Array index in keys
Don't insert comments as text nodes
Don't assign JSX properties multiple times
Watch out for possible "wrong" semicolons inside JSX elements
Don't put multiple components in one file; each file must have one componentFiles:
app/(marketing)/articles/[slug]/page.tsxcomponents/ui/select.tsxcomponents/app/marketing-articles-rate-limit-test.tsxcomponents/app/marketing-subscription.tsxcomponents/ui/button.tsxcomponents/ui/code-block.tsx**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
**/*.{js,jsx,ts,tsx}: Don't use consecutive spaces in regular expression literals
Don't use the arguments object
Don't use the comma operator
Don't write functions that exceed a given Cognitive Complexity score
Don't use unnecessary boolean casts
Don't use unnecessary callbacks with flatMap
Use for...of statements instead of Array.forEach
Don't create classes that only have static members
Don't use this and super in static contexts
Don't use unnecessary catch clauses
Don't use unnecessary constructors
Don't use unnecessary continue statements
Don't export empty modules that don't change anything
Don't use unnecessary escape sequences in regular expression literals
Don't use unnecessary labels
Don't use unnecessary nested block statements
Don't rename imports, exports, and destructured assignments to the same name
Don't use unnecessary string or template literal concatenation
Don't use String.raw in template literals when there are no escape sequences
Don't use useless case statements in switch statements
Don't use ternary operators when simpler alternatives exist
Don't use useless this aliasing
Don't initialize variables to undefined
Don't use void operators
Use arrow functions instead of function expressions
Use Date.now() to get milliseconds since the Unix Epoch
Use .flatMap() instead of map().flat() when possible
Use literal property access instead of computed property access
Don't use parseInt() or Number.parseInt() when binary, octal, or hexadecimal literals work
Use concise optional chaining instead of chained logical expressions
Use regular expression literals instead of the RegExp constructor when possible
Don't use number literal object member names that aren't base 10 or use underscore separators
Remove redundant terms from logical expressions
Use while loops instead of for loops when you don't need initializer and update expressions
Don't reassign const variables
Don't use constant expressions in conditions
Don't use Math.min and Math.max to clamp value...Files:
app/(marketing)/articles/[slug]/page.tsxorpc/routers/test.tsorpc/routers/index.tscomponents/ui/select.tsxorpc/hooks/use-test.tscomponents/app/marketing-articles-rate-limit-test.tsxcomponents/app/marketing-subscription.tsxcomponents/ui/button.tsxcomponents/ui/code-block.tsx**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
**/*.{ts,tsx}: Don't use primitive type aliases or misleading types
Don't use empty type parameters in type aliases and interfaces
Don't use any or unknown as type constraints
Don't return a value from a function that has a 'void' return type
Don't use the TypeScript directive @ts-ignore
Make sure switch-case statements are exhaustive
Don't use TypeScript enums
Don't add type annotations to variables, parameters, and class properties that are initialized with literal expressions
Don't use TypeScript namespaces
Don't use non-null assertions with the ! postfix operator
Don't use parameter properties in class constructors
Don't use user-defined types
Use as const instead of literal types and type annotations
Use either T[] or Array consistently
Use consistent accessibility modifiers on class properties and methods
Put default function parameters and optional function parameters last
Initialize each enum member value explicitly
Use export type for types
Use import type for types
Make sure all enum members are literal values
Use function types instead of object types with call signatures
Don't use void type outside of generic or return types
Don't use TypeScript const enum
Don't declare empty interfaces
Don't let variables evolve into any type through reassignments
Don't use the any type
Don't misuse the non-null assertion operator (!) in TypeScript files
Don't use implicit any type on variable declarations
Don't merge interfaces and classes unsafely
Don't use overload signatures that aren't next to each other
Use the namespace keyword instead of the module keyword to declare TypeScript namespacesUse type-only imports when possible
**/*.{ts,tsx}: Use camelCase for function and method names
Use UPPER_SNAKE_CASE for constants
Use camelCase for variables
Use PascalCase for classes and types
Use absolute imports for top-level modules (e.g., @/components, @/lib, @/entities) instead of long relative paths
Follow import order: React imports, third-party, internal abso...Files:
app/(marketing)/articles/[slug]/page.tsxorpc/routers/test.tsorpc/routers/index.tscomponents/ui/select.tsxorpc/hooks/use-test.tscomponents/app/marketing-articles-rate-limit-test.tsxcomponents/app/marketing-subscription.tsxcomponents/ui/button.tsxcomponents/ui/code-block.tsx**/*.{html,jsx,tsx,css}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
Don't use TailwindCSS class names 'h-NUMBER w-NUMBER'; instead use 'size-NUMBR'
Files:
app/(marketing)/articles/[slug]/page.tsxcomponents/ui/select.tsxcomponents/app/marketing-articles-rate-limit-test.tsxcomponents/app/marketing-subscription.tsxcomponents/ui/button.tsxcomponents/ui/code-block.tsxapp/**/page.tsx
📄 CodeRabbit inference engine (.cursor/rules/app-folder.mdc)
Page files must be named page.tsx and define the page component and metadata
Page components in the Next.js App Router must be named page.tsx
Pages must be named page.tsx
Files:
app/(marketing)/articles/[slug]/page.tsxapp/**/[(]*[)]/**
📄 CodeRabbit inference engine (.cursor/rules/app-folder.mdc)
Use parentheses-named folders (group) to create route groups that don’t affect the URL
Files:
app/(marketing)/articles/[slug]/page.tsxapp/**/{page,layout}.tsx
📄 CodeRabbit inference engine (.cursor/rules/app-folder.mdc)
app/**/{page,layout}.tsx: Export a Metadata object asexport const metadatain pages and layouts
Perform server-side data fetching in pages and layouts where possibleFiles:
app/(marketing)/articles/[slug]/page.tsxapp/**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/app-folder.mdc)
app/**/*.tsx: Prefer Server Components by default in the app directory
Add "use client" only when necessary for Client ComponentsFiles:
app/(marketing)/articles/[slug]/page.tsxapp/(marketing)/**
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Place marketing and landing content within app/(marketing)/
Files:
app/(marketing)/articles/[slug]/page.tsx**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/zero-locker-patterns.mdc)
**/*.tsx: Use Component Composition Pattern: build complex UI by composing smaller, reusable components (e.g., Form, FormField, FormItem)
Handle form errors with React Hook Form and Zod resolver for client-side validation
Avoid direct database access in React components; use hooks/services instead
**/*.tsx: Use PascalCase for React component names
Use functional components only, typed with explicit props interfaces
Optimize components using React.memo for expensive components, useMemo for heavy computations, and useCallback for stable handlers
**/*.tsx: Never use useState for form state; use React Hook Form (useForm) instead
Always use Zod schemas with zodResolver for form validation
Always use shadcn Form components: Form, FormField, FormItem, FormLabel, FormControl, FormMessage
Always use Icons.spinner with animate-spin for loading states
Never use text like "Deleting..." or "Loading..." for loading states
Use size-4 instead of h-4 w-4 for spinner sizing (Tailwind)
Disable buttons during loading: disabled={isLoading}
Show spinner + text inside buttons when loading
Use Button variant="destructive" for delete actions
Add disabled opacity class to buttons: className="disabled:opacity-50"
Avoid manual form validation; rely on Zod + resolver integrationFiles:
app/(marketing)/articles/[slug]/page.tsxcomponents/ui/select.tsxcomponents/app/marketing-articles-rate-limit-test.tsxcomponents/app/marketing-subscription.tsxcomponents/ui/button.tsxcomponents/ui/code-block.tsx**/*.{js,ts}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
**/*.{js,ts}: Don't use __dirname and __filename in the global scope
Use with { type: "json" } for JSON module imports
Don't access namespace imports dynamically
Use node:assert/strict over node:assert
Use the node: protocol for Node.js builtin modulesFiles:
orpc/routers/test.tsorpc/routers/index.tsorpc/hooks/use-test.tsorpc/routers/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/orpc-folder.mdc)
orpc/routers/**/*.ts: In oRPC routers, build procedures using os.$context(), then compose authProcedure and permissionProcedure via .use(...) middleware chaining
Define routes with .input(zodSchema).output(zodSchema).handler(async (...) => { ... }) to enforce schema-validated inputs/outputs
For list endpoints, implement pagination (page, limit), deterministic orderBy, and compute total/hasMore
Apply authMiddleware to protected routes and requirePermission(feature, action) where feature-gated access is needed
Use ORPCError with standard codes (e.g., UNAUTHORIZED, FORBIDDEN, NOT_FOUND, BAD_REQUEST) for predictable error handling
Map known ORM errors (e.g., Prisma P2002) to meaningful ORPCError codes like CONFLICT and fall back to INTERNAL_SERVER_ERROR
Always validate inputs with Zod schemas and define explicit output schemas; handle validation errors gracefully
Never expose sensitive fields in responses; use client-safe entity transformations and selective include projections
Group related procedures in a single router file and use consistent naming for routes and files
Use include helpers (e.g., EntityQuery.getClientSafeInclude()) to fetch only client-safe relations
Use server-side caching or efficient queries where appropriate; prefer pagination over large result sets
Return deterministic ordering for list endpoints (e.g., orderBy createdAt desc)
Provide meaningful error messages when throwing BAD_REQUEST/CONFLICT while avoiding sensitive details
orpc/routers/**/*.ts: Group routes by feature (e.g., credentialRouter, cardRouter) in dedicated router files
Use descriptive, action-indicative procedure names within routers
Use action-based names: create, getById, list, update, delete
Keep procedure names consistent across all routers
Use camelCase for procedure names
Use Zod schemas for all procedure inputs via .input(schema)
List procedures must return metadata (total, hasMore, page, limit) alongside data
Apply authentication middleware to all protecte...Files:
orpc/routers/test.tsorpc/routers/index.tsorpc/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/project-overview.mdc)
Ensure consistent error handling and responses within oRPC routes and client code
orpc/**/*.ts: Use oRPC standard error codes (ORPCError) with meaningful, contextual messages
Handle specific error types (e.g., Prisma codes), log errors, and map to appropriate ORPC error codes
Use FORBIDDEN for permission errors; include feature and action in the message and upgrade info when applicableAlways encrypt passwords before storage in server-side handlers/services
Files:
orpc/routers/test.tsorpc/routers/index.tsorpc/hooks/use-test.tsorpc/routers/**/!(*index).ts
📄 CodeRabbit inference engine (.cursor/rules/orpc-patterns.mdc)
Export routers individually from their own files
Files:
orpc/routers/test.tsorpc/routers/*.ts
📄 CodeRabbit inference engine (.cursor/rules/zero-locker-rules.mdc)
Define route handlers in orpc/routers with one file per domain (e.g., credential.ts, card.ts)
Files:
orpc/routers/test.tsorpc/routers/index.ts{components,entities,lib,orpc,schemas,hooks,config,types}/**/index.ts
📄 CodeRabbit inference engine (.cursor/rules/project-overview.mdc)
Use barrel exports: each folder should include an index.ts for clean imports
Files:
orpc/routers/index.tsorpc/routers/index.ts
📄 CodeRabbit inference engine (.cursor/rules/orpc-patterns.mdc)
Aggregate and export all feature routers in orpc/routers/index.ts
Files:
orpc/routers/index.tscomponents/ui/**
📄 CodeRabbit inference engine (.cursor/rules/components-folder.mdc)
Place base shadcn/ui components under components/ui
Files:
components/ui/select.tsxcomponents/ui/button.tsxcomponents/ui/code-block.tsxcomponents/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/components-folder.mdc)
components/**/*.{ts,tsx}: Always define a TypeScript interface for component props
Follow established naming patterns consistently across files
Use strict, explicit TypeScript types for safetyFiles:
components/ui/select.tsxcomponents/app/marketing-articles-rate-limit-test.tsxcomponents/app/marketing-subscription.tsxcomponents/ui/button.tsxcomponents/ui/code-block.tsxcomponents/**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/components-folder.mdc)
components/**/*.tsx: Add 'use client' directive for components that use client-side hooks/effects
Use cn() for conditional Tailwind classes
Use semantic Tailwind colors (e.g., text-foreground, bg-background) and consistent spacing (space-y-4, gap-4)
Use responsive Tailwind prefixes (md:, lg:, xl:) for adaptive layouts
Define component variants with cva and defaultVariants when variants are needed
Prefer useState for local state; use useReducer for complex state
Use TanStack Query hooks from /orpc/hooks for server state; prefer server-side data fetching when possible
Implement proper ARIA attributes and keyboard navigation for accessibility
Use React.memo for expensive components
Use useMemo and useCallback for expensive computations and stable callbacks
Lazy-load heavy components via dynamic import
Import only needed icons from lucide-react (no wildcard imports)
Wrap components that might fail in Error Boundaries
Provide loading and error states for async UI
Add JSDoc comments for complex components
components/**/*.tsx: Components must be named in kebab-case.tsx (e.g., dashboard-credential-form.tsx)
Use React Hook Form for form management in UI forms
Use React Hook Form error handling, display validation errors, and handle submission errors gracefully in formsFiles:
components/ui/select.tsxcomponents/app/marketing-articles-rate-limit-test.tsxcomponents/app/marketing-subscription.tsxcomponents/ui/button.tsxcomponents/ui/code-block.tsxcomponents/**/[a-z0-9-]*.tsx
📄 CodeRabbit inference engine (.cursor/rules/project-overview.mdc)
Name React components in kebab-case with .tsx under the components directory (e.g., dashboard-credential-form.tsx)
Files:
components/ui/select.tsxcomponents/app/marketing-articles-rate-limit-test.tsxcomponents/app/marketing-subscription.tsxcomponents/ui/button.tsxcomponents/ui/code-block.tsxcomponents/{app,layout,shared,ui}/**
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Organize React components under components/app, components/layout, components/shared, and components/ui
Files:
components/ui/select.tsxcomponents/app/marketing-articles-rate-limit-test.tsxcomponents/app/marketing-subscription.tsxcomponents/ui/button.tsxcomponents/ui/code-block.tsxcomponents/{layout,shared,ui}/**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/zero-locker-rules.mdc)
Organize layout, shared, and base UI components under components/layout, components/shared, and components/ui
Files:
components/ui/select.tsxcomponents/ui/button.tsxcomponents/ui/code-block.tsxorpc/hooks/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/orpc-folder.mdc)
orpc/hooks/**/*.ts: Create React Query hooks that call orpc client methods with stable queryKey factories
Use enabled flags for queries that depend on optional parameters (e.g., only fetch detail when id is truthy)
On successful mutations, invalidate relevant list queries and update detail cache via setQueryData when possible
Centralize query keys with a factory (e.g., entityKeys) to ensure consistent cache keys across hooksUse TanStack Query for server state in hooks
Files:
orpc/hooks/use-test.tsorpc/hooks/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Place React Query hooks for API calls under orpc/hooks/
Files:
orpc/hooks/use-test.ts**/use-*.ts
📄 CodeRabbit inference engine (.cursor/rules/zero-locker-rules.mdc)
Hooks files must be named use-kebab-case.ts (e.g., use-copy-to-clipboard.ts)
Files:
orpc/hooks/use-test.tsorpc/hooks/use-*.ts
📄 CodeRabbit inference engine (.cursor/rules/zero-locker-rules.mdc)
Place oRPC-related hooks under orpc/hooks with use-*.ts naming
Files:
orpc/hooks/use-test.tscomponents/app/**
📄 CodeRabbit inference engine (.cursor/rules/components-folder.mdc)
Place application-specific React components under components/app
Files:
components/app/marketing-articles-rate-limit-test.tsxcomponents/app/marketing-subscription.tsxcomponents/app/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/components-folder.mdc)
Use naming pattern {feature}-{purpose}-{type}.tsx for app components
Files:
components/app/marketing-articles-rate-limit-test.tsxcomponents/app/marketing-subscription.tsxcomponents/app/marketing-*.tsx
📄 CodeRabbit inference engine (.cursor/rules/components-folder.mdc)
Marketing components in components/app must be prefixed with marketing-
Place marketing components under components/app/ with filenames starting marketing-*.tsx
Files:
components/app/marketing-articles-rate-limit-test.tsxcomponents/app/marketing-subscription.tsx🧠 Learnings (13)
📚 Learning: 2025-10-02T21:01:44.094Z
Learnt from: CR PR: FindMalek/zero-locker#0 File: .cursor/rules/orpc-folder.mdc:0-0 Timestamp: 2025-10-02T21:01:44.094Z Learning: Applies to orpc/routers/**/*.ts : Group related procedures in a single router file and use consistent naming for routes and filesApplied to files:
orpc/routers/test.tsorpc/routers/index.ts📚 Learning: 2025-10-02T21:01:44.094Z
Learnt from: CR PR: FindMalek/zero-locker#0 File: .cursor/rules/orpc-folder.mdc:0-0 Timestamp: 2025-10-02T21:01:44.094Z Learning: Applies to orpc/routers/**/*.ts : In oRPC routers, build procedures using os.$context<ORPCContext>(), then compose authProcedure and permissionProcedure via .use(...) middleware chainingApplied to files:
orpc/routers/test.ts📚 Learning: 2025-10-02T22:19:00.164Z
Learnt from: CR PR: FindMalek/zero-locker#0 File: .cursor/rules/orpc-patterns.mdc:0-0 Timestamp: 2025-10-02T22:19:00.164Z Learning: Applies to orpc/routers/**/*.ts : Keep procedure names consistent across all routersApplied to files:
orpc/routers/test.ts📚 Learning: 2025-10-02T22:19:00.164Z
Learnt from: CR PR: FindMalek/zero-locker#0 File: .cursor/rules/orpc-patterns.mdc:0-0 Timestamp: 2025-10-02T22:19:00.164Z Learning: Applies to orpc/routers/**/*.ts : Use descriptive, action-indicative procedure names within routersApplied to files:
orpc/routers/test.ts📚 Learning: 2025-10-02T21:01:44.094Z
Learnt from: CR PR: FindMalek/zero-locker#0 File: .cursor/rules/orpc-folder.mdc:0-0 Timestamp: 2025-10-02T21:01:44.094Z Learning: Applies to orpc/**/*.{test,spec}.{ts,tsx} : Write route tests covering success, error conditions, auth/permission checks, and input validationApplied to files:
orpc/routers/test.ts📚 Learning: 2025-10-02T22:19:00.164Z
Learnt from: CR PR: FindMalek/zero-locker#0 File: .cursor/rules/orpc-patterns.mdc:0-0 Timestamp: 2025-10-02T22:19:00.164Z Learning: Applies to orpc/routers/index.ts : Aggregate and export all feature routers in orpc/routers/index.tsApplied to files:
orpc/routers/index.ts📚 Learning: 2025-10-02T22:19:00.164Z
Learnt from: CR PR: FindMalek/zero-locker#0 File: .cursor/rules/orpc-patterns.mdc:0-0 Timestamp: 2025-10-02T22:19:00.164Z Learning: Applies to orpc/routers/**/!(*index).ts : Export routers individually from their own filesApplied to files:
orpc/routers/index.ts📚 Learning: 2025-10-02T21:01:44.094Z
Learnt from: CR PR: FindMalek/zero-locker#0 File: .cursor/rules/orpc-folder.mdc:0-0 Timestamp: 2025-10-02T21:01:44.094Z Learning: Applies to orpc/**/*.{test,spec}.{ts,tsx} : Write hook tests covering queries with mocks, mutation flows including cache updates, and error statesApplied to files:
orpc/hooks/use-test.ts📚 Learning: 2025-10-02T22:16:27.157Z
Learnt from: CR PR: FindMalek/zero-locker#0 File: .cursor/rules/architecture.mdc:0-0 Timestamp: 2025-10-02T22:16:27.157Z Learning: Applies to orpc/hooks/**/*.{ts,tsx} : Place React Query hooks for API calls under orpc/hooks/Applied to files:
orpc/hooks/use-test.ts📚 Learning: 2025-10-02T22:21:11.735Z
Learnt from: CR PR: FindMalek/zero-locker#0 File: .cursor/rules/zero-locker-rules.mdc:0-0 Timestamp: 2025-10-02T22:21:11.735Z Learning: Applies to orpc/hooks/use-*.ts : Place oRPC-related hooks under orpc/hooks with use-*.ts namingApplied to files:
orpc/hooks/use-test.ts📚 Learning: 2025-10-02T21:01:44.094Z
Learnt from: CR PR: FindMalek/zero-locker#0 File: .cursor/rules/orpc-folder.mdc:0-0 Timestamp: 2025-10-02T21:01:44.094Z Learning: Applies to orpc/hooks/**/*.ts : Create React Query hooks that call orpc client methods with stable queryKey factoriesApplied to files:
orpc/hooks/use-test.ts📚 Learning: 2025-10-06T20:52:07.624Z
Learnt from: CR PR: FindMalek/zero-locker#0 File: .cursor/rules/loading-button-patterns.mdc:0-0 Timestamp: 2025-10-06T20:52:07.624Z Learning: Applies to **/*.tsx : Use Button variant="destructive" for delete actionsApplied to files:
components/ui/button.tsx📚 Learning: 2025-10-02T20:56:15.975Z
Learnt from: CR PR: FindMalek/zero-locker#0 File: .cursor/rules/components-folder.mdc:0-0 Timestamp: 2025-10-02T20:56:15.975Z Learning: Applies to components/**/*.tsx : Define component variants with cva and defaultVariants when variants are neededApplied to files:
components/ui/button.tsx🧬 Code graph analysis (5)
app/(marketing)/articles/[slug]/page.tsx (2)
components/ui/code-block.tsx (1)
SimpleCodeBlock(427-483)components/app/marketing-articles-rate-limit-test.tsx (1)
MarketingArticlesRateLimitTest(34-291)orpc/routers/test.ts (2)
orpc/types.ts (1)
ORPCContext(14-28)lib/utils/rate-limit.ts (2)
checkRateLimit(187-267)RATE_LIMIT_PRESETS(301-322)orpc/routers/index.ts (1)
orpc/routers/test.ts (1)
testRouter(154-158)components/app/marketing-articles-rate-limit-test.tsx (2)
orpc/hooks/use-test.ts (1)
useTestRateLimit(5-12)components/shared/icons.tsx (1)
Icons(165-293)components/ui/code-block.tsx (2)
components/ui/select.tsx (5)
Select(177-177)SelectTrigger(185-185)SelectValue(186-186)SelectContent(178-178)SelectItem(180-180)components/ui/button.tsx (1)
Button(60-60)🪛 ast-grep (0.39.6)
components/ui/code-block.tsx
[warning] 702-702: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html(react-unsafe-html-injection)
[warning] 746-746: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html(react-unsafe-html-injection)
🪛 LanguageTool
data/articles/building-bulletproof-apis-rate-limiting-orpc.mdx
[grammar] ~11-~11: Use a hyphen to join words.
Context: ... tutorial - we're building the same rate limiting system that protects Zero Locke...(QB_NEW_EN_HYPHEN)
[uncategorized] ~17-~17: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...of this, you'll have: - ✅ A multi-tier rate limiting system that actually works - ✅ oRPC mid...(EN_COMPOUND_ADJECTIVE_INTERNAL)
[uncategorized] ~48-~48: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...g step by step. ## 📋 Step 1: The Core Rate Limiting Engine First things first - we need th...(EN_COMPOUND_ADJECTIVE_INTERNAL)
[grammar] ~50-~50: Use a hyphen to join words.
Context: ...gs first - we need the brain of our rate limiting system. This handles the slidin...(QB_NEW_EN_HYPHEN)
[grammar] ~124-~124: Use a hyphen to join words.
Context: ...limit:${ip}` }`} /> Now the main rate limiting logic: <CodeBlock language=...(QB_NEW_EN_HYPHEN)
[uncategorized] ~429-~429: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...system in production. Or check out our [open source implementation](https://github.com/Find...(EN_COMPOUND_ADJECTIVE_INTERNAL)
[grammar] ~433-~433: Use a hyphen to join words.
Context: ... _This is the real deal - the same rate limiting system protecting Zero Locker i...(QB_NEW_EN_HYPHEN)
🔇 Additional comments (9)
components.json (2)
13-13: Reordering "iconLibrary" maintains consistent configuration structure.The relocation of the
iconLibraryentry before thealiasessection doesn't affect functionality but improves config organization. This aligns with the supporting new icon-based UI components mentioned in the PR.
21-23: New registry configuration properly enables @kibo-ui component installation.The "registries" field allows you to configure multiple resource registries for your project, enabling installation of components, libraries, utilities, and other resources from various sources. The
@kibo-uinamespace with the URL templatehttps://www.kibo-ui.com/r/{name}.jsonfollows the correct shadcn pattern and enables the CLI to resolve components via commands likenpx shadcn add @kibo-ui/component-name.package.json (2)
74-74: All three new dependencies verified and compatible.Package versions exist, no security vulnerabilities found, and peer dependencies are satisfied:
@radix-ui/react-use-controllable-state@1.2.2: Compatible with React 19@shikijs/transformers@3.13.0andshiki@3.13.0: Versions aligned, no conflicts with existing dependencies
74-74: No issues found — @radix-ui/react-use-controllable-state@^1.2.2 is properly integrated.The package is already in package.json (line 74) and the version constraint is compatible with the existing Radix UI dependencies. As an internal utility already used transitively by packages like react-checkbox and react-dropdown-menu, it maintains compatibility across the ^1.x and ^2.x versions present in the project.
orpc/routers/index.ts (1)
7-7: LGTM!The testRouter integration follows the established pattern for aggregating feature routers.
Also applies to: 18-18
components/ui/select.tsx (1)
7-7: LGTM!The changes enhance the Select component API by:
- Updating to the standardized import path
- Simplifying the icon rendering (always visible)
- Adding an
alignprop with a sensible defaultAlso applies to: 46-48, 57-57, 71-71
components/ui/button.tsx (1)
5-5: LGTM!The changes enhance the Button component by:
- Using the standardized import path
- Refining visual styling (removed shadow-xs)
- Adding new icon size variants (
icon-smandicon-lg)Also applies to: 12-18, 28-29
app/(marketing)/articles/[slug]/page.tsx (1)
9-9: LGTM!The changes properly extend MDX rendering capabilities by mapping custom components (
CodeBlockandRateLimitTest) to their React implementations. This follows the standard MDX component customization pattern.Also applies to: 12-12, 108-109
components/app/marketing-articles-rate-limit-test.tsx (1)
34-41: Overall: solid component, props/types look goodNice client directive, prop interface, and clear UX with spinner/toasts. Keep it up.
| // biome-ignore lint/suspicious/noConsole: "it's fine" | ||
| .catch(console.error); |
There was a problem hiding this comment.
Remove console.error usage.
The coding guidelines prohibit using console methods. Consider removing the error logging or using a proper logging solution if error tracking is needed.
As per coding guidelines
Apply this diff:
highlight(children as string, language, themes)
.then(setHtml)
- // biome-ignore lint/suspicious/noConsole: "it's fine"
- .catch(console.error);
+ .catch(() => {
+ // Silently fail and fallback to raw code
+ });📝 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.
| // biome-ignore lint/suspicious/noConsole: "it's fine" | |
| .catch(console.error); | |
| highlight(children as string, language, themes) | |
| .then(setHtml) | |
| .catch(() => { | |
| // Silently fail and fallback to raw code | |
| }); |
🤖 Prompt for AI Agents
In components/ui/code-block.tsx around lines 692-693, remove the direct use of
console.error in the promise catch; replace it with the project's logging
utility or error handling flow. Import or reference the existing logger (e.g.,
processLogger or appLogger) and call its error method with the caught error and
context, or if logging isn't desired, handle the error silently or propagate it
(return/rethrow) according to the function's contract; ensure no console.* calls
remain and update imports accordingly.
Summary by CodeRabbit