Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedThe pull request is closed. Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughAdds a new NOTIFY_SENDER action end-to-end: database enum and migration, AI action handler, Resend email template and send logic, frontend UI/constants/validation, env flag for Resend, subject formatting guard, error utils update, Cold Email blocker UI tweak, and a version bump. Changes
Sequence Diagram(s)sequenceDiagram
participant Email as Incoming Email
participant AI as AI Action Handler
participant Notify as sendColdEmailNotification
participant Resend as Resend Service
participant Sender as Cold Emailer
Email->>AI: Email ingested (headers, subject, messageId)
AI->>AI: Rule matches → ActionType.NOTIFY_SENDER
AI->>Notify: call with senderEmail, recipientEmail, originalSubject, messageId
activate Notify
Notify->>Notify: format reply subject, build payload (from,to,replyTo,in-reply-to)
Notify->>Resend: render ColdEmailNotification & send via Resend API
activate Resend
Resend-->>Notify: send response (success / error)
deactivate Resend
alt success
Notify->>Notify: log success (message id)
else error
Notify->>Notify: log error and return failure
end
Notify-->>AI: { success, error? }
deactivate Notify
opt delivered
Resend->>Sender: deliver notification email
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
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.
2 issues found across 16 files
Prompt for AI agents (all 2 issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="apps/web/app/(app)/[emailAccountId]/assistant/constants.ts">
<violation number="1" location="apps/web/app/(app)/[emailAccountId]/assistant/constants.ts:29">
P2: The `getActionTypeColor` helper function is missing a case for the new `NOTIFY_SENDER` action type. Following the established pattern in this file, consider adding a condition to handle strings containing "notify" to return the correct amber color.</violation>
</file>
<file name="apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx">
<violation number="1" location="apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx:343">
P2: Missing `rule.systemType` in the `useMemo` dependency array. The memoized `typeOptions` now depends on `rule.systemType` but this value isn't included in the dependencies, which could cause stale options when the rule type changes. Add `rule.systemType` to the dependency array.</violation>
</file>
Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx (1)
282-355: Addrule.systemTypeto useMemo dependencies.The
typeOptionsmemoization depends onrule.systemType(checked at line 343), but it's not included in the dependencies array at line 355. WhilesystemTyperarely changes after initialization, adding it ensures correctness and prevents potential stale closures.🔎 Proposed fix
return options; - }, [provider, terminology.label.action]); + }, [provider, terminology.label.action, rule.systemType]);
🧹 Nitpick comments (2)
packages/resend/emails/cold-email-notification.tsx (1)
34-36: Consider usingbaseUrlprop for the image URL.The image URL is currently hardcoded to
"https://www.getinboxzero.com/icon.png", which matches the defaultbaseUrl. For consistency and flexibility, consider using thebaseUrlprop:- src={"https://www.getinboxzero.com/icon.png"} + src={`${baseUrl}/icon.png`}This ensures the image URL adapts when a different
baseUrlis provided.apps/web/utils/ai/actions.ts (1)
328-345: Consider logging the notification result for better observability.The
notify_senderfunction callssendColdEmailNotificationbut doesn't capture or log the result. SincesendColdEmailNotificationreturns{ success: boolean; error?: string }, capturing this would improve observability and debugging.🔎 Suggested improvement
const notify_sender: ActionFunction<Record<string, unknown>> = async ({ email, userEmail, logger, }) => { const senderEmail = extractEmailAddress(email.headers.from); if (!senderEmail) { logger.error("Could not extract sender email for notify_sender action"); return; } - await sendColdEmailNotification({ + const result = await sendColdEmailNotification({ senderEmail, recipientEmail: userEmail, originalSubject: email.headers.subject, logger, }); + + if (!result.success) { + logger.warn("Notify sender action completed with error", { + error: result.error, + senderEmail, + }); + } };
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsx(1 hunks)apps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsx(1 hunks)apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx(1 hunks)apps/web/app/(app)/[emailAccountId]/assistant/constants.ts(4 hunks)apps/web/app/(landing)/components/page.tsx(1 hunks)apps/web/components/PlanBadge.tsx(2 hunks)apps/web/prisma/migrations/20251219012216_add_notify_sender_action_type/migration.sql(1 hunks)apps/web/prisma/schema.prisma(1 hunks)apps/web/utils/action-display.tsx(3 hunks)apps/web/utils/action-item.ts(2 hunks)apps/web/utils/actions/rule.validation.ts(1 hunks)apps/web/utils/ai/actions.ts(3 hunks)apps/web/utils/cold-email/send-notification.ts(1 hunks)packages/resend/emails/cold-email-notification.tsx(1 hunks)packages/resend/src/send.tsx(3 hunks)version.txt(1 hunks)
🧰 Additional context used
📓 Path-based instructions (32)
**/prisma/schema.prisma
📄 CodeRabbit inference engine (.cursor/rules/prisma.mdc)
Use PostgreSQL as the database system with Prisma
Files:
apps/web/prisma/schema.prisma
!(pages/_document).{jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)
Don't use the next/head module in pages/_document.js on Next.js projects
Files:
apps/web/prisma/schema.prismaapps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/prisma/migrations/20251219012216_add_notify_sender_action_type/migration.sqlapps/web/utils/actions/rule.validation.tsapps/web/utils/cold-email/send-notification.tsapps/web/utils/action-item.tsapps/web/utils/action-display.tsxpackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/assistant/constants.tsapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxversion.txtpackages/resend/emails/cold-email-notification.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsxapps/web/utils/ai/actions.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/data-fetching.mdc)
**/*.{ts,tsx}: For API GET requests to server, use theswrpackage
Useresult?.serverErrorwithtoastErrorfrom@/components/Toastfor error handling in async operations
**/*.{ts,tsx}: Use wrapper functions for Gmail message operations (get, list, batch, etc.) from @/utils/gmail/message.ts instead of direct API calls
Use wrapper functions for Gmail thread operations from @/utils/gmail/thread.ts instead of direct API calls
Use wrapper functions for Gmail label operations from @/utils/gmail/label.ts instead of direct API calls
**/*.{ts,tsx}: For early access feature flags, create hooks using the naming conventionuse[FeatureName]Enabledthat return a boolean fromuseFeatureFlagEnabled("flag-key")
For A/B test variant flags, create hooks using the naming conventionuse[FeatureName]Variantthat define variant types, useuseFeatureFlagVariantKey()with type casting, and provide a default "control" fallback
Use kebab-case for PostHog feature flag keys (e.g.,inbox-cleaner,pricing-options-2)
Always define types for A/B test variant flags (e.g.,type PricingVariant = "control" | "variant-a" | "variant-b") and provide type safety through type casting
**/*.{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 this and super in static contexts
Don't use any or unknown as type constraints
Don't use the TypeScript directive @ts-ignore
Don't use TypeScript enums
Don't export imported variables
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
Useas constinstead of literal types and type annotations
Use eitherT[]orArray<T>consistently
Initialize each enum member value explicitly
Useexport typefor types
Use `impo...
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/utils/actions/rule.validation.tsapps/web/utils/cold-email/send-notification.tsapps/web/utils/action-item.tsapps/web/utils/action-display.tsxpackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/assistant/constants.tsapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxpackages/resend/emails/cold-email-notification.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsxapps/web/utils/ai/actions.ts
apps/web/app/(app)/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/page-structure.mdc)
apps/web/app/(app)/**/*.{ts,tsx}: Components for the page are either put inpage.tsx, or in theapps/web/app/(app)/PAGE_NAMEfolder
If we're in a deeply nested component we will useswrto fetch via API
If you need to useonClickin a component, that component is a client component and file must start withuse client
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/app/(app)/[emailAccountId]/assistant/constants.tsapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/prisma-enum-imports.mdc)
Always import Prisma enums from
@/generated/prisma/enumsinstead of@/generated/prisma/clientto avoid Next.js bundling errors in client componentsImport Prisma using the project's centralized utility:
import prisma from '@/utils/prisma'
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/utils/actions/rule.validation.tsapps/web/utils/cold-email/send-notification.tsapps/web/utils/action-item.tsapps/web/utils/action-display.tsxpackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/assistant/constants.tsapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxpackages/resend/emails/cold-email-notification.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsxapps/web/utils/ai/actions.ts
apps/web/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Import specific lodash functions rather than entire lodash library to minimize bundle size (e.g.,
import groupBy from 'lodash/groupBy')
apps/web/**/*.{ts,tsx}: Use TypeScript with strict null checks
Use@/path aliases for imports from project root
Follow tailwindcss patterns with prettier-plugin-tailwindcss class organization
Prefix client-side environment variables withNEXT_PUBLIC_
Leverage TypeScript inference for better developer experience with type exports from API routes
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/utils/actions/rule.validation.tsapps/web/utils/cold-email/send-notification.tsapps/web/utils/action-item.tsapps/web/utils/action-display.tsxapps/web/app/(app)/[emailAccountId]/assistant/constants.tsapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsxapps/web/utils/ai/actions.ts
**/*.{tsx,ts}
📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)
**/*.{tsx,ts}: Use Shadcn UI and Tailwind for components and styling
Usenext/imagepackage for images
For API GET requests to server, use theswrpackage with hooks likeuseSWRto fetch data
For text inputs, use theInputcomponent withregisterPropsfor form integration and error handling
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/utils/actions/rule.validation.tsapps/web/utils/cold-email/send-notification.tsapps/web/utils/action-item.tsapps/web/utils/action-display.tsxpackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/assistant/constants.tsapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxpackages/resend/emails/cold-email-notification.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsxapps/web/utils/ai/actions.ts
**/*.{tsx,ts,css}
📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)
Implement responsive design with Tailwind CSS using a mobile-first approach
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/utils/actions/rule.validation.tsapps/web/utils/cold-email/send-notification.tsapps/web/utils/action-item.tsapps/web/utils/action-display.tsxpackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/assistant/constants.tsapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxpackages/resend/emails/cold-email-notification.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsxapps/web/utils/ai/actions.ts
**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)
**/*.tsx: Use theLoadingContentcomponent to handle loading states instead of manual loading state management
For text areas, use theInputcomponent withtype='text',autosizeTextareaprop set to true, andregisterPropsfor form integration
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/utils/action-display.tsxpackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxpackages/resend/emails/cold-email-notification.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)
**/*.{js,jsx,ts,tsx}: Don't useaccessKeyattribute on any HTML element
Don't setaria-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<marquee>or<blink>
Only use thescopeprop on<th>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 assigntabIndexto non-interactive HTML elements
Don't use positive integers fortabIndexproperty
Don't include "image", "picture", or "photo" in img alt prop
Don't use explicit role property that's the same as the implicit/default role
Make static elements with click handlers use a valid role attribute
Always include atitleelement for SVG elements
Give all elements requiring alt text meaningful information for screen readers
Make sure anchors have content that's accessible to screen readers
AssigntabIndexto non-interactive HTML elements witharia-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 atypeattribute for button elements
Make elements with interactive roles and handlers focusable
Give heading elements content that's accessible to screen readers (not hidden witharia-hidden)
Always include alangattribute on the html element
Always include atitleattribute for iframe elements
AccompanyonClickwith at least one of:onKeyUp,onKeyDown, oronKeyPress
AccompanyonMouseOver/onMouseOutwithonFocus/onBlur
Include caption tracks for audio and video elements
Use semantic elements instead of role attributes in JSX
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 AR...
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/utils/actions/rule.validation.tsapps/web/utils/cold-email/send-notification.tsapps/web/utils/action-item.tsapps/web/utils/action-display.tsxpackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/assistant/constants.tsapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxpackages/resend/emails/cold-email-notification.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsxapps/web/utils/ai/actions.ts
**/*.{jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)
**/*.{jsx,tsx}: 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 use event handlers on non-interactive elements
Don't assign to React component props
Don't use bothchildrenanddangerouslySetInnerHTMLprops on the same element
Don't use dangerous JSX props
Don't use Array index in keys
Don't insert comments as text nodes
Don't assign JSX properties multiple times
Don't add extra closing tags for components without children
Use<>...</>instead of<Fragment>...</Fragment>
Watch out for possible "wrong" semicolons inside JSX elements
Make sure void (self-closing) elements don't have children
Don't usetarget="_blank"withoutrel="noopener"
Don't use<img>elements in Next.js projects
Don't use<head>elements in Next.js projects
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/utils/action-display.tsxpackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxpackages/resend/emails/cold-email-notification.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsx
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/utilities.mdc)
**/*.{js,ts,jsx,tsx}: Use lodash utilities for common operations (arrays, objects, strings)
Import specific lodash functions to minimize bundle size (e.g.,import groupBy from 'lodash/groupBy')
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/utils/actions/rule.validation.tsapps/web/utils/cold-email/send-notification.tsapps/web/utils/action-item.tsapps/web/utils/action-display.tsxpackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/assistant/constants.tsapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxpackages/resend/emails/cold-email-notification.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsxapps/web/utils/ai/actions.ts
apps/web/**/app/**
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Follow NextJS app router structure with (app) directory
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/app/(app)/[emailAccountId]/assistant/constants.tsapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsx
apps/web/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
apps/web/**/*.{tsx,jsx}: Prefer functional components with hooks over class components
Use shadcn/ui components when available
Follow consistent naming conventions with PascalCase for component names
Use LoadingContent component for async data with loading and error states
Useresult?.serverErrorwithtoastErrorandtoastSuccessfor mutation error handling
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/utils/action-display.tsxapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsx
apps/web/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
apps/web/**/*.{ts,tsx,js,jsx}: Use proper error handling with try/catch blocks
Prefer self-documenting code over comments; use descriptive variable and function names instead of explaining intent with comments
Add helper functions to the bottom of files, not the top
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/utils/actions/rule.validation.tsapps/web/utils/cold-email/send-notification.tsapps/web/utils/action-item.tsapps/web/utils/action-display.tsxapps/web/app/(app)/[emailAccountId]/assistant/constants.tsapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsxapps/web/utils/ai/actions.ts
apps/web/**/*.{ts,tsx,js,jsx,json,css,md}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Format code with Prettier
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/utils/actions/rule.validation.tsapps/web/utils/cold-email/send-notification.tsapps/web/utils/action-item.tsapps/web/utils/action-display.tsxapps/web/app/(app)/[emailAccountId]/assistant/constants.tsapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsxapps/web/utils/ai/actions.ts
apps/web/**/*.{tsx,jsx,css}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Ensure responsive design with mobile-first approach
Files:
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsxapps/web/utils/action-display.tsxapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsxapps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsx
**/*.validation.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/form-handling.mdc)
**/*.validation.{ts,tsx}: Define validation schemas using Zod
Use descriptive error messages in validation schemas
Files:
apps/web/utils/actions/rule.validation.ts
apps/web/utils/actions/*.ts
📄 CodeRabbit inference engine (.cursor/rules/fullstack-workflow.mdc)
apps/web/utils/actions/*.ts: Usenext-safe-actionwith Zod schemas for all server actions (create/update/delete mutations), storing validation schemas inapps/web/utils/actions/*.validation.ts
Server actions should use 'use server' directive and automatically receive authentication context (emailAccountId) from theactionClient
apps/web/utils/actions/*.ts: Create corresponding server action implementation files using the naming conventionapps/web/utils/actions/NAME.tswith 'use server' directive
Use 'use server' directive at the top of server action implementation files
Implement all server actions using thenext-safe-actionlibrary with actionClient, actionClientUser, or adminActionClient for type safety and validation
UseactionClientUserwhen only authenticated user context (userId) is needed
UseactionClientwhen both authenticated user context and a specific emailAccountId are needed, with emailAccountId bound when calling from the client
UseadminActionClientfor actions restricted to admin users
Add metadata with a meaningful action name using.metadata({ name: "actionName" })for Sentry instrumentation and monitoring
Use.schema()method with Zod validation schemas from corresponding.validation.tsfiles in next-safe-action configuration
Access context (userId, emailAccountId, etc.) via thectxobject parameter in the.action()handler
UserevalidatePathorrevalidateTagfrom 'next/cache' within server action handlers when mutations modify data displayed elsewhere
Files:
apps/web/utils/actions/rule.validation.ts
apps/web/utils/actions/*.validation.ts
📄 CodeRabbit inference engine (.cursor/rules/fullstack-workflow.mdc)
apps/web/utils/actions/*.validation.ts: Define Zod validation schemas in separate*.validation.tsfiles and export both the schema and inferred type (e.g.,CreateExampleBody)
Export types from Zod schemas usingz.infer<>to maintain type safety between validation and client usage
apps/web/utils/actions/*.validation.ts: Create separate validation files for server actions using the naming conventionapps/web/utils/actions/NAME.validation.tscontaining Zod schemas and inferred types
Define input validation schemas using Zod in.validation.tsfiles and export both the schema and its inferred TypeScript type
Files:
apps/web/utils/actions/rule.validation.ts
apps/web/utils/actions/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
apps/web/utils/actions/**/*.ts: Server actions must be located inapps/web/utils/actionsfolder
Server action files must start withuse serverdirective
Files:
apps/web/utils/actions/rule.validation.ts
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/security.mdc)
**/*.ts: ALL database queries MUST be scoped to the authenticated user/account by including user/account filtering in WHERE clauses to prevent unauthorized data access
Always validate that resources belong to the authenticated user before performing operations, using ownership checks in WHERE clauses or relationships
Always validate all input parameters for type, format, and length before using them in database queries
Use SafeError for error responses to prevent information disclosure. Generic error messages should not reveal internal IDs, logic, or resource ownership details
Only return necessary fields in API responses using Prisma'sselectoption. Never expose sensitive data such as password hashes, private keys, or system flags
Prevent Insecure Direct Object References (IDOR) by validating resource ownership before operations. AllfindUnique/findFirstcalls MUST include ownership filters
Prevent mass assignment vulnerabilities by explicitly whitelisting allowed fields in update operations instead of accepting all user-provided data
Prevent privilege escalation by never allowing users to modify system fields, ownership fields, or admin-only attributes through user input
AllfindManyqueries MUST be scoped to the user's data by including appropriate WHERE filters to prevent returning data from other users
Use Prisma relationships for access control by leveraging nested where clauses (e.g.,emailAccount: { id: emailAccountId }) to validate ownership
Files:
apps/web/utils/actions/rule.validation.tsapps/web/utils/cold-email/send-notification.tsapps/web/utils/action-item.tsapps/web/app/(app)/[emailAccountId]/assistant/constants.tsapps/web/utils/ai/actions.ts
apps/web/**/utils/actions/*.ts
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
apps/web/**/utils/actions/*.ts: Usenext-safe-actionwith proper Zod validation for server actions
CallrevalidatePathin server actions for cache invalidation after mutations
Files:
apps/web/utils/actions/rule.validation.ts
apps/web/**/utils/actions/*.validation.ts
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Create separate Zod validation schema files for server action inputs
Files:
apps/web/utils/actions/rule.validation.ts
apps/web/**/{app/api,utils/actions}/**/*.ts
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
apps/web/**/{app/api,utils/actions}/**/*.ts: Use server actions for all mutations (create/update/delete operations) instead of POST API routes
UsewithAuthfor user-level operations andwithEmailAccountfor email-account-level operations
Files:
apps/web/utils/actions/rule.validation.ts
**/{utils,helpers,lib}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/logging.mdc)
Logger should be passed as a parameter to helper functions instead of creating their own logger instances
Files:
apps/web/utils/actions/rule.validation.tsapps/web/utils/cold-email/send-notification.tsapps/web/utils/action-item.tsapps/web/utils/action-display.tsxapps/web/utils/ai/actions.ts
**/*Form.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/form-handling.mdc)
**/*Form.{ts,tsx}: Use React Hook Form with Zod for validation in form components
Validate form inputs before submission
Show validation errors inline next to form fields
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
apps/web/**/*{Form,Form.tsx}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Use React Hook Form with Zod validation for form handling
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
**/{pages,routes,components}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/gmail-api.mdc)
Never call Gmail API directly from routes or components - always use wrapper functions from the utils folder
Files:
apps/web/app/(landing)/components/page.tsxapps/web/components/PlanBadge.tsx
apps/web/components/**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/fullstack-workflow.mdc)
Use
LoadingContentcomponent to consistently handle loading and error states, passingloading,error, andchildrenpropsUse PascalCase for component file names (e.g.,
components/Button.tsx)
Files:
apps/web/components/PlanBadge.tsx
apps/web/{utils/ai,utils/llms,__tests__}/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/llm.mdc)
LLM-related code must be organized in specific directories:
apps/web/utils/ai/for main implementations,apps/web/utils/llms/for core utilities and configurations, andapps/web/__tests__/for LLM-specific tests
Files:
apps/web/utils/ai/actions.ts
apps/web/utils/ai/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/llm.mdc)
apps/web/utils/ai/**/*.ts: LLM feature functions must import fromzodfor schema validation, usecreateScopedLoggerfrom@/utils/logger,chatCompletionObjectandcreateGenerateObjectfrom@/utils/llms, and importEmailAccountWithAItype from@/utils/llms/types
LLM feature functions must follow a standard structure: accept options withinputDataandemailAccountparameters, implement input validation with early returns, define separate system and user prompts, create a Zod schema for response validation, and usecreateGenerateObjectto execute the LLM call
System prompts must define the LLM's role and task specifications
User prompts must contain the actual data and context, and should be kept separate from system prompts
Always define a Zod schema for LLM response validation and make schemas as specific as possible to guide the LLM output
Use descriptive scoped loggers for each LLM feature, log inputs and outputs with appropriate log levels, and include relevant context in log messages
Implement early returns for invalid LLM inputs, use proper error types and logging, implement fallbacks for AI failures, and add retry logic for transient failures usingwithRetry
Use XML-like tags to structure data in prompts, remove excessive whitespace and truncate long inputs, and format data consistently across similar LLM functions
Use TypeScript types for all LLM function parameters and return values, and define clear interfaces for complex input/output structures
Keep related AI functions in the same file or directory, extract common patterns into utility functions, and document complex AI logic with clear comments
Files:
apps/web/utils/ai/actions.ts
🧠 Learnings (25)
📚 Learning: 2025-11-25T14:38:42.022Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/prisma.mdc:0-0
Timestamp: 2025-11-25T14:38:42.022Z
Learning: Applies to **/prisma/schema.prisma : Use PostgreSQL as the database system with Prisma
Applied to files:
apps/web/prisma/migrations/20251219012216_add_notify_sender_action_type/migration.sql
📚 Learning: 2025-11-25T14:39:49.448Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/server-actions.mdc:0-0
Timestamp: 2025-11-25T14:39:49.448Z
Learning: Applies to apps/web/utils/actions/*.validation.ts : Create separate validation files for server actions using the naming convention `apps/web/utils/actions/NAME.validation.ts` containing Zod schemas and inferred types
Applied to files:
apps/web/utils/actions/rule.validation.ts
📚 Learning: 2025-12-17T11:18:06.818Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-12-17T11:18:06.818Z
Learning: Applies to apps/web/**/utils/actions/*.validation.ts : Create separate Zod validation schema files for server action inputs
Applied to files:
apps/web/utils/actions/rule.validation.ts
📚 Learning: 2025-11-25T14:37:09.306Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/fullstack-workflow.mdc:0-0
Timestamp: 2025-11-25T14:37:09.306Z
Learning: Applies to apps/web/utils/actions/*.ts : Use `next-safe-action` with Zod schemas for all server actions (create/update/delete mutations), storing validation schemas in `apps/web/utils/actions/*.validation.ts`
Applied to files:
apps/web/utils/actions/rule.validation.ts
📚 Learning: 2025-12-17T11:18:06.818Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-12-17T11:18:06.818Z
Learning: Applies to apps/web/**/utils/actions/*.ts : Use `next-safe-action` with proper Zod validation for server actions
Applied to files:
apps/web/utils/actions/rule.validation.ts
📚 Learning: 2025-11-25T14:39:49.448Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/server-actions.mdc:0-0
Timestamp: 2025-11-25T14:39:49.448Z
Learning: Applies to apps/web/utils/actions/*.ts : Use `.schema()` method with Zod validation schemas from corresponding `.validation.ts` files in next-safe-action configuration
Applied to files:
apps/web/utils/actions/rule.validation.ts
📚 Learning: 2025-11-25T14:37:09.306Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/fullstack-workflow.mdc:0-0
Timestamp: 2025-11-25T14:37:09.306Z
Learning: Applies to apps/web/utils/actions/*.validation.ts : Export types from Zod schemas using `z.infer<>` to maintain type safety between validation and client usage
Applied to files:
apps/web/utils/actions/rule.validation.ts
📚 Learning: 2025-11-25T14:39:49.448Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/server-actions.mdc:0-0
Timestamp: 2025-11-25T14:39:49.448Z
Learning: Applies to apps/web/utils/actions/*.validation.ts : Define input validation schemas using Zod in `.validation.ts` files and export both the schema and its inferred TypeScript type
Applied to files:
apps/web/utils/actions/rule.validation.ts
📚 Learning: 2025-11-25T14:36:51.389Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-11-25T14:36:51.389Z
Learning: Applies to **/*.validation.ts : Use descriptive error messages in Zod validation schemas
Applied to files:
apps/web/utils/actions/rule.validation.ts
📚 Learning: 2025-11-25T14:37:09.306Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/fullstack-workflow.mdc:0-0
Timestamp: 2025-11-25T14:37:09.306Z
Learning: Applies to apps/web/utils/actions/*.validation.ts : Define Zod validation schemas in separate `*.validation.ts` files and export both the schema and inferred type (e.g., `CreateExampleBody`)
Applied to files:
apps/web/utils/actions/rule.validation.ts
📚 Learning: 2025-11-25T14:36:51.389Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-11-25T14:36:51.389Z
Learning: Applies to **/*.validation.ts : Define validation schemas using Zod
Applied to files:
apps/web/utils/actions/rule.validation.ts
📚 Learning: 2025-11-25T14:39:49.448Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/server-actions.mdc:0-0
Timestamp: 2025-11-25T14:39:49.448Z
Learning: Applies to apps/web/utils/actions/*.ts : Add metadata with a meaningful action name using `.metadata({ name: "actionName" })` for Sentry instrumentation and monitoring
Applied to files:
apps/web/utils/action-item.tsapps/web/utils/action-display.tsxapps/web/app/(landing)/components/page.tsx
📚 Learning: 2025-11-25T14:36:36.276Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/data-fetching.mdc:0-0
Timestamp: 2025-11-25T14:36:36.276Z
Learning: Applies to **/*.{ts,tsx} : Import error and success toast utilities from '@/components/Toast' for displaying notifications
Applied to files:
apps/web/utils/action-display.tsx
📚 Learning: 2025-11-25T14:39:49.448Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/server-actions.mdc:0-0
Timestamp: 2025-11-25T14:39:49.448Z
Learning: Applies to apps/web/utils/actions/*.ts : Use `actionClient` when both authenticated user context and a specific emailAccountId are needed, with emailAccountId bound when calling from the client
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/constants.tsapps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/utils/ai/actions.ts
📚 Learning: 2025-07-17T04:19:57.099Z
Learnt from: edulelis
Repo: elie222/inbox-zero PR: 576
File: packages/resend/emails/digest.tsx:78-83
Timestamp: 2025-07-17T04:19:57.099Z
Learning: In packages/resend/emails/digest.tsx, the DigestEmailProps type uses `[key: string]: DigestItem[] | undefined | string | Date | undefined` instead of intersection types like `& Record<string, DigestItem[] | undefined>` due to implementation constraints. This was the initial implementation approach and cannot be changed to more restrictive typing.
Applied to files:
packages/resend/emails/cold-email-notification.tsx
📚 Learning: 2025-11-25T14:40:13.649Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-11-25T14:40:13.649Z
Learning: Applies to **/*.{tsx,ts,jsx,js} : For text inputs in forms, use the `Input` component with `type='email'`, `name`, `label`, `registerProps` from react-hook-form, and `error` props
Applied to files:
packages/resend/emails/cold-email-notification.tsx
📚 Learning: 2025-11-25T14:37:22.660Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/gmail-api.mdc:0-0
Timestamp: 2025-11-25T14:37:22.660Z
Learning: Applies to **/*.{ts,tsx} : Use wrapper functions for Gmail label operations from @/utils/gmail/label.ts instead of direct API calls
Applied to files:
apps/web/app/(landing)/components/page.tsxapps/web/utils/ai/actions.ts
📚 Learning: 2025-11-25T14:37:22.660Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/gmail-api.mdc:0-0
Timestamp: 2025-11-25T14:37:22.660Z
Learning: Applies to apps/web/utils/gmail/**/*.{ts,tsx} : Keep Gmail provider-specific implementation details isolated within the apps/web/utils/gmail/ directory
Applied to files:
apps/web/app/(landing)/components/page.tsx
📚 Learning: 2025-11-25T14:42:16.602Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-11-25T14:42:16.602Z
Learning: The `utils` folder contains core app logic such as Next.js Server Actions and Gmail API requests
Applied to files:
apps/web/utils/ai/actions.ts
📚 Learning: 2025-11-25T14:42:11.919Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-11-25T14:42:11.919Z
Learning: Applies to utils/**/*.{js,ts,jsx,tsx} : The `utils` folder contains core app logic such as Next.js Server Actions and Gmail API requests
Applied to files:
apps/web/utils/ai/actions.ts
📚 Learning: 2025-11-25T14:37:09.306Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/fullstack-workflow.mdc:0-0
Timestamp: 2025-11-25T14:37:09.306Z
Learning: Applies to apps/web/utils/actions/*.ts : Server actions should use 'use server' directive and automatically receive authentication context (`emailAccountId`) from the `actionClient`
Applied to files:
apps/web/utils/ai/actions.ts
📚 Learning: 2025-11-25T14:38:07.606Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.606Z
Learning: Applies to apps/web/utils/ai/**/*.ts : LLM feature functions must import from `zod` for schema validation, use `createScopedLogger` from `@/utils/logger`, `chatCompletionObject` and `createGenerateObject` from `@/utils/llms`, and import `EmailAccountWithAI` type from `@/utils/llms/types`
Applied to files:
apps/web/utils/ai/actions.ts
📚 Learning: 2025-11-25T14:37:22.660Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/gmail-api.mdc:0-0
Timestamp: 2025-11-25T14:37:22.660Z
Learning: Applies to **/*.{ts,tsx} : Use wrapper functions for Gmail message operations (get, list, batch, etc.) from @/utils/gmail/message.ts instead of direct API calls
Applied to files:
apps/web/utils/ai/actions.ts
📚 Learning: 2025-11-25T14:38:07.606Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.606Z
Learning: Applies to apps/web/utils/ai/**/*.ts : LLM feature functions must follow a standard structure: accept options with `inputData` and `emailAccount` parameters, implement input validation with early returns, define separate system and user prompts, create a Zod schema for response validation, and use `createGenerateObject` to execute the LLM call
Applied to files:
apps/web/utils/ai/actions.ts
📚 Learning: 2025-11-25T14:37:22.660Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/gmail-api.mdc:0-0
Timestamp: 2025-11-25T14:37:22.660Z
Learning: Applies to **/*.{ts,tsx} : Use wrapper functions for Gmail thread operations from @/utils/gmail/thread.ts instead of direct API calls
Applied to files:
apps/web/utils/ai/actions.ts
🧬 Code graph analysis (4)
packages/resend/src/send.tsx (2)
apps/web/utils/cold-email/send-notification.ts (1)
sendColdEmailNotification(5-58)packages/resend/emails/cold-email-notification.tsx (1)
ColdEmailNotificationProps(15-17)
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx (1)
apps/web/utils/action-display.tsx (1)
getActionIcon(89-120)
packages/resend/emails/cold-email-notification.tsx (2)
apps/web/components/new-landing/common/Section.tsx (1)
Section(9-15)apps/web/components/new-landing/icons/Link.tsx (1)
Link(1-18)
apps/web/utils/ai/actions.ts (3)
apps/web/utils/email.ts (1)
extractEmailAddress(19-52)apps/web/utils/cold-email/send-notification.ts (1)
sendColdEmailNotification(5-58)packages/resend/src/send.tsx (1)
sendColdEmailNotification(211-252)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: cubic · AI code reviewer
- GitHub Check: Review for correctness
- GitHub Check: test
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (20)
version.txt (1)
1-1: LGTM!Appropriate minor version bump for the new NOTIFY_SENDER feature addition.
apps/web/utils/actions/rule.validation.ts (1)
29-29: LGTM!The addition of
NOTIFY_SENDERto the validation schema is correct. Unlike actions such asLABEL,FORWARD, orCALL_WEBHOOKthat require specific field validation (labelId, to, url),NOTIFY_SENDERdoesn't need additional validation rules, which aligns with its implementation.packages/resend/emails/cold-email-notification.tsx (1)
50-65: LGTM!The notification message is clear, professional, and appropriately explains to the sender why their email was filtered. The tone is polite while being direct about the filtering action.
apps/web/prisma/migrations/20251219012216_add_notify_sender_action_type/migration.sql (1)
1-2: LGTM!The migration correctly adds the
NOTIFY_SENDERvalue to the PostgreSQLActionTypeenum.apps/web/app/(landing)/components/page.tsx (1)
333-337: LGTM!The addition of
NOTIFY_SENDERto the demo ActionBadges is appropriate for showcasing the new action type in the component library demo page.apps/web/components/PlanBadge.tsx (2)
182-183: LGTM!The label "Notify Sender" is consistent with the action type's purpose and follows the naming convention used for other action types.
228-229: LGTM!The purple color assignment for
NOTIFY_SENDERis consistent with other notification-style actions likeCALL_WEBHOOKandDIGEST.apps/web/utils/action-display.tsx (3)
5-5: LGTM!Appropriate import of
BellIconfor the notification action.
80-81: LGTM!The display label "Notify Sender" is clear and consistent with the action's purpose.
113-114: LGTM!
BellIconis a semantically appropriate icon choice for the notification action.apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx (1)
342-351: LGTM with minor suggestion!The conditional inclusion of
NOTIFY_SENDERonly for cold email rules is appropriate and follows the same pattern as theMOVE_FOLDERoption for Microsoft providers.apps/web/app/(app)/[emailAccountId]/assistant/constants.ts (1)
13-13: LGTM! Consistent action type configuration.The NOTIFY_SENDER action type is properly configured across all three mappings (colors, text colors, and icons). The amber color scheme provides good visual distinction, and BellIcon is an appropriate choice for notification actions.
Also applies to: 29-29, 44-44, 59-59
apps/web/app/(app)/[emailAccountId]/assistant/ActionSteps.tsx (1)
536-544: LGTM! Clean conditional rendering for NOTIFY_SENDER.The implementation follows the existing pattern used for other action types. The descriptive message clearly explains that the notification is automated and comes from Inbox Zero, not the user's email—which is important for user understanding.
apps/web/app/(app)/[emailAccountId]/assistant/ActionSummaryCard.tsx (1)
206-210: LGTM! Clear summary with helpful tooltip.The NOTIFY_SENDER case is properly handled with a concise summary and an informative tooltip that clarifies the notification source and purpose.
apps/web/prisma/schema.prisma (1)
1054-1054: LGTM! Proper enum addition with clear documentation.The NOTIFY_SENDER value is correctly added to the ActionType enum with a helpful comment explaining its purpose and scope (cold email rules only).
apps/web/utils/ai/actions.ts (1)
13-14: LGTM! Proper integration of NOTIFY_SENDER action.The imports and switch case are correctly added, following the established pattern for other action types.
Also applies to: 78-79
apps/web/utils/action-item.ts (1)
152-154: LGTM! Correct handling for fieldless action.NOTIFY_SENDER is properly configured with empty fields (similar to ARCHIVE, MARK_SPAM, etc.) and the sanitization logic correctly returns the base object since no additional fields are needed.
Also applies to: 281-283
apps/web/utils/cold-email/send-notification.ts (1)
5-57: LGTM! Robust implementation with excellent error handling.The function demonstrates good practices:
- Structured error handling at multiple levels (configuration check, API errors, exceptions)
- Comprehensive logging for observability (warn/error/info)
- Clear return type for caller feedback
- Appropriate subject formatting with "Re: " prefix
packages/resend/src/send.tsx (2)
17-22: LGTM! Good refactoring with constant extraction.Introducing
RESEND_NOT_CONFIGURED_MESSAGEimproves consistency and maintainability. The constant is properly reused in the existingsendEmailfunction.Also applies to: 43-43
206-252: LGTM! Well-documented function with appropriate design differences.The implementation correctly handles the unique requirements for cold email notifications:
- Excellent JSDoc comment explaining why this differs from other email functions
- No unsubscribe token (since recipient is external sender, not our user)
- Includes
replyToparameter for proper email threading- Proper error handling and logging
- Returns result for caller observability
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/web/components/email-list/EmailMessage.tsx(2 hunks)apps/web/utils/ai/actions.ts(3 hunks)apps/web/utils/cold-email/send-notification.ts(1 hunks)packages/resend/src/send.tsx(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/web/utils/ai/actions.ts
- packages/resend/src/send.tsx
🧰 Additional context used
📓 Path-based instructions (18)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/data-fetching.mdc)
**/*.{ts,tsx}: For API GET requests to server, use theswrpackage
Useresult?.serverErrorwithtoastErrorfrom@/components/Toastfor error handling in async operations
**/*.{ts,tsx}: Use wrapper functions for Gmail message operations (get, list, batch, etc.) from @/utils/gmail/message.ts instead of direct API calls
Use wrapper functions for Gmail thread operations from @/utils/gmail/thread.ts instead of direct API calls
Use wrapper functions for Gmail label operations from @/utils/gmail/label.ts instead of direct API calls
**/*.{ts,tsx}: For early access feature flags, create hooks using the naming conventionuse[FeatureName]Enabledthat return a boolean fromuseFeatureFlagEnabled("flag-key")
For A/B test variant flags, create hooks using the naming conventionuse[FeatureName]Variantthat define variant types, useuseFeatureFlagVariantKey()with type casting, and provide a default "control" fallback
Use kebab-case for PostHog feature flag keys (e.g.,inbox-cleaner,pricing-options-2)
Always define types for A/B test variant flags (e.g.,type PricingVariant = "control" | "variant-a" | "variant-b") and provide type safety through type casting
**/*.{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 this and super in static contexts
Don't use any or unknown as type constraints
Don't use the TypeScript directive @ts-ignore
Don't use TypeScript enums
Don't export imported variables
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
Useas constinstead of literal types and type annotations
Use eitherT[]orArray<T>consistently
Initialize each enum member value explicitly
Useexport typefor types
Use `impo...
Files:
apps/web/components/email-list/EmailMessage.tsxapps/web/utils/cold-email/send-notification.ts
apps/web/components/**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/fullstack-workflow.mdc)
Use
LoadingContentcomponent to consistently handle loading and error states, passingloading,error, andchildrenpropsUse PascalCase for component file names (e.g.,
components/Button.tsx)
Files:
apps/web/components/email-list/EmailMessage.tsx
**/{pages,routes,components}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/gmail-api.mdc)
Never call Gmail API directly from routes or components - always use wrapper functions from the utils folder
Files:
apps/web/components/email-list/EmailMessage.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/prisma-enum-imports.mdc)
Always import Prisma enums from
@/generated/prisma/enumsinstead of@/generated/prisma/clientto avoid Next.js bundling errors in client componentsImport Prisma using the project's centralized utility:
import prisma from '@/utils/prisma'
Files:
apps/web/components/email-list/EmailMessage.tsxapps/web/utils/cold-email/send-notification.ts
apps/web/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Import specific lodash functions rather than entire lodash library to minimize bundle size (e.g.,
import groupBy from 'lodash/groupBy')
apps/web/**/*.{ts,tsx}: Use TypeScript with strict null checks
Use@/path aliases for imports from project root
Follow tailwindcss patterns with prettier-plugin-tailwindcss class organization
Prefix client-side environment variables withNEXT_PUBLIC_
Leverage TypeScript inference for better developer experience with type exports from API routes
Files:
apps/web/components/email-list/EmailMessage.tsxapps/web/utils/cold-email/send-notification.ts
**/*.{tsx,ts}
📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)
**/*.{tsx,ts}: Use Shadcn UI and Tailwind for components and styling
Usenext/imagepackage for images
For API GET requests to server, use theswrpackage with hooks likeuseSWRto fetch data
For text inputs, use theInputcomponent withregisterPropsfor form integration and error handling
Files:
apps/web/components/email-list/EmailMessage.tsxapps/web/utils/cold-email/send-notification.ts
**/*.{tsx,ts,css}
📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)
Implement responsive design with Tailwind CSS using a mobile-first approach
Files:
apps/web/components/email-list/EmailMessage.tsxapps/web/utils/cold-email/send-notification.ts
**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)
**/*.tsx: Use theLoadingContentcomponent to handle loading states instead of manual loading state management
For text areas, use theInputcomponent withtype='text',autosizeTextareaprop set to true, andregisterPropsfor form integration
Files:
apps/web/components/email-list/EmailMessage.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)
**/*.{js,jsx,ts,tsx}: Don't useaccessKeyattribute on any HTML element
Don't setaria-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<marquee>or<blink>
Only use thescopeprop on<th>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 assigntabIndexto non-interactive HTML elements
Don't use positive integers fortabIndexproperty
Don't include "image", "picture", or "photo" in img alt prop
Don't use explicit role property that's the same as the implicit/default role
Make static elements with click handlers use a valid role attribute
Always include atitleelement for SVG elements
Give all elements requiring alt text meaningful information for screen readers
Make sure anchors have content that's accessible to screen readers
AssigntabIndexto non-interactive HTML elements witharia-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 atypeattribute for button elements
Make elements with interactive roles and handlers focusable
Give heading elements content that's accessible to screen readers (not hidden witharia-hidden)
Always include alangattribute on the html element
Always include atitleattribute for iframe elements
AccompanyonClickwith at least one of:onKeyUp,onKeyDown, oronKeyPress
AccompanyonMouseOver/onMouseOutwithonFocus/onBlur
Include caption tracks for audio and video elements
Use semantic elements instead of role attributes in JSX
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 AR...
Files:
apps/web/components/email-list/EmailMessage.tsxapps/web/utils/cold-email/send-notification.ts
**/*.{jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)
**/*.{jsx,tsx}: 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 use event handlers on non-interactive elements
Don't assign to React component props
Don't use bothchildrenanddangerouslySetInnerHTMLprops on the same element
Don't use dangerous JSX props
Don't use Array index in keys
Don't insert comments as text nodes
Don't assign JSX properties multiple times
Don't add extra closing tags for components without children
Use<>...</>instead of<Fragment>...</Fragment>
Watch out for possible "wrong" semicolons inside JSX elements
Make sure void (self-closing) elements don't have children
Don't usetarget="_blank"withoutrel="noopener"
Don't use<img>elements in Next.js projects
Don't use<head>elements in Next.js projects
Files:
apps/web/components/email-list/EmailMessage.tsx
!(pages/_document).{jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)
Don't use the next/head module in pages/_document.js on Next.js projects
Files:
apps/web/components/email-list/EmailMessage.tsxapps/web/utils/cold-email/send-notification.ts
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/utilities.mdc)
**/*.{js,ts,jsx,tsx}: Use lodash utilities for common operations (arrays, objects, strings)
Import specific lodash functions to minimize bundle size (e.g.,import groupBy from 'lodash/groupBy')
Files:
apps/web/components/email-list/EmailMessage.tsxapps/web/utils/cold-email/send-notification.ts
apps/web/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
apps/web/**/*.{tsx,jsx}: Prefer functional components with hooks over class components
Use shadcn/ui components when available
Follow consistent naming conventions with PascalCase for component names
Use LoadingContent component for async data with loading and error states
Useresult?.serverErrorwithtoastErrorandtoastSuccessfor mutation error handling
Files:
apps/web/components/email-list/EmailMessage.tsx
apps/web/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
apps/web/**/*.{ts,tsx,js,jsx}: Use proper error handling with try/catch blocks
Prefer self-documenting code over comments; use descriptive variable and function names instead of explaining intent with comments
Add helper functions to the bottom of files, not the top
Files:
apps/web/components/email-list/EmailMessage.tsxapps/web/utils/cold-email/send-notification.ts
apps/web/**/*.{ts,tsx,js,jsx,json,css,md}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Format code with Prettier
Files:
apps/web/components/email-list/EmailMessage.tsxapps/web/utils/cold-email/send-notification.ts
apps/web/**/*.{tsx,jsx,css}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Ensure responsive design with mobile-first approach
Files:
apps/web/components/email-list/EmailMessage.tsx
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/security.mdc)
**/*.ts: ALL database queries MUST be scoped to the authenticated user/account by including user/account filtering in WHERE clauses to prevent unauthorized data access
Always validate that resources belong to the authenticated user before performing operations, using ownership checks in WHERE clauses or relationships
Always validate all input parameters for type, format, and length before using them in database queries
Use SafeError for error responses to prevent information disclosure. Generic error messages should not reveal internal IDs, logic, or resource ownership details
Only return necessary fields in API responses using Prisma'sselectoption. Never expose sensitive data such as password hashes, private keys, or system flags
Prevent Insecure Direct Object References (IDOR) by validating resource ownership before operations. AllfindUnique/findFirstcalls MUST include ownership filters
Prevent mass assignment vulnerabilities by explicitly whitelisting allowed fields in update operations instead of accepting all user-provided data
Prevent privilege escalation by never allowing users to modify system fields, ownership fields, or admin-only attributes through user input
AllfindManyqueries MUST be scoped to the user's data by including appropriate WHERE filters to prevent returning data from other users
Use Prisma relationships for access control by leveraging nested where clauses (e.g.,emailAccount: { id: emailAccountId }) to validate ownership
Files:
apps/web/utils/cold-email/send-notification.ts
**/{utils,helpers,lib}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/logging.mdc)
Logger should be passed as a parameter to helper functions instead of creating their own logger instances
Files:
apps/web/utils/cold-email/send-notification.ts
🧠 Learnings (5)
📚 Learning: 2025-11-25T14:37:22.660Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/gmail-api.mdc:0-0
Timestamp: 2025-11-25T14:37:22.660Z
Learning: Applies to **/*.{ts,tsx} : Use wrapper functions for Gmail message operations (get, list, batch, etc.) from @/utils/gmail/message.ts instead of direct API calls
Applied to files:
apps/web/components/email-list/EmailMessage.tsxapps/web/utils/cold-email/send-notification.ts
📚 Learning: 2025-11-25T14:37:22.660Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/gmail-api.mdc:0-0
Timestamp: 2025-11-25T14:37:22.660Z
Learning: Applies to **/*.{ts,tsx} : Use wrapper functions for Gmail thread operations from @/utils/gmail/thread.ts instead of direct API calls
Applied to files:
apps/web/components/email-list/EmailMessage.tsx
📚 Learning: 2025-11-25T14:37:22.660Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/gmail-api.mdc:0-0
Timestamp: 2025-11-25T14:37:22.660Z
Learning: Applies to **/*.{ts,tsx} : Use wrapper functions for Gmail label operations from @/utils/gmail/label.ts instead of direct API calls
Applied to files:
apps/web/components/email-list/EmailMessage.tsx
📚 Learning: 2025-11-25T14:37:22.660Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/gmail-api.mdc:0-0
Timestamp: 2025-11-25T14:37:22.660Z
Learning: Applies to apps/web/utils/gmail/**/*.{ts,tsx} : Keep Gmail provider-specific implementation details isolated within the apps/web/utils/gmail/ directory
Applied to files:
apps/web/utils/cold-email/send-notification.ts
📚 Learning: 2025-11-25T14:38:07.606Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.606Z
Learning: Applies to apps/web/utils/ai/**/*.ts : LLM feature functions must import from `zod` for schema validation, use `createScopedLogger` from `@/utils/logger`, `chatCompletionObject` and `createGenerateObject` from `@/utils/llms`, and import `EmailAccountWithAI` type from `@/utils/llms/types`
Applied to files:
apps/web/utils/cold-email/send-notification.ts
🧬 Code graph analysis (2)
apps/web/components/email-list/EmailMessage.tsx (1)
apps/web/utils/email/subject.ts (1)
formatReplySubject(6-13)
apps/web/utils/cold-email/send-notification.ts (4)
packages/resend/src/send.tsx (1)
sendColdEmailNotification(211-258)apps/web/utils/logger.ts (1)
Logger(5-5)apps/web/env.ts (1)
env(17-255)apps/web/utils/email/subject.ts (1)
formatReplySubject(6-13)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: cubic · AI code reviewer
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: test
- GitHub Check: Review for correctness
🔇 Additional comments (4)
apps/web/components/email-list/EmailMessage.tsx (2)
28-28: LGTM! Clean import addition.The import follows project conventions with the
@/path alias and brings in the utility needed for improved subject formatting.
332-332: Excellent improvement to reply subject formatting.Replacing manual "Re: " concatenation with
formatReplySubject()provides several benefits:
- Prevents duplicate "Re: Re: ..." chains when replying to messages that already have the prefix
- Handles edge cases like null/undefined subjects and whitespace
- Case-insensitive "Re:" detection (handles "re:", "Re:", "RE:")
- Centralizes subject formatting logic for consistency across the codebase
This aligns well with the broader PR objective of standardizing subject formatting for the NOTIFY_SENDER action and related workflows.
apps/web/utils/cold-email/send-notification.ts (2)
6-62: Well-structured implementation with proper error handling.The function follows best practices:
- Logger is correctly passed as a parameter (per guidelines)
- Comprehensive try-catch error handling
- Defensive programming with early returns
- Structured logging with appropriate context
- Type-safe return type
34-34:NEXT_PUBLIC_BASE_URLis properly defined and correctly used.The environment variable is defined in
apps/web/env.tswith Zod validation (z.string()) in the client section and included inexperimental__runtimeEnv. The usage on line 34 ofsend-notification.tsis appropriate—NEXT_PUBLIC_ variables are available to server components, server actions and route handlers, in addition to client-side code.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx (1)
342-356: Consider addingenvto the useMemo dependency array.The memoized
typeOptionsusesenv.NEXT_PUBLIC_IS_RESEND_CONFIGUREDbutenvisn't included in the dependency array. Whileenvis effectively a constant from@t3-oss/env-nextjsand won't change at runtime, including it would satisfy React's exhaustive-deps rule and make the dependencies explicit.🔎 Proposed fix
- }, [provider, terminology.label.action, rule.systemType]); + }, [provider, terminology.label.action, rule.systemType, env.NEXT_PUBLIC_IS_RESEND_CONFIGURED]);
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx(2 hunks)apps/web/env.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (22)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/data-fetching.mdc)
**/*.{ts,tsx}: For API GET requests to server, use theswrpackage
Useresult?.serverErrorwithtoastErrorfrom@/components/Toastfor error handling in async operations
**/*.{ts,tsx}: Use wrapper functions for Gmail message operations (get, list, batch, etc.) from @/utils/gmail/message.ts instead of direct API calls
Use wrapper functions for Gmail thread operations from @/utils/gmail/thread.ts instead of direct API calls
Use wrapper functions for Gmail label operations from @/utils/gmail/label.ts instead of direct API calls
**/*.{ts,tsx}: For early access feature flags, create hooks using the naming conventionuse[FeatureName]Enabledthat return a boolean fromuseFeatureFlagEnabled("flag-key")
For A/B test variant flags, create hooks using the naming conventionuse[FeatureName]Variantthat define variant types, useuseFeatureFlagVariantKey()with type casting, and provide a default "control" fallback
Use kebab-case for PostHog feature flag keys (e.g.,inbox-cleaner,pricing-options-2)
Always define types for A/B test variant flags (e.g.,type PricingVariant = "control" | "variant-a" | "variant-b") and provide type safety through type casting
**/*.{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 this and super in static contexts
Don't use any or unknown as type constraints
Don't use the TypeScript directive @ts-ignore
Don't use TypeScript enums
Don't export imported variables
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
Useas constinstead of literal types and type annotations
Use eitherT[]orArray<T>consistently
Initialize each enum member value explicitly
Useexport typefor types
Use `impo...
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/env.ts
**/*Form.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/form-handling.mdc)
**/*Form.{ts,tsx}: Use React Hook Form with Zod for validation in form components
Validate form inputs before submission
Show validation errors inline next to form fields
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
apps/web/app/(app)/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/page-structure.mdc)
apps/web/app/(app)/**/*.{ts,tsx}: Components for the page are either put inpage.tsx, or in theapps/web/app/(app)/PAGE_NAMEfolder
If we're in a deeply nested component we will useswrto fetch via API
If you need to useonClickin a component, that component is a client component and file must start withuse client
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/prisma-enum-imports.mdc)
Always import Prisma enums from
@/generated/prisma/enumsinstead of@/generated/prisma/clientto avoid Next.js bundling errors in client componentsImport Prisma using the project's centralized utility:
import prisma from '@/utils/prisma'
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/env.ts
apps/web/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Import specific lodash functions rather than entire lodash library to minimize bundle size (e.g.,
import groupBy from 'lodash/groupBy')
apps/web/**/*.{ts,tsx}: Use TypeScript with strict null checks
Use@/path aliases for imports from project root
Follow tailwindcss patterns with prettier-plugin-tailwindcss class organization
Prefix client-side environment variables withNEXT_PUBLIC_
Leverage TypeScript inference for better developer experience with type exports from API routes
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/env.ts
**/*.{tsx,ts}
📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)
**/*.{tsx,ts}: Use Shadcn UI and Tailwind for components and styling
Usenext/imagepackage for images
For API GET requests to server, use theswrpackage with hooks likeuseSWRto fetch data
For text inputs, use theInputcomponent withregisterPropsfor form integration and error handling
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/env.ts
**/*.{tsx,ts,css}
📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)
Implement responsive design with Tailwind CSS using a mobile-first approach
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/env.ts
**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)
**/*.tsx: Use theLoadingContentcomponent to handle loading states instead of manual loading state management
For text areas, use theInputcomponent withtype='text',autosizeTextareaprop set to true, andregisterPropsfor form integration
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)
**/*.{js,jsx,ts,tsx}: Don't useaccessKeyattribute on any HTML element
Don't setaria-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<marquee>or<blink>
Only use thescopeprop on<th>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 assigntabIndexto non-interactive HTML elements
Don't use positive integers fortabIndexproperty
Don't include "image", "picture", or "photo" in img alt prop
Don't use explicit role property that's the same as the implicit/default role
Make static elements with click handlers use a valid role attribute
Always include atitleelement for SVG elements
Give all elements requiring alt text meaningful information for screen readers
Make sure anchors have content that's accessible to screen readers
AssigntabIndexto non-interactive HTML elements witharia-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 atypeattribute for button elements
Make elements with interactive roles and handlers focusable
Give heading elements content that's accessible to screen readers (not hidden witharia-hidden)
Always include alangattribute on the html element
Always include atitleattribute for iframe elements
AccompanyonClickwith at least one of:onKeyUp,onKeyDown, oronKeyPress
AccompanyonMouseOver/onMouseOutwithonFocus/onBlur
Include caption tracks for audio and video elements
Use semantic elements instead of role attributes in JSX
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 AR...
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/env.ts
**/*.{jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)
**/*.{jsx,tsx}: 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 use event handlers on non-interactive elements
Don't assign to React component props
Don't use bothchildrenanddangerouslySetInnerHTMLprops on the same element
Don't use dangerous JSX props
Don't use Array index in keys
Don't insert comments as text nodes
Don't assign JSX properties multiple times
Don't add extra closing tags for components without children
Use<>...</>instead of<Fragment>...</Fragment>
Watch out for possible "wrong" semicolons inside JSX elements
Make sure void (self-closing) elements don't have children
Don't usetarget="_blank"withoutrel="noopener"
Don't use<img>elements in Next.js projects
Don't use<head>elements in Next.js projects
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
!(pages/_document).{jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)
Don't use the next/head module in pages/_document.js on Next.js projects
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/env.ts
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/utilities.mdc)
**/*.{js,ts,jsx,tsx}: Use lodash utilities for common operations (arrays, objects, strings)
Import specific lodash functions to minimize bundle size (e.g.,import groupBy from 'lodash/groupBy')
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/env.ts
apps/web/**/app/**
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Follow NextJS app router structure with (app) directory
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
apps/web/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
apps/web/**/*.{tsx,jsx}: Prefer functional components with hooks over class components
Use shadcn/ui components when available
Follow consistent naming conventions with PascalCase for component names
Use LoadingContent component for async data with loading and error states
Useresult?.serverErrorwithtoastErrorandtoastSuccessfor mutation error handling
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
apps/web/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
apps/web/**/*.{ts,tsx,js,jsx}: Use proper error handling with try/catch blocks
Prefer self-documenting code over comments; use descriptive variable and function names instead of explaining intent with comments
Add helper functions to the bottom of files, not the top
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/env.ts
apps/web/**/*.{ts,tsx,js,jsx,json,css,md}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Format code with Prettier
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/env.ts
apps/web/**/*.{tsx,jsx,css}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Ensure responsive design with mobile-first approach
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
apps/web/**/*{Form,Form.tsx}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Use React Hook Form with Zod validation for form handling
Files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
apps/web/env.ts
📄 CodeRabbit inference engine (.cursor/rules/environment-variables.mdc)
apps/web/env.ts: Add server-only environment variables toapps/web/env.tsunder theserverobject with Zod schema validation
Add client-side environment variables toapps/web/env.tsunder theclientobject withNEXT_PUBLIC_prefix and Zod schema validation
Add client-side environment variables toapps/web/env.tsunder theexperimental__runtimeEnvobject to enable runtime access
Files:
apps/web/env.ts
{.env.example,apps/web/env.ts}
📄 CodeRabbit inference engine (.cursor/rules/environment-variables.mdc)
Client-side environment variables must be prefixed with
NEXT_PUBLIC_
Files:
apps/web/env.ts
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/security.mdc)
**/*.ts: ALL database queries MUST be scoped to the authenticated user/account by including user/account filtering in WHERE clauses to prevent unauthorized data access
Always validate that resources belong to the authenticated user before performing operations, using ownership checks in WHERE clauses or relationships
Always validate all input parameters for type, format, and length before using them in database queries
Use SafeError for error responses to prevent information disclosure. Generic error messages should not reveal internal IDs, logic, or resource ownership details
Only return necessary fields in API responses using Prisma'sselectoption. Never expose sensitive data such as password hashes, private keys, or system flags
Prevent Insecure Direct Object References (IDOR) by validating resource ownership before operations. AllfindUnique/findFirstcalls MUST include ownership filters
Prevent mass assignment vulnerabilities by explicitly whitelisting allowed fields in update operations instead of accepting all user-provided data
Prevent privilege escalation by never allowing users to modify system fields, ownership fields, or admin-only attributes through user input
AllfindManyqueries MUST be scoped to the user's data by including appropriate WHERE filters to prevent returning data from other users
Use Prisma relationships for access control by leveraging nested where clauses (e.g.,emailAccount: { id: emailAccountId }) to validate ownership
Files:
apps/web/env.ts
apps/web/**/{.env.example,env.ts,turbo.json}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Add environment variables to
.env.example,env.ts, andturbo.json
Files:
apps/web/env.ts
🧠 Learnings (22)
📚 Learning: 2025-11-25T14:40:00.833Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-25T14:40:00.833Z
Learning: Applies to **/*.test.{ts,tsx} : Use test helpers `getEmail`, `getEmailAccount`, and `getRule` from `@/__tests__/helpers` for mocking emails, accounts, and rules
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-12-17T02:38:37.011Z
Learnt from: elie222
Repo: elie222/inbox-zero PR: 1103
File: apps/web/utils/actions/rule.ts:447-457
Timestamp: 2025-12-17T02:38:37.011Z
Learning: In apps/web/utils/actions/rule.ts, revalidatePath is not needed for toggleAllRulesAction because rules data is fetched client-side using SWR, not server-side. Server-side cache revalidation is only needed when using Next.js server components or server-side data fetching.
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-11-25T14:37:56.430Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.430Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Prefer using existing helpers from `@/__tests__/helpers.ts` (`getEmailAccount`, `getEmail`, `getRule`, `getMockMessage`, `getMockExecutedRule`) instead of creating custom test data helpers
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-11-25T14:38:07.606Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.606Z
Learning: Applies to apps/web/utils/ai/**/*.ts : LLM feature functions must import from `zod` for schema validation, use `createScopedLogger` from `@/utils/logger`, `chatCompletionObject` and `createGenerateObject` from `@/utils/llms`, and import `EmailAccountWithAI` type from `@/utils/llms/types`
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-11-25T14:36:45.807Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.807Z
Learning: Applies to apps/web/env.ts : Add client-side environment variables to `apps/web/env.ts` under the `client` object with `NEXT_PUBLIC_` prefix and Zod schema validation
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsxapps/web/env.ts
📚 Learning: 2025-11-25T14:37:09.306Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/fullstack-workflow.mdc:0-0
Timestamp: 2025-11-25T14:37:09.306Z
Learning: Applies to apps/web/components/**/*Form*.tsx : Use React Hook Form with Zod validation (`zodResolver`) for form handling, with form components using `register`, `handleSubmit`, and error handling from the hook
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-11-25T14:36:51.389Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-11-25T14:36:51.389Z
Learning: Applies to **/*Form.{ts,tsx} : Validate form inputs before submission using React Hook Form and Zod resolver
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-11-25T14:36:51.389Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-11-25T14:36:51.389Z
Learning: Applies to **/*Form.{ts,tsx} : Use React Hook Form with Zod for form validation
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-12-17T11:18:06.818Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-12-17T11:18:06.818Z
Learning: Applies to apps/web/**/*{Form,Form.tsx} : Use React Hook Form with Zod validation for form handling
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-11-25T14:36:53.147Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-11-25T14:36:53.147Z
Learning: Applies to **/*Form.{ts,tsx} : Use React Hook Form with Zod for validation in form components
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-11-25T14:40:13.649Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-11-25T14:40:13.649Z
Learning: Applies to **/*.{tsx,ts,jsx,js} : For text inputs in forms, use the `Input` component with `type='email'`, `name`, `label`, `registerProps` from react-hook-form, and `error` props
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-11-25T14:40:13.649Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-11-25T14:40:13.649Z
Learning: Applies to **/*.{tsx,ts,jsx,js} : For text areas in forms, use the `Input` component with `type='text'`, `autosizeTextarea` prop, `rows`, `name`, `placeholder`, `registerProps` from react-hook-form, and `error` props
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-11-09T19:50:05.292Z
Learnt from: ppranay20
Repo: elie222/inbox-zero PR: 935
File: apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx:367-369
Timestamp: 2025-11-09T19:50:05.292Z
Learning: In React Hook Form, when using `useMemo` or `useEffect` with form errors, always use `formState` as the dependency rather than `errors` or `formState.errors`. This is because React Hook Form uses a Proxy pattern where the errors object is mutable and won't trigger dependency arrays correctly. The formState dependency ensures proper reactivity when form validation state changes.
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-11-25T14:36:53.147Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-11-25T14:36:53.147Z
Learning: Applies to **/*Form.{ts,tsx} : Validate form inputs before submission
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2024-08-23T11:37:26.779Z
Learnt from: aryanprince
Repo: elie222/inbox-zero PR: 210
File: apps/web/app/(app)/stats/NewsletterModal.tsx:2-4
Timestamp: 2024-08-23T11:37:26.779Z
Learning: `MoreDropdown` is a React component and `useUnsubscribeButton` is a custom React hook, and they should not be imported using `import type`.
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-11-25T14:36:43.454Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:43.454Z
Learning: Applies to apps/web/env.ts : For client-side environment variables in `apps/web/env.ts`, prefix them with `NEXT_PUBLIC_` and add them to both the `client` and `experimental__runtimeEnv` sections
Applied to files:
apps/web/env.ts
📚 Learning: 2025-12-17T11:18:06.818Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-12-17T11:18:06.818Z
Learning: Applies to apps/web/**/*.{ts,tsx} : Prefix client-side environment variables with `NEXT_PUBLIC_`
Applied to files:
apps/web/env.ts
📚 Learning: 2025-11-25T14:36:45.807Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.807Z
Learning: Applies to {.env.example,apps/web/env.ts} : Client-side environment variables must be prefixed with `NEXT_PUBLIC_`
Applied to files:
apps/web/env.ts
📚 Learning: 2025-11-25T14:36:45.807Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.807Z
Learning: Applies to apps/web/env.ts : Add client-side environment variables to `apps/web/env.ts` under the `experimental__runtimeEnv` object to enable runtime access
Applied to files:
apps/web/env.ts
📚 Learning: 2025-11-25T14:36:43.454Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:43.454Z
Learning: Applies to apps/web/env.ts : Define environment variables in `apps/web/env.ts` using Zod schema validation, organizing them into `server` and `client` sections
Applied to files:
apps/web/env.ts
📚 Learning: 2025-11-25T14:36:45.807Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.807Z
Learning: Applies to apps/web/env.ts : Add server-only environment variables to `apps/web/env.ts` under the `server` object with Zod schema validation
Applied to files:
apps/web/env.ts
📚 Learning: 2025-12-17T11:18:06.818Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-12-17T11:18:06.818Z
Learning: Applies to apps/web/**/{.env.example,env.ts,turbo.json} : Add environment variables to `.env.example`, `env.ts`, and `turbo.json`
Applied to files:
apps/web/env.ts
🧬 Code graph analysis (1)
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx (2)
apps/web/env.ts (1)
env(17-258)apps/web/utils/action-display.tsx (1)
getActionIcon(89-120)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: cubic · AI code reviewer
- GitHub Check: test
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Review for correctness
🔇 Additional comments (1)
apps/web/env.ts (1)
193-194: LGTM! Correctly implements derived environment variable.The
NEXT_PUBLIC_IS_RESEND_CONFIGUREDflag is properly defined as a derived boolean based on the presence ofRESEND_API_KEY. The implementation correctly:
- Uses the
NEXT_PUBLIC_prefix for client-side access- Marks it as optional since RESEND may not be configured
- Derives the value at runtime using
!!process.env.RESEND_API_KEY- Includes a clear comment explaining the derivation
This approach ensures the UI can conditionally enable RESEND-dependent features without exposing the API key itself.
Also applies to: 256-256
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
apps/web/utils/cold-email/send-notification.ts (1)
25-25: Validate or provide fallback for empty subjects.As noted in the previous review, if
originalSubjectis empty or whitespace-only,formatReplySubjectwill produce"Re: ", which is malformed and may break email threading.
🧹 Nitpick comments (1)
apps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsx (1)
20-28: Consider aligning TabsContent order with visual tab order.The TabsContent blocks (lines 26-51) are ordered as test → cold-emails → rejected → settings, which doesn't match the visual tab order (cold-emails → rejected → test → settings). While this doesn't affect functionality since React matches by the
valueprop, aligning the code order with the visual order could improve maintainability.📝 Optional refactor to align content block order
- <TabsContent value="test" className="mb-10"> - <ColdEmailTest /> - </TabsContent> - <TabsContent value="cold-emails" className="mb-10"> <Card> <ColdEmailList /> </Card> </TabsContent> + <TabsContent value="rejected" className="mb-10"> <Card> <ColdEmailRejected /> </Card> </TabsContent> + + <TabsContent value="test" className="mb-10"> + <ColdEmailTest /> + </TabsContent> - <TabsContent value="rejected" className="mb-10"> - <Card> - <ColdEmailRejected /> - </Card> - </TabsContent> - <TabsContent value="settings" className="mb-10"> <MessageText className="my-4"> To manage cold email settings, go to the Assistant Rules tab and click
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsx(1 hunks)apps/web/app/(app)/[emailAccountId]/assistant/constants.ts(4 hunks)apps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsx(1 hunks)apps/web/utils/ai/actions.ts(3 hunks)apps/web/utils/cold-email/send-notification.ts(1 hunks)apps/web/utils/email/subject.ts(1 hunks)apps/web/utils/error.ts(3 hunks)packages/resend/src/send.tsx(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/web/utils/ai/actions.ts
- apps/web/app/(app)/[emailAccountId]/assistant/constants.ts
🧰 Additional context used
📓 Path-based instructions (18)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/data-fetching.mdc)
**/*.{ts,tsx}: For API GET requests to server, use theswrpackage
Useresult?.serverErrorwithtoastErrorfrom@/components/Toastfor error handling in async operations
**/*.{ts,tsx}: Use wrapper functions for Gmail message operations (get, list, batch, etc.) from @/utils/gmail/message.ts instead of direct API calls
Use wrapper functions for Gmail thread operations from @/utils/gmail/thread.ts instead of direct API calls
Use wrapper functions for Gmail label operations from @/utils/gmail/label.ts instead of direct API calls
**/*.{ts,tsx}: For early access feature flags, create hooks using the naming conventionuse[FeatureName]Enabledthat return a boolean fromuseFeatureFlagEnabled("flag-key")
For A/B test variant flags, create hooks using the naming conventionuse[FeatureName]Variantthat define variant types, useuseFeatureFlagVariantKey()with type casting, and provide a default "control" fallback
Use kebab-case for PostHog feature flag keys (e.g.,inbox-cleaner,pricing-options-2)
Always define types for A/B test variant flags (e.g.,type PricingVariant = "control" | "variant-a" | "variant-b") and provide type safety through type casting
**/*.{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 this and super in static contexts
Don't use any or unknown as type constraints
Don't use the TypeScript directive @ts-ignore
Don't use TypeScript enums
Don't export imported variables
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
Useas constinstead of literal types and type annotations
Use eitherT[]orArray<T>consistently
Initialize each enum member value explicitly
Useexport typefor types
Use `impo...
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxapps/web/utils/email/subject.tspackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsxapps/web/utils/error.tsapps/web/utils/cold-email/send-notification.ts
apps/web/app/(app)/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/page-structure.mdc)
apps/web/app/(app)/**/*.{ts,tsx}: Components for the page are either put inpage.tsx, or in theapps/web/app/(app)/PAGE_NAMEfolder
If we're in a deeply nested component we will useswrto fetch via API
If you need to useonClickin a component, that component is a client component and file must start withuse client
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/prisma-enum-imports.mdc)
Always import Prisma enums from
@/generated/prisma/enumsinstead of@/generated/prisma/clientto avoid Next.js bundling errors in client componentsImport Prisma using the project's centralized utility:
import prisma from '@/utils/prisma'
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxapps/web/utils/email/subject.tspackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsxapps/web/utils/error.tsapps/web/utils/cold-email/send-notification.ts
apps/web/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
Import specific lodash functions rather than entire lodash library to minimize bundle size (e.g.,
import groupBy from 'lodash/groupBy')
apps/web/**/*.{ts,tsx}: Use TypeScript with strict null checks
Use@/path aliases for imports from project root
Follow tailwindcss patterns with prettier-plugin-tailwindcss class organization
Prefix client-side environment variables withNEXT_PUBLIC_
Leverage TypeScript inference for better developer experience with type exports from API routes
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxapps/web/utils/email/subject.tsapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsxapps/web/utils/error.tsapps/web/utils/cold-email/send-notification.ts
**/*.{tsx,ts}
📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)
**/*.{tsx,ts}: Use Shadcn UI and Tailwind for components and styling
Usenext/imagepackage for images
For API GET requests to server, use theswrpackage with hooks likeuseSWRto fetch data
For text inputs, use theInputcomponent withregisterPropsfor form integration and error handling
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxapps/web/utils/email/subject.tspackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsxapps/web/utils/error.tsapps/web/utils/cold-email/send-notification.ts
**/*.{tsx,ts,css}
📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)
Implement responsive design with Tailwind CSS using a mobile-first approach
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxapps/web/utils/email/subject.tspackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsxapps/web/utils/error.tsapps/web/utils/cold-email/send-notification.ts
**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)
**/*.tsx: Use theLoadingContentcomponent to handle loading states instead of manual loading state management
For text areas, use theInputcomponent withtype='text',autosizeTextareaprop set to true, andregisterPropsfor form integration
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxpackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)
**/*.{js,jsx,ts,tsx}: Don't useaccessKeyattribute on any HTML element
Don't setaria-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<marquee>or<blink>
Only use thescopeprop on<th>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 assigntabIndexto non-interactive HTML elements
Don't use positive integers fortabIndexproperty
Don't include "image", "picture", or "photo" in img alt prop
Don't use explicit role property that's the same as the implicit/default role
Make static elements with click handlers use a valid role attribute
Always include atitleelement for SVG elements
Give all elements requiring alt text meaningful information for screen readers
Make sure anchors have content that's accessible to screen readers
AssigntabIndexto non-interactive HTML elements witharia-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 atypeattribute for button elements
Make elements with interactive roles and handlers focusable
Give heading elements content that's accessible to screen readers (not hidden witharia-hidden)
Always include alangattribute on the html element
Always include atitleattribute for iframe elements
AccompanyonClickwith at least one of:onKeyUp,onKeyDown, oronKeyPress
AccompanyonMouseOver/onMouseOutwithonFocus/onBlur
Include caption tracks for audio and video elements
Use semantic elements instead of role attributes in JSX
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 AR...
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxapps/web/utils/email/subject.tspackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsxapps/web/utils/error.tsapps/web/utils/cold-email/send-notification.ts
**/*.{jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)
**/*.{jsx,tsx}: 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 use event handlers on non-interactive elements
Don't assign to React component props
Don't use bothchildrenanddangerouslySetInnerHTMLprops on the same element
Don't use dangerous JSX props
Don't use Array index in keys
Don't insert comments as text nodes
Don't assign JSX properties multiple times
Don't add extra closing tags for components without children
Use<>...</>instead of<Fragment>...</Fragment>
Watch out for possible "wrong" semicolons inside JSX elements
Make sure void (self-closing) elements don't have children
Don't usetarget="_blank"withoutrel="noopener"
Don't use<img>elements in Next.js projects
Don't use<head>elements in Next.js projects
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxpackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsx
!(pages/_document).{jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)
Don't use the next/head module in pages/_document.js on Next.js projects
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxapps/web/utils/email/subject.tspackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsxapps/web/utils/error.tsapps/web/utils/cold-email/send-notification.ts
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/utilities.mdc)
**/*.{js,ts,jsx,tsx}: Use lodash utilities for common operations (arrays, objects, strings)
Import specific lodash functions to minimize bundle size (e.g.,import groupBy from 'lodash/groupBy')
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxapps/web/utils/email/subject.tspackages/resend/src/send.tsxapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsxapps/web/utils/error.tsapps/web/utils/cold-email/send-notification.ts
apps/web/**/app/**
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Follow NextJS app router structure with (app) directory
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsx
apps/web/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
apps/web/**/*.{tsx,jsx}: Prefer functional components with hooks over class components
Use shadcn/ui components when available
Follow consistent naming conventions with PascalCase for component names
Use LoadingContent component for async data with loading and error states
Useresult?.serverErrorwithtoastErrorandtoastSuccessfor mutation error handling
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsx
apps/web/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
apps/web/**/*.{ts,tsx,js,jsx}: Use proper error handling with try/catch blocks
Prefer self-documenting code over comments; use descriptive variable and function names instead of explaining intent with comments
Add helper functions to the bottom of files, not the top
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxapps/web/utils/email/subject.tsapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsxapps/web/utils/error.tsapps/web/utils/cold-email/send-notification.ts
apps/web/**/*.{ts,tsx,js,jsx,json,css,md}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Format code with Prettier
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxapps/web/utils/email/subject.tsapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsxapps/web/utils/error.tsapps/web/utils/cold-email/send-notification.ts
apps/web/**/*.{tsx,jsx,css}
📄 CodeRabbit inference engine (apps/web/CLAUDE.md)
Ensure responsive design with mobile-first approach
Files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsxapps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsx
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/security.mdc)
**/*.ts: ALL database queries MUST be scoped to the authenticated user/account by including user/account filtering in WHERE clauses to prevent unauthorized data access
Always validate that resources belong to the authenticated user before performing operations, using ownership checks in WHERE clauses or relationships
Always validate all input parameters for type, format, and length before using them in database queries
Use SafeError for error responses to prevent information disclosure. Generic error messages should not reveal internal IDs, logic, or resource ownership details
Only return necessary fields in API responses using Prisma'sselectoption. Never expose sensitive data such as password hashes, private keys, or system flags
Prevent Insecure Direct Object References (IDOR) by validating resource ownership before operations. AllfindUnique/findFirstcalls MUST include ownership filters
Prevent mass assignment vulnerabilities by explicitly whitelisting allowed fields in update operations instead of accepting all user-provided data
Prevent privilege escalation by never allowing users to modify system fields, ownership fields, or admin-only attributes through user input
AllfindManyqueries MUST be scoped to the user's data by including appropriate WHERE filters to prevent returning data from other users
Use Prisma relationships for access control by leveraging nested where clauses (e.g.,emailAccount: { id: emailAccountId }) to validate ownership
Files:
apps/web/utils/email/subject.tsapps/web/utils/error.tsapps/web/utils/cold-email/send-notification.ts
**/{utils,helpers,lib}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/logging.mdc)
Logger should be passed as a parameter to helper functions instead of creating their own logger instances
Files:
apps/web/utils/email/subject.tsapps/web/utils/error.tsapps/web/utils/cold-email/send-notification.ts
🧠 Learnings (9)
📚 Learning: 2025-11-25T14:39:49.448Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/server-actions.mdc:0-0
Timestamp: 2025-11-25T14:39:49.448Z
Learning: Applies to apps/web/utils/actions/*.ts : Add metadata with a meaningful action name using `.metadata({ name: "actionName" })` for Sentry instrumentation and monitoring
Applied to files:
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsx
📚 Learning: 2025-07-08T13:14:07.449Z
Learnt from: elie222
Repo: elie222/inbox-zero PR: 537
File: apps/web/app/(app)/[emailAccountId]/clean/onboarding/page.tsx:30-34
Timestamp: 2025-07-08T13:14:07.449Z
Learning: The clean onboarding page in apps/web/app/(app)/[emailAccountId]/clean/onboarding/page.tsx is intentionally Gmail-specific and should show an error for non-Google email accounts rather than attempting to support multiple providers.
Applied to files:
apps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsx
📚 Learning: 2025-11-25T14:40:00.833Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-25T14:40:00.833Z
Learning: Applies to **/*.test.{ts,tsx} : Use test helpers `getEmail`, `getEmailAccount`, and `getRule` from `@/__tests__/helpers` for mocking emails, accounts, and rules
Applied to files:
apps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsx
📚 Learning: 2025-11-25T14:39:08.150Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security-audit.mdc:0-0
Timestamp: 2025-11-25T14:39:08.150Z
Learning: Applies to apps/web/app/api/**/*.{ts,tsx} : Use generic error messages instead of revealing internal details; throw `SafeError` instead of exposing user IDs, resource IDs, or system information
Applied to files:
apps/web/utils/error.ts
📚 Learning: 2025-11-25T14:39:27.909Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security.mdc:0-0
Timestamp: 2025-11-25T14:39:27.909Z
Learning: Applies to **/app/api/**/*.ts : Maintain consistent error response format across all API routes to avoid information disclosure while providing meaningful error feedback
Applied to files:
apps/web/utils/error.ts
📚 Learning: 2025-11-25T14:39:27.909Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security.mdc:0-0
Timestamp: 2025-11-25T14:39:27.909Z
Learning: Applies to **/*.ts : Use SafeError for error responses to prevent information disclosure. Generic error messages should not reveal internal IDs, logic, or resource ownership details
Applied to files:
apps/web/utils/error.ts
📚 Learning: 2025-11-25T14:39:23.326Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security.mdc:0-0
Timestamp: 2025-11-25T14:39:23.326Z
Learning: Applies to app/api/**/*.ts : Use `SafeError` for error responses to prevent information disclosure - provide generic messages (e.g., 'Rule not found' not 'Rule {id} does not exist for user {userId}') without revealing internal IDs or ownership details
Applied to files:
apps/web/utils/error.ts
📚 Learning: 2025-11-25T14:38:07.606Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.606Z
Learning: Applies to apps/web/utils/ai/**/*.ts : Implement early returns for invalid LLM inputs, use proper error types and logging, implement fallbacks for AI failures, and add retry logic for transient failures using `withRetry`
Applied to files:
apps/web/utils/error.ts
📚 Learning: 2025-12-17T11:18:06.818Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-12-17T11:18:06.818Z
Learning: Applies to apps/web/**/*.{ts,tsx,js,jsx} : Use proper error handling with try/catch blocks
Applied to files:
apps/web/utils/error.ts
🧬 Code graph analysis (1)
packages/resend/src/send.tsx (2)
apps/web/utils/cold-email/send-notification.ts (1)
sendColdEmailNotification(7-66)packages/resend/emails/cold-email-notification.tsx (1)
ColdEmailNotificationProps(15-17)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: cubic · AI code reviewer
- GitHub Check: test
- GitHub Check: Review for correctness
🔇 Additional comments (5)
apps/web/utils/email/subject.ts (1)
6-17: LGTM! Clean edge-case handling for empty subjects.The new guard for empty subjects (lines 8-11) correctly returns "Re: (no subject)" as a sensible default, preventing malformed reply subjects. The logic flow is correct: empty check → duplicate "Re:" detection → "Re:" prefix addition.
apps/web/app/(app)/[emailAccountId]/cold-email-blocker/ColdEmailContent.tsx (1)
18-18: LGTM! Default tab now shows primary content.Setting "cold-emails" as the default value makes excellent UX sense for this feature, allowing users to immediately see their cold emails upon landing on the page.
apps/web/app/(app)/[emailAccountId]/assistant/AvailableActionsPanel.tsx (1)
24-24: LGTM!The NOTIFY_SENDER action name mapping follows the existing pattern and integrates cleanly with the available actions panel.
apps/web/utils/error.ts (2)
44-51: LGTM!The sampling logic correctly implements probabilistic error reporting. When
Math.random() >= sampleRate, the capture is skipped, which properly reduces error volume in production.
221-249: LGTM!The
getErrorMessageutility provides robust error message extraction with proper fallback handling. The helper functionsasRecordandgetStringPropsafely navigate nested error structures.
| if (result.error) { | ||
| console.error("Error sending cold email notification", result.error); | ||
| throw new Error( | ||
| `Error sending cold email notification: ${result.error.message}`, | ||
| ); | ||
| } |
There was a problem hiding this comment.
Error handling inconsistency creates dead code in caller.
This function throws when result.error exists, but the caller in apps/web/utils/cold-email/send-notification.ts (lines 39-48) expects to check result.error directly. Because of the throw on line 255, the caller's error check is unreachable dead code—any error will be caught by the outer try-catch block instead.
This is inconsistent with the caller's expectations. Choose one approach:
Option 1 (Recommended): Remove the throw and return the result, allowing the caller to check result.error as it expects.
Option 2: Keep the throw and remove the dead if (result.error) check in the caller (lines 39-48 of send-notification.ts).
🔎 Recommended fix: Remove throw to match caller's pattern
if (result.error) {
console.error("Error sending cold email notification", result.error);
- throw new Error(
- `Error sending cold email notification: ${result.error.message}`,
- );
}
return result;📝 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.
| if (result.error) { | |
| console.error("Error sending cold email notification", result.error); | |
| throw new Error( | |
| `Error sending cold email notification: ${result.error.message}`, | |
| ); | |
| } | |
| if (result.error) { | |
| console.error("Error sending cold email notification", result.error); | |
| } | |
| return result; |
🤖 Prompt for AI Agents
In packages/resend/src/send.tsx around lines 253 to 258, the function logs and
then throws when result.error exists, which makes the caller's subsequent if
(result.error) check unreachable; remove the throw and instead return the result
so callers can inspect result.error as they expect, keeping or enhancing the
console.error log as needed to preserve diagnostics.
There was a problem hiding this comment.
2 issues found across 7 files (changes from recent commits).
Prompt for AI agents (all 2 issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="apps/web/utils/cold-email/send-notification.ts">
<violation number="1" location="apps/web/utils/cold-email/send-notification.ts:40">
P2: This error check is unreachable dead code. The `sendColdEmailNotificationViaResend` function throws an exception when `result.error` exists, so this `if (result.error)` block will never execute - the error will be caught by the outer try-catch block instead. Either remove this dead code block, or modify the called function to return errors instead of throwing.</violation>
</file>
<file name="apps/web/app/(app)/[emailAccountId]/assistant/constants.ts">
<violation number="1" location="apps/web/app/(app)/[emailAccountId]/assistant/constants.ts:66">
P2: The `lowerExample.includes("sender")` check is too broad and will incorrectly match strings like "Reply to sender" or "Forward to original sender", returning NOTIFY_SENDER color instead of the correct action color. Consider using only `"notify"` as the keyword, or use a combined pattern like `"notify sender"` to be more specific.</violation>
</file>
Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR
| }); | ||
| return { | ||
| success: false, | ||
| error: error instanceof Error ? error.message : "Unknown error", |
There was a problem hiding this comment.
getErrorMessage is imported but not used, and the manual instanceof Error check may drop detail. Consider using getErrorMessage(error) here (or remove the import if you don’t need it).
| error: error instanceof Error ? error.message : "Unknown error", | |
| error: getErrorMessage(error), |
🚀 Reply to ask Macroscope to explain or update this suggestion.
👍 Helpful? React to give us feedback.
| }, | ||
| }); | ||
|
|
||
| logger.info("Cold email notification sent", { |
There was a problem hiding this comment.
sendColdEmailNotification treats a non-throwing { data, error } response as success. Consider checking result.error before logging/returning success and propagate it if present.
+ if (result.error) {
+ logger.error("Resend returned an error when sending cold email notification", { senderEmail, error: result.error });
+ return { success: false, error: getErrorMessage(result.error) };
+ }🚀 Reply to ask Macroscope to explain or update this suggestion.
👍 Helpful? React to give us feedback.
Add cold email notifier by introducing
ActionType.NOTIFY_SENDERacross UI, validation, and backend execution to send Resend-based notifications for cold outreach filteringIntroduce a new action type that displays dedicated UI copy, appears only for cold email rules when
NEXT_PUBLIC_IS_RESEND_CONFIGUREDis true, validates in schemas, and executes viautils/ai/actions.ts::notify_senderusing Resend with a new email template and helper. Include enum/migration updates, icon/color mappings, and subject formatting fixes.📍Where to Start
Start with the
notify_senderflow in apps/web/utils/ai/actions.ts, then review the email send helper in apps/web/utils/cold-email/send-notification.ts and the Resend sender in packages/resend/src/send.tsx.📊 Macroscope summarized 854178c. 19 files reviewed, 4 issues evaluated, 2 issues filtered, 2 comments posted
🗂️ Filtered Issues
apps/web/app/(app)/[emailAccountId]/assistant/constants.ts — 0 comments posted, 1 evaluated, 1 filtered
getActionTypeColorfunction does not include a case to match strings containing "notify" or "sender", so any caller passing a string like "notify sender" will receive the fallback"bg-gray-500"instead of the newly added"bg-amber-500"color forActionType.NOTIFY_SENDER. This is inconsistent with the pattern used for other action types in the function. [ Out of scope ]apps/web/utils/actions/rule.validation.ts — 0 comments posted, 1 evaluated, 1 filtered
ActionType.NOTIFY_SENDERis added tozodActionTypebut no validation is added in thesuperRefineblock ofzodAction. IfNOTIFY_SENDERrequires specific fields (likecontent,subject, or recipient configuration similar to other email-related actions likeFORWARDorSEND_EMAIL), users could create invalid rules that pass validation but fail at runtime when the action is executed. [ Low confidence ]Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.