Conversation
|
@edulelis is attempting to deploy a commit to the Inbox Zero Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughThe changes introduce logic to ensure a default digest schedule is created for users during onboarding, including a new server action for this purpose. The onboarding flow now checks and sets the digest schedule alongside categories. Minor prompt refinements and a UI spacing adjustment for email category badges are also included. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant OnboardingPage
participant ServerActions
User->>OnboardingPage: Complete digest categories selection
OnboardingPage->>ServerActions: updateDigestCategoriesAction
alt Success
OnboardingPage->>ServerActions: ensureDefaultDigestScheduleAction
alt Schedule exists or created
OnboardingPage->>User: Show success, complete onboarding
else Schedule creation fails
OnboardingPage->>User: Show error toast
end
else Categories save fails
OnboardingPage->>User: Show error toast
end
Possibly related PRs
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
apps/web/app/(app)/[emailAccountId]/assistant/onboarding/digest-frequency/page.tsxOops! Something went wrong! :( ESLint: 9.28.0 ESLint couldn't find an eslint.config.(js|mjs|cjs) file. From ESLint v9.0.0, the default configuration file is now eslint.config.js. https://eslint.org/docs/latest/use/configure/migration-guide If you still have problems after following the migration guide, please stop by apps/web/utils/actions/settings.tsOops! Something went wrong! :( ESLint: 9.28.0 ESLint couldn't find an eslint.config.(js|mjs|cjs) file. From ESLint v9.0.0, the default configuration file is now eslint.config.js. https://eslint.org/docs/latest/use/configure/migration-guide If you still have problems after following the migration guide, please stop by apps/web/utils/ai/choose-rule/ai-choose-rule.tsOops! Something went wrong! :( ESLint: 9.28.0 ESLint couldn't find an eslint.config.(js|mjs|cjs) file. From ESLint v9.0.0, the default configuration file is now eslint.config.js. https://eslint.org/docs/latest/use/configure/migration-guide If you still have problems after following the migration guide, please stop by
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/web/app/(app)/[emailAccountId]/assistant/onboarding/digest-frequency/page.tsx(3 hunks)apps/web/utils/actions/settings.ts(2 hunks)apps/web/utils/ai/choose-rule/ai-choose-rule.ts(2 hunks)packages/resend/emails/digest.tsx(5 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
`apps/web/**/*.{ts,tsx}`: Use TypeScript with strict null checks Path aliases: U...
apps/web/**/*.{ts,tsx}: Use TypeScript with strict null checks
Path aliases: Use@/for imports from project root
Use proper error handling with try/catch blocks
Format code with Prettier
📄 Source: CodeRabbit Inference Engine (apps/web/CLAUDE.md)
List of files the instruction was applied to:
apps/web/utils/ai/choose-rule/ai-choose-rule.tsapps/web/app/(app)/[emailAccountId]/assistant/onboarding/digest-frequency/page.tsxapps/web/utils/actions/settings.ts
`**/*.{ts,tsx}`: Define validation schemas using Zod Apply the same validation in both client and server Use descriptive error messages
**/*.{ts,tsx}: Define validation schemas using Zod
Apply the same validation in both client and server
Use descriptive error messages
📄 Source: CodeRabbit Inference Engine (.cursor/rules/form-handling.mdc)
List of files the instruction was applied to:
apps/web/utils/ai/choose-rule/ai-choose-rule.tsapps/web/app/(app)/[emailAccountId]/assistant/onboarding/digest-frequency/page.tsxpackages/resend/emails/digest.tsxapps/web/utils/actions/settings.ts
`apps/web/app/**/*`: NextJS app router structure with (app) directory
apps/web/app/**/*: NextJS app router structure with (app) directory
📄 Source: CodeRabbit Inference Engine (apps/web/CLAUDE.md)
List of files the instruction was applied to:
apps/web/app/(app)/[emailAccountId]/assistant/onboarding/digest-frequency/page.tsx
`apps/web/**/*.tsx`: Follow tailwindcss patterns with prettier-plugin-tailwindcs...
apps/web/**/*.tsx: Follow tailwindcss patterns with prettier-plugin-tailwindcss
Prefer functional components with hooks
Use shadcn/ui components when available
Ensure responsive design with mobile-first approach
Follow consistent naming conventions (PascalCase for components)
Use LoadingContent component for async data
📄 Source: CodeRabbit Inference Engine (apps/web/CLAUDE.md)
List of files the instruction was applied to:
apps/web/app/(app)/[emailAccountId]/assistant/onboarding/digest-frequency/page.tsx
`**/*.tsx`: For API GET requests to server, use the `swr` package Use `result?.serverError` with `toastError` and `toastSuccess` for error handling; success toast is optional
**/*.tsx: For API GET requests to server, use theswrpackage
Useresult?.serverErrorwithtoastErrorandtoastSuccessfor error handling; success toast is optional
📄 Source: CodeRabbit Inference Engine (.cursor/rules/data-fetching.mdc)
List of files the instruction was applied to:
apps/web/app/(app)/[emailAccountId]/assistant/onboarding/digest-frequency/page.tsxpackages/resend/emails/digest.tsx
`**/*.tsx`: Use React Hook Form with Zod for validation Validate form inputs before submission Show validation errors inline next to form fields
**/*.tsx: Use React Hook Form with Zod for validation
Validate form inputs before submission
Show validation errors inline next to form fields
📄 Source: CodeRabbit Inference Engine (.cursor/rules/form-handling.mdc)
List of files the instruction was applied to:
apps/web/app/(app)/[emailAccountId]/assistant/onboarding/digest-frequency/page.tsxpackages/resend/emails/digest.tsx
🧠 Learnings (3)
apps/web/utils/ai/choose-rule/ai-choose-rule.ts (2)
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/index.mdc:0-0
Timestamp: 2025-06-23T12:26:22.732Z
Learning: Clearly document the purpose and scope of each rule file to help developers quickly understand where to find relevant guidance.
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/cursor-rules.mdc:0-0
Timestamp: 2025-07-03T12:02:24.598Z
Learning: Applies to .cursor/rules/*.mdc : Make Cursor rule file names descriptive of the rule's purpose
apps/web/app/(app)/[emailAccountId]/assistant/onboarding/digest-frequency/page.tsx (7)
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/hooks.mdc:0-0
Timestamp: 2025-06-23T12:26:16.769Z
Learning: Custom React hooks should encapsulate reusable stateful logic, especially for data fetching or complex UI interactions.
Learnt from: aryanprince
PR: elie222/inbox-zero#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`.
Learnt from: CR
PR: elie222/inbox-zero#0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:02:16.137Z
Learning: Applies to apps/web/**/*.tsx : Prefer functional components with hooks
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-06-23T12:26:59.468Z
Learning: For components with onClick handlers in Next.js App Router, ensure they are client components by including the 'use client' directive at the top of the file.
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/data-fetching.mdc:0-0
Timestamp: 2025-07-03T12:02:38.024Z
Learning: For mutating data, use Next.js server actions
Learnt from: CR
PR: elie222/inbox-zero#0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-07-03T12:02:16.137Z
Learning: Applies to apps/web/**/*.tsx : Use shadcn/ui components when available
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-06-23T12:27:33.499Z
Learning: For form text inputs in React using Shadcn UI, use the `Input` component with `registerProps` from a form library (such as react-hook-form) and pass any validation errors to the `error` prop.
apps/web/utils/actions/settings.ts (7)
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/server-actions.mdc:0-0
Timestamp: 2025-06-23T12:27:23.938Z
Learning: Input validation schemas for server actions should be defined using Zod in dedicated .validation.ts files, which can be reused on the client for form validation.
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/server-actions.mdc:0-0
Timestamp: 2025-06-23T12:27:23.938Z
Learning: Sentry instrumentation for server actions is automatically applied via withServerActionInstrumentation in the safe action clients, and meaningful action names should be provided using the .metadata({ name: "actionName" }) method.
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/server-actions.mdc:0-0
Timestamp: 2025-06-23T12:27:23.938Z
Learning: In Next.js projects, server actions should be implemented using the next-safe-action library to ensure type safety, input validation, context management, and centralized error handling.
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/data-fetching.mdc:0-0
Timestamp: 2025-07-03T12:02:38.024Z
Learning: For mutating data, use Next.js server actions
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/server-actions.mdc:0-0
Timestamp: 2025-06-23T12:27:23.938Z
Learning: The next-safe-action library provides different clients for context management: actionClientUser for authenticated user context, actionClient for user plus resource-specific context (like emailAccountId), and adminActionClient for admin-restricted actions.
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-07-03T12:02:53.001Z
Learning: Applies to **/*.{ts,tsx} : Define validation schemas using Zod
Learnt from: CR
PR: elie222/inbox-zero#0
File: .cursor/rules/form-handling.mdc:0-0
Timestamp: 2025-07-03T12:02:53.001Z
Learning: Applies to **/*.tsx : Use React Hook Form with Zod for validation
🧬 Code Graph Analysis (2)
apps/web/app/(app)/[emailAccountId]/assistant/onboarding/digest-frequency/page.tsx (3)
apps/web/utils/actions/settings.ts (2)
ensureDefaultDigestScheduleAction(200-237)updateDigestScheduleAction(54-104)apps/web/utils/cookies.ts (2)
markOnboardingAsCompleted(4-6)ASSISTANT_ONBOARDING_COOKIE(1-1)apps/web/utils/path.ts (1)
prefixPath(1-4)
apps/web/utils/actions/settings.ts (3)
apps/web/utils/actions/safe-action.ts (1)
actionClient(43-73)apps/web/utils/schedule.ts (1)
calculateNextScheduleDate(52-150)apps/web/utils/error.ts (1)
SafeError(83-91)
⏰ 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). (2)
- GitHub Check: Static Code Analysis Js
- GitHub Check: Jit Security
🔇 Additional comments (6)
apps/web/utils/actions/settings.ts (1)
200-237: Default digest schedule bitmask verified and correctThe
maskForutility maps JavaScript days (0 = Sunday … 6 = Saturday) to bitmasks via1 << (6 - jsDay). CallingmaskFor(1)yields1 << 5, so using1 << (6 - 1)for Monday is accurate. No changes needed—LGTM!packages/resend/emails/digest.tsx (1)
207-207: LGTM! Consistent margin adjustment improves badge alignment.The uniform application of
ml-[8px]across all category count scenarios will improve the visual alignment of digest count badges, which aligns with the PR objective to fix digest email alignment.Also applies to: 241-241, 264-264, 299-299, 321-321
apps/web/utils/ai/choose-rule/ai-choose-rule.ts (2)
33-35: LGTM! Improved prompt instructions for better AI responses.The additional priority rules will help ensure more concise and accurate AI responses by requiring exact rule name matching and avoiding repetitive explanations.
67-67: LGTM! Better specification of expected output format.Clarifying "valid JSON object" instead of just "JSON object" helps set clearer expectations for the AI response format.
apps/web/app/(app)/[emailAccountId]/assistant/onboarding/digest-frequency/page.tsx (2)
9-13: LGTM! Proper imports for the new digest schedule functionality.The imports correctly include both actions needed for the enhanced onboarding flow.
82-119: LGTM! Well-structured sequential updates with proper error handling.The enhanced
handleFinishfunction correctly coordinates both digest categories and schedule updates. The error handling with early returns ensures that onboarding only proceeds when both operations succeed, which is the correct behavior.The schedule configuration (weekly on Monday at 11 AM) is consistent with the default created in the useEffect and server action.
| useEffect(() => { | ||
| // Ensure user has a digest schedule entry when they visit this page, otherwise the digest is not sent | ||
| const timeOfDay = new Date(); | ||
| timeOfDay.setHours(11, 0, 0, 0); // 11 AM in user's timezone | ||
| ensureDefaultDigestScheduleAction(emailAccountId, { timeOfDay }); | ||
| }, [emailAccountId]); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add error handling for the default schedule creation.
The useEffect lacks error handling for ensureDefaultDigestScheduleAction. While this action is designed to be safe, adding error handling would improve robustness.
useEffect(() => {
// Ensure user has a digest schedule entry when they visit this page, otherwise the digest is not sent
const timeOfDay = new Date();
timeOfDay.setHours(11, 0, 0, 0); // 11 AM in user's timezone
- ensureDefaultDigestScheduleAction(emailAccountId, { timeOfDay });
+ ensureDefaultDigestScheduleAction(emailAccountId, { timeOfDay }).catch(
+ (error) => {
+ console.error("Failed to ensure default digest schedule:", error);
+ // Non-blocking error - user can still proceed with onboarding
+ }
+ );
}, [emailAccountId]);📝 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.
| useEffect(() => { | |
| // Ensure user has a digest schedule entry when they visit this page, otherwise the digest is not sent | |
| const timeOfDay = new Date(); | |
| timeOfDay.setHours(11, 0, 0, 0); // 11 AM in user's timezone | |
| ensureDefaultDigestScheduleAction(emailAccountId, { timeOfDay }); | |
| }, [emailAccountId]); | |
| useEffect(() => { | |
| // Ensure user has a digest schedule entry when they visit this page, otherwise the digest is not sent | |
| const timeOfDay = new Date(); | |
| timeOfDay.setHours(11, 0, 0, 0); // 11 AM in user's timezone | |
| ensureDefaultDigestScheduleAction(emailAccountId, { timeOfDay }).catch( | |
| (error) => { | |
| console.error("Failed to ensure default digest schedule:", error); | |
| // Non-blocking error - user can still proceed with onboarding | |
| } | |
| ); | |
| }, [emailAccountId]); |
🤖 Prompt for AI Agents
In
apps/web/app/(app)/[emailAccountId]/assistant/onboarding/digest-frequency/page.tsx
around lines 60 to 65, the useEffect calls ensureDefaultDigestScheduleAction
without error handling. Wrap the call in a try-catch block or handle the promise
rejection to catch any errors during the default schedule creation, and log or
handle the error appropriately to improve robustness.
Realigning digest counts as image below

Summary by CodeRabbit