Skip to content

Enable meeting briefs beta and other feature flags#1095

Merged
elie222 merged 2 commits intomainfrom
feat/enable-meeting-briefs
Dec 16, 2025
Merged

Enable meeting briefs beta and other feature flags#1095
elie222 merged 2 commits intomainfrom
feat/enable-meeting-briefs

Conversation

@elie222
Copy link
Owner

@elie222 elie222 commented Dec 16, 2025

Gate digest, meeting briefs beta, and integrations in web app with new public env flags and show Beta badges in sidebar

Add NEXT_PUBLIC_DIGEST_ENABLED, NEXT_PUBLIC_MEETING_BRIEFS_ENABLED, and NEXT_PUBLIC_INTEGRATIONS_ENABLED to client env, gate digest UI and settings behind the digest flag, switch meeting briefs flagging to env, add an Integrations nav item and mark Integrations and Meeting Briefs as beta with a sidebar badge, and document the flags. Also reorder the ActionType.FORWARD form inputs and bump v2.23.1.

📍Where to Start

Start with the feature flag definitions in env.ts, then review their usage in navigation and feature hooks in useFeatureFlags.ts and sidebar rendering in components/SideNav.tsx and components/SideNavMenu.tsx.


Macroscope summarized 811d26d.

Summary by CodeRabbit

  • New Features

    • Added Integrations entry to navigation (beta) and introduced feature flags for Digest, Meeting Briefs, and Integrations.
  • Improvements

    • Digest setting and related UI are now feature-flag gated.
    • Reordered fields in the Forward action for improved usability.
    • Beta badges added to indicate experimental items in navigation.
  • Documentation

    • Added and documented the new feature-flag environment variables.
  • Chores

    • Version bumped to v2.23.1.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Dec 16, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
inbox-zero Ready Ready Preview Dec 16, 2025 0:04am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 16, 2025

Note

Other AI code review bot(s) detected

CodeRabbit 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.

Walkthrough

Adds three client-side feature flags (NEXT_PUBLIC_DIGEST_ENABLED, NEXT_PUBLIC_MEETING_BRIEFS_ENABLED, NEXT_PUBLIC_INTEGRATIONS_ENABLED), wires them into env/runtime config and docs, gates digest and integrations UI behind those flags, adds a useIntegrationsEnabled hook, reorders a FORWARD action field, and bumps version to v2.23.1. (≤50 words)

Changes

Cohort / File(s) Summary
Environment configuration
apps/web/.env.example, apps/web/env.ts, turbo.json, version.txt
Added three public feature-flag env vars (NEXT_PUBLIC_DIGEST_ENABLED, NEXT_PUBLIC_MEETING_BRIEFS_ENABLED, NEXT_PUBLIC_INTEGRATIONS_ENABLED) to examples, client/runtime env mapping and turbo.json; bumped version to v2.23.1.
Digest feature gating
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx, apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
Conditionally render the digest toggle and DigestSetting only when NEXT_PUBLIC_DIGEST_ENABLED is truthy; moved tooltip/markup into the gated block.
Feature flag hooks
apps/web/hooks/useFeatureFlags.ts
useMeetingBriefsEnabled now reads env.NEXT_PUBLIC_MEETING_BRIEFS_ENABLED; added new exported hook useIntegrationsEnabled that returns env.NEXT_PUBLIC_INTEGRATIONS_ENABLED.
Navigation UI
apps/web/components/SideNav.tsx, apps/web/components/SideNavMenu.tsx
Added optional beta?: boolean to NavItem type, conditionally include an "Integrations" nav item when integrations flag enabled, and render a Beta Badge for items marked beta.
Utility change
apps/web/utils/action-item.ts
Reordered fields for ActionType.FORWARD so the to field appears before content (removed duplicate).
Docs
docs/hosting/environment-variables.md, apps/web/.env.example
Documented the three new NEXT_PUBLIC_* feature flags in hosting docs and example env.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas to check closely:
    • Consistent wiring of the three flags from env.tsuseFeatureFlags → gated components.
    • Boolean coercion behavior in env.ts (undefined vs false) and downstream UI expectations.
    • SideNav/SideNavMenu: ensure beta rendering and layout/styling align with existing items.
    • RuleForm/SettingsTab: verify no regressions in form submission or settings state when digest UI is absent.

Possibly related PRs

Poem

🐰 I hopped through env and code today,
Flags tucked in where toggles play,
Digest, Briefs, Integrations too,
Quietly waiting for "true",
A bunny's small deploy bouquet 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main objectives: enabling meeting briefs beta and introducing multiple feature flags for digest, meeting briefs, and integrations.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/enable-meeting-briefs

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 27338a4 and 811d26d.

📒 Files selected for processing (1)
  • docs/hosting/environment-variables.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
!(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:

  • docs/hosting/environment-variables.md
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:27.988Z
Learning: Applies to apps/web/hooks/useFeatureFlags.ts : Use kebab-case for feature flag keys (e.g., `inbox-cleaner`, `pricing-options-2`)
📚 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:

  • docs/hosting/environment-variables.md
📚 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:

  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:36:18.416Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.416Z
Learning: Applies to apps/web/**/*NEXT_PUBLIC_* : Prefix client-side environment variables with `NEXT_PUBLIC_`

Applied to files:

  • docs/hosting/environment-variables.md
📚 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:

  • docs/hosting/environment-variables.md
📚 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:

  • docs/hosting/environment-variables.md
📚 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 turbo.json : Add new environment variables to `turbo.json` under `tasks.build.env` as a global dependency for the build task

Applied to files:

  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:36:18.416Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.416Z
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:

  • docs/hosting/environment-variables.md
📚 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 : Add new environment variables to `.env.example` with example values

Applied to files:

  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:38:27.988Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:27.988Z
Learning: Applies to apps/web/hooks/useFeatureFlags.ts : Use `use[FeatureName]Enabled` naming convention for boolean feature flag hooks and `use[FeatureName]Variant` for A/B test variant hooks

Applied to files:

  • docs/hosting/environment-variables.md
📚 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 turbo.json : Add environment variables to `turbo.json` under `tasks.build.env` array to declare build-time dependencies

Applied to files:

  • docs/hosting/environment-variables.md
📚 Learning: 2025-07-19T15:06:43.730Z
Learnt from: garnertb
Repo: elie222/inbox-zero PR: 580
File: apps/web/.env.example:4-7
Timestamp: 2025-07-19T15:06:43.730Z
Learning: In apps/web/.env.example, boolean environment variables follow an unquoted convention (e.g., LOG_ZOD_ERRORS=true, AUTH_TRUST_HOST=true). Logical grouping of related variables (like auth variables together) is preferred over strict alphabetical ordering for better developer experience.

Applied to files:

  • docs/hosting/environment-variables.md
🔇 Additional comments (1)
docs/hosting/environment-variables.md (1)

88-90: Documentation additions are accurate and well-placed.

The three new feature flags are properly documented with clear descriptions, appropriate defaults (false for opt-in features), and helpful context about operational dependencies (QStash for digest, cron job for meeting briefs). Placement within the Feature Flags section is logical and consistent with the existing table format. Each entry correctly uses the NEXT_PUBLIC_ prefix and is marked as optional.


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

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
apps/web/utils/action-item.ts (1)

112-115: Consider separating unrelated change.

This field reordering improvement appears unrelated to the PR's stated objective of enabling feature flags for meeting briefs and other features. While the change itself is reasonable (placing the required "To" field first), consider whether it should be in a separate commit or PR for clearer change tracking.

apps/web/.env.example (1)

140-143: Add trailing newline for consistency.

The file is missing a trailing newline at the end. This is a minor formatting issue flagged by dotenv-linter.

Apply this diff:

 # Feature flags
 # NEXT_PUBLIC_DIGEST_ENABLED=true
 # NEXT_PUBLIC_MEETING_BRIEFS_ENABLED=true
-# NEXT_PUBLIC_INTEGRATIONS_ENABLED=true
+# NEXT_PUBLIC_INTEGRATIONS_ENABLED=true
+
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc6b703 and 27338a4.

📒 Files selected for processing (10)
  • apps/web/.env.example (1 hunks)
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx (2 hunks)
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx (2 hunks)
  • apps/web/components/SideNav.tsx (4 hunks)
  • apps/web/components/SideNavMenu.tsx (3 hunks)
  • apps/web/env.ts (2 hunks)
  • apps/web/hooks/useFeatureFlags.ts (1 hunks)
  • apps/web/utils/action-item.ts (1 hunks)
  • turbo.json (1 hunks)
  • version.txt (1 hunks)
🧰 Additional context used
📓 Path-based instructions (25)
!(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:

  • version.txt
  • apps/web/components/SideNavMenu.tsx
  • turbo.json
  • apps/web/env.ts
  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/utils/action-item.ts
  • apps/web/components/SideNav.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
  • apps/web/.env.example
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
apps/web/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

apps/web/**/*.{ts,tsx}: Use TypeScript with strict null checks
Use @/ path aliases for imports from project root
Use proper error handling with try/catch blocks
Format code with Prettier
Follow consistent naming conventions using PascalCase for components
Centralize shared types in dedicated type files

Import specific lodash functions rather than entire lodash library to minimize bundle size (e.g., import groupBy from 'lodash/groupBy')

Files:

  • apps/web/components/SideNavMenu.tsx
  • apps/web/env.ts
  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/utils/action-item.ts
  • apps/web/components/SideNav.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
apps/web/**/*.tsx

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

apps/web/**/*.tsx: Follow tailwindcss patterns with prettier-plugin-tailwindcss for class sorting
Prefer functional components with hooks over class components
Use shadcn/ui components when available
Ensure responsive design with mobile-first approach
Use LoadingContent component for async data with loading and error states

Files:

  • apps/web/components/SideNavMenu.tsx
  • apps/web/components/SideNav.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
apps/web/components/**/*.tsx

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

apps/web/components/**/*.tsx: Use React Hook Form with Zod validation for form components
Use result?.serverError with toastError and toastSuccess for error handling in form submissions

Use LoadingContent component to consistently handle loading and error states, passing loading, error, and children props

Use PascalCase for component file names (e.g., components/Button.tsx)

Files:

  • apps/web/components/SideNavMenu.tsx
  • apps/web/components/SideNav.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/data-fetching.mdc)

**/*.{ts,tsx}: For API GET requests to server, use the swr package
Use result?.serverError with toastError from @/components/Toast for 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 convention use[FeatureName]Enabled that return a boolean from useFeatureFlagEnabled("flag-key")
For A/B test variant flags, create hooks using the naming convention use[FeatureName]Variant that define variant types, use useFeatureFlagVariantKey() 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
Use as const instead of literal types and type annotations
Use either T[] or Array<T> consistently
Initialize each enum member value explicitly
Use export type for types
Use `impo...

Files:

  • apps/web/components/SideNavMenu.tsx
  • apps/web/env.ts
  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/utils/action-item.ts
  • apps/web/components/SideNav.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.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/SideNavMenu.tsx
  • apps/web/components/SideNav.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/prisma-enum-imports.mdc)

Always import Prisma enums from @/generated/prisma/enums instead of @/generated/prisma/client to avoid Next.js bundling errors in client components

Import Prisma using the project's centralized utility: import prisma from '@/utils/prisma'

Files:

  • apps/web/components/SideNavMenu.tsx
  • apps/web/env.ts
  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/utils/action-item.ts
  • apps/web/components/SideNav.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

**/*.{tsx,ts}: Use Shadcn UI and Tailwind for components and styling
Use next/image package for images
For API GET requests to server, use the swr package with hooks like useSWR to fetch data
For text inputs, use the Input component with registerProps for form integration and error handling

Files:

  • apps/web/components/SideNavMenu.tsx
  • apps/web/env.ts
  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/utils/action-item.ts
  • apps/web/components/SideNav.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
**/*.{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/SideNavMenu.tsx
  • apps/web/env.ts
  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/utils/action-item.ts
  • apps/web/components/SideNav.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

**/*.tsx: Use the LoadingContent component to handle loading states instead of manual loading state management
For text areas, use the Input component with type='text', autosizeTextarea prop set to true, and registerProps for form integration

Files:

  • apps/web/components/SideNavMenu.tsx
  • apps/web/components/SideNav.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{js,jsx,ts,tsx}: Don't use accessKey attribute on any HTML element
Don't set aria-hidden="true" on focusable elements
Don't add ARIA roles, states, and properties to elements that don't support them
Don't use distracting elements like <marquee> or <blink>
Only use the scope prop 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 assign tabIndex to non-interactive HTML elements
Don't use positive integers for tabIndex property
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 a title element 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
Assign tabIndex to non-interactive HTML elements with aria-activedescendant
Include all required ARIA attributes for elements with ARIA roles
Make sure ARIA properties are valid for the element's supported roles
Always include a type attribute for button elements
Make elements with interactive roles and handlers focusable
Give heading elements content that's accessible to screen readers (not hidden with aria-hidden)
Always include a lang attribute on the html element
Always include a title attribute for iframe elements
Accompany onClick with at least one of: onKeyUp, onKeyDown, or onKeyPress
Accompany onMouseOver/onMouseOut with onFocus/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/SideNavMenu.tsx
  • apps/web/env.ts
  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/utils/action-item.ts
  • apps/web/components/SideNav.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
**/*.{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 both children and dangerouslySetInnerHTML props 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 use target="_blank" without rel="noopener"
Don't use <img> elements in Next.js projects
Don't use <head> elements in Next.js projects

Files:

  • apps/web/components/SideNavMenu.tsx
  • apps/web/components/SideNav.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.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/components/SideNavMenu.tsx
  • apps/web/env.ts
  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/utils/action-item.ts
  • apps/web/components/SideNav.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
turbo.json

📄 CodeRabbit inference engine (.cursor/rules/environment-variables.mdc)

Add new environment variables to turbo.json under tasks.build.env as a global dependency for the build task

Files:

  • turbo.json
apps/web/**/{.env.example,env.ts,turbo.json}

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

Add environment variables to .env.example, env.ts, and turbo.json

Files:

  • apps/web/env.ts
  • apps/web/.env.example
apps/web/env.ts

📄 CodeRabbit inference engine (.cursor/rules/environment-variables.mdc)

apps/web/env.ts: Add server-only environment variables to apps/web/env.ts under the server object with Zod schema validation
Add client-side environment variables to apps/web/env.ts under the client object with NEXT_PUBLIC_ prefix and Zod schema validation
Add client-side environment variables to apps/web/env.ts under the experimental__runtimeEnv object 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's select option. 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. All findUnique/findFirst calls 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
All findMany queries 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/hooks/useFeatureFlags.ts
  • apps/web/utils/action-item.ts
apps/web/hooks/use*.ts

📄 CodeRabbit inference engine (apps/web/CLAUDE.md)

Use SWR for client-side data fetching with typed responses from GET API routes

apps/web/hooks/use*.ts: Use SWR hooks for client-side data fetching, with hooks stored in apps/web/hooks/use*.ts that return typed responses from GET API routes
Call mutate() on SWR hooks after successful mutations to refresh cached data

apps/web/hooks/use*.ts: Use the use prefix for custom hook filenames (e.g., useAccounts.ts)
For data fetching in custom hooks, prefer using useSWR and wrap it to handle API endpoint URL, returning data, loading state, error state, and potentially the mutate function
Create dedicated hooks for specific data types (e.g., useAccounts, useLabels) to wrap useSWR for individual API endpoints

Files:

  • apps/web/hooks/useFeatureFlags.ts
apps/web/hooks/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/hooks.mdc)

Place custom hooks in the apps/web/hooks/ directory

Files:

  • apps/web/hooks/useFeatureFlags.ts
apps/web/hooks/useFeatureFlags.ts

📄 CodeRabbit inference engine (.cursor/rules/posthog-feature-flags.mdc)

Feature flag hooks should be defined in apps/web/hooks/useFeatureFlags.ts with two patterns: boolean flags using useFeatureFlagEnabled("key") and variant flags using useFeatureFlagVariantKey("key") with type casting

Files:

  • apps/web/hooks/useFeatureFlags.ts
**/{server,api,actions,utils}/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/logging.mdc)

**/{server,api,actions,utils}/**/*.ts: Use createScopedLogger from "@/utils/logger" for logging in backend code
Add the createScopedLogger instantiation at the top of the file with an appropriate scope name
Use .with() method to attach context variables only within specific functions, not on global loggers
For large functions with reused variables, use createScopedLogger().with() to attach context once and reuse the logger without passing variables repeatedly

Files:

  • apps/web/utils/action-item.ts
apps/web/app/**/*.{ts,tsx}

📄 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/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
**/*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 in page.tsx, or in the apps/web/app/(app)/PAGE_NAME folder
If we're in a deeply nested component we will use swr to fetch via API
If you need to use onClick in a component, that component is a client component and file must start with use client

Files:

  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
🧠 Learnings (32)
📓 Common learnings
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.416Z
Learning: Applies to apps/web/**/{.env.example,env.ts,turbo.json} : Add environment variables to `.env.example`, `env.ts`, and `turbo.json`
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
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
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:32.328Z
Learning: Applies to **/*.{ts,tsx} : For early access feature flags, create hooks using the naming convention `use[FeatureName]Enabled` that return a boolean from `useFeatureFlagEnabled("flag-key")`
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.416Z
Learning: Applies to apps/web/**/*NEXT_PUBLIC_* : Prefix client-side environment variables with `NEXT_PUBLIC_`
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_`
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:27.988Z
Learning: Applies to apps/web/hooks/useFeatureFlags.ts : Use kebab-case for feature flag keys (e.g., `inbox-cleaner`, `pricing-options-2`)
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 turbo.json : Add new environment variables to `turbo.json` under `tasks.build.env` as a global dependency for the build task
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:27.988Z
Learning: Applies to apps/web/hooks/useFeatureFlags.ts : Use `use[FeatureName]Enabled` naming convention for boolean feature flag hooks and `use[FeatureName]Variant` for A/B test variant hooks
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:32.328Z
Learning: Applies to **/*.{ts,tsx} : For A/B test variant flags, create hooks using the naming convention `use[FeatureName]Variant` that define variant types, use `useFeatureFlagVariantKey()` with type casting, and provide a default "control" fallback
📚 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 turbo.json : Add new environment variables to `turbo.json` under `tasks.build.env` as a global dependency for the build task

Applied to files:

  • turbo.json
  • 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 turbo.json : Add environment variables to `turbo.json` under `tasks.build.env` array to declare build-time dependencies

Applied to files:

  • turbo.json
  • apps/web/env.ts
📚 Learning: 2025-11-25T14:36:18.416Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.416Z
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:

  • turbo.json
  • apps/web/env.ts
  • apps/web/.env.example
📚 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:

  • turbo.json
  • apps/web/env.ts
  • apps/web/.env.example
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx
📚 Learning: 2025-11-25T14:36:18.416Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.416Z
Learning: Applies to apps/web/**/*NEXT_PUBLIC_* : Prefix client-side environment variables with `NEXT_PUBLIC_`

Applied to files:

  • turbo.json
  • apps/web/env.ts
  • apps/web/.env.example
📚 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:

  • turbo.json
  • apps/web/env.ts
  • apps/web/.env.example
📚 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:

  • turbo.json
  • apps/web/env.ts
  • apps/web/.env.example
📚 Learning: 2025-11-25T14:42:08.869Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-11-25T14:42:08.869Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't hardcode sensitive data like API keys and tokens

Applied to files:

  • turbo.json
  • 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
  • apps/web/.env.example
📚 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
  • apps/web/.env.example
📚 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
  • apps/web/.env.example
📚 Learning: 2025-11-25T14:38:32.328Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:32.328Z
Learning: Applies to apps/web/hooks/useFeatureFlags.ts : Feature flag hooks should be defined in `apps/web/hooks/useFeatureFlags.ts` with two patterns: boolean flags using `useFeatureFlagEnabled("key")` and variant flags using `useFeatureFlagVariantKey("key")` with type casting

Applied to files:

  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/components/SideNav.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-11-25T14:38:27.988Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:27.988Z
Learning: Applies to apps/web/hooks/useFeatureFlags.ts : All feature flag hooks should be defined in `apps/web/hooks/useFeatureFlags.ts`

Applied to files:

  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/components/SideNav.tsx
📚 Learning: 2025-11-25T14:38:27.988Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:27.988Z
Learning: Applies to apps/web/hooks/useFeatureFlags.ts : For early access features, create boolean flag hooks using `useFeatureFlagEnabled` with the pattern `export function use[FeatureName]Enabled()`

Applied to files:

  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/components/SideNav.tsx
📚 Learning: 2025-11-25T14:38:27.988Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:27.988Z
Learning: Applies to apps/web/hooks/useFeatureFlags.ts : Use `use[FeatureName]Enabled` naming convention for boolean feature flag hooks and `use[FeatureName]Variant` for A/B test variant hooks

Applied to files:

  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/components/SideNav.tsx
📚 Learning: 2025-11-25T14:38:32.328Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:32.328Z
Learning: Applies to **/*.{ts,tsx} : For early access feature flags, create hooks using the naming convention `use[FeatureName]Enabled` that return a boolean from `useFeatureFlagEnabled("flag-key")`

Applied to files:

  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/components/SideNav.tsx
📚 Learning: 2025-11-25T14:38:32.328Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:32.328Z
Learning: Centralize all feature flag hooks in `apps/web/hooks/useFeatureFlags.ts` rather than scattering them across multiple files

Applied to files:

  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/components/SideNav.tsx
📚 Learning: 2025-11-25T14:38:32.328Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:32.328Z
Learning: Applies to **/*.{ts,tsx} : For A/B test variant flags, create hooks using the naming convention `use[FeatureName]Variant` that define variant types, use `useFeatureFlagVariantKey()` with type casting, and provide a default "control" fallback

Applied to files:

  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/components/SideNav.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-11-25T14:38:27.988Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:27.988Z
Learning: Applies to apps/web/hooks/useFeatureFlags.ts : Use kebab-case for feature flag keys (e.g., `inbox-cleaner`, `pricing-options-2`)

Applied to files:

  • apps/web/hooks/useFeatureFlags.ts
  • apps/web/components/SideNav.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
📚 Learning: 2025-11-25T14:38:27.988Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:27.988Z
Learning: Applies to apps/web/hooks/useFeatureFlags.ts : For A/B test variants, create hooks using `useFeatureFlagVariantKey` with the pattern `export function use[FeatureName]Variant()` and always provide a default fallback value

Applied to files:

  • apps/web/hooks/useFeatureFlags.ts
📚 Learning: 2025-11-25T14:38:27.988Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:27.988Z
Learning: Applies to apps/web/hooks/useFeatureFlags.ts : Always define explicit types for variant flags and provide a default/control fallback value

Applied to files:

  • apps/web/hooks/useFeatureFlags.ts
📚 Learning: 2025-11-25T14:38:32.328Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/posthog-feature-flags.mdc:0-0
Timestamp: 2025-11-25T14:38:32.328Z
Learning: Applies to **/*.{ts,tsx} : Use kebab-case for PostHog feature flag keys (e.g., `inbox-cleaner`, `pricing-options-2`)

Applied to files:

  • apps/web/hooks/useFeatureFlags.ts
📚 Learning: 2025-11-25T14:36:18.416Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.416Z
Learning: Applies to apps/web/**/*.tsx : Use shadcn/ui components when available

Applied to files:

  • apps/web/components/SideNav.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} : Use the `LoadingContent` component to handle loading states

Applied to files:

  • apps/web/components/SideNav.tsx
📚 Learning: 2025-11-25T14:36:18.416Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.416Z
Learning: Applies to apps/web/**/*.tsx : Use LoadingContent component for async data with loading and error states

Applied to files:

  • apps/web/components/SideNav.tsx
📚 Learning: 2025-11-25T14:40:15.063Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ui-components.mdc:0-0
Timestamp: 2025-11-25T14:40:15.063Z
Learning: Applies to **/*.tsx : Use the `LoadingContent` component to handle loading states instead of manual loading state management

Applied to files:

  • apps/web/components/SideNav.tsx
📚 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/**/*.tsx : Use `LoadingContent` component to consistently handle loading and error states, passing `loading`, `error`, and `children` props

Applied to files:

  • apps/web/components/SideNav.tsx
📚 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:

  • apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
  • apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.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]/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 .env.example : Add new environment variables to `.env.example` with example values

Applied to files:

  • apps/web/.env.example
📚 Learning: 2025-07-19T15:06:43.730Z
Learnt from: garnertb
Repo: elie222/inbox-zero PR: 580
File: apps/web/.env.example:4-7
Timestamp: 2025-07-19T15:06:43.730Z
Learning: In apps/web/.env.example, boolean environment variables follow an unquoted convention (e.g., LOG_ZOD_ERRORS=true, AUTH_TRUST_HOST=true). Logical grouping of related variables (like auth variables together) is preferred over strict alphabetical ordering for better developer experience.

Applied to files:

  • apps/web/.env.example
🧬 Code graph analysis (5)
apps/web/components/SideNavMenu.tsx (1)
apps/web/components/new-landing/common/Badge.tsx (1)
  • Badge (24-99)
apps/web/hooks/useFeatureFlags.ts (1)
apps/web/env.ts (1)
  • env (17-255)
apps/web/components/SideNav.tsx (1)
apps/web/hooks/useFeatureFlags.ts (3)
  • useCleanerEnabled (7-9)
  • useMeetingBriefsEnabled (11-13)
  • useIntegrationsEnabled (15-17)
apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx (2)
apps/web/env.ts (1)
  • env (17-255)
apps/web/components/Toggle.tsx (1)
  • Toggle (18-50)
apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx (2)
apps/web/env.ts (1)
  • env (17-255)
apps/web/app/(app)/[emailAccountId]/assistant/settings/DigestSetting.tsx (1)
  • DigestSetting (15-42)
🪛 dotenv-linter (4.0.0)
apps/web/.env.example

[warning] 143-143: [EndingBlankLine] No blank line at the end of the file

(EndingBlankLine)

⏰ 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: cubic · AI code reviewer
  • GitHub Check: test
🔇 Additional comments (15)
version.txt (1)

1-1: LGTM!

Version bump is appropriate for this feature flag release.

turbo.json (1)

131-135: LGTM!

All new environment variables correctly added to the build configuration per coding guidelines.

apps/web/env.ts (2)

190-192: LGTM!

Environment variables correctly defined with proper NEXT_PUBLIC_ prefix, Zod validation, and optional boolean types per coding guidelines.


249-253: LGTM!

Runtime environment mappings correctly added for all three new feature flags per coding guidelines.

apps/web/app/(app)/[emailAccountId]/assistant/settings/SettingsTab.tsx (2)

10-10: LGTM!

Proper import of environment configuration for feature flag usage.


20-20: LGTM!

Digest setting correctly gated behind the feature flag using idiomatic React conditional rendering.

apps/web/components/SideNavMenu.tsx (2)

10-10: Verify Badge variant support.

Confirm that the Badge component from @/components/ui/badge supports the "secondary" variant used on line 45. Based on shadcn/ui conventions this should be fine, but explicit verification would ensure no runtime issues.


20-20: LGTM with verification pending.

Beta badge implementation follows good practices. The optional beta property on NavItem and conditional rendering logic are well-structured.

Also applies to: 44-48

apps/web/hooks/useFeatureFlags.ts (1)

5-5: Verify intentional shift from runtime to build-time feature flags.

The useMeetingBriefsEnabled hook has been changed from reading a PostHog feature flag (runtime/dynamic) to reading an environment variable (build-time/static). This is a significant behavioral change:

  • Before: Feature could be toggled remotely via PostHog without redeployment
  • After: Feature requires rebuild and redeployment to toggle

The same limitation applies to the new useIntegrationsEnabled hook. If this shift from dynamic to static feature flags is intentional (perhaps for simplification or to reduce PostHog dependencies), this is fine. However, if runtime toggleability is desired, consider keeping the PostHog integration.

Based on learnings, the hooks follow the correct naming convention use[FeatureName]Enabled.

Also applies to: 11-17

apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx (2)

55-55: LGTM!

The environment import follows the established pattern for accessing client-side feature flags.


497-514: LGTM!

The digest UI is properly gated behind the environment-based feature flag. The implementation correctly wraps both the Toggle component and its TooltipExplanation, ensuring the entire feature is hidden when disabled.

Based on learnings, this follows the established pattern for adding environment variables to control feature visibility.

apps/web/components/SideNav.tsx (4)

31-31: LGTM!

The imports are correct and follow established patterns. The useIntegrationsEnabled hook follows the naming convention specified in the learnings for environment-based feature flags.

Also applies to: 56-56


82-82: LGTM!

The hook usage follows the established pattern for environment-based feature flags, consistent with the existing useMeetingBriefsEnabled usage above it.


118-127: LGTM!

The conditional rendering of the Integrations nav item follows the established pattern used for Meeting Briefs below. The use of the spread operator with a conditional array is clean and idiomatic.


139-139: LGTM!

The useMemo dependency array is correctly updated to include showIntegrations, which is used in the memoized computation. This ensures the navigation items update properly when the feature flag changes.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 10 files

Prompt for AI agents (all 3 issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="apps/web/env.ts">

<violation number="1" location="apps/web/env.ts:190">
P2: Feature flag missing default value. Per project conventions, feature flags should use `.default(false)` to avoid `undefined` values in boolean checks. Other similar flags like `NEXT_PUBLIC_CONTACTS_ENABLED` follow this pattern.</violation>

<violation number="2" location="apps/web/env.ts:191">
P2: Feature flag missing default value. Per project conventions, feature flags should use `.default(false)` to avoid `undefined` values in boolean checks.</violation>

<violation number="3" location="apps/web/env.ts:192">
P2: Feature flag missing default value. Per project conventions, feature flags should use `.default(false)` to avoid `undefined` values in boolean checks.</violation>
</file>

Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR

NEXT_PUBLIC_BYPASS_PREMIUM_CHECKS: z.coerce.boolean().optional(),
NEXT_PUBLIC_DIGEST_ENABLED: z.coerce.boolean().optional(),
NEXT_PUBLIC_MEETING_BRIEFS_ENABLED: z.coerce.boolean().optional(),
NEXT_PUBLIC_INTEGRATIONS_ENABLED: z.coerce.boolean().optional(),
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Dec 16, 2025

Choose a reason for hiding this comment

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

P2: Feature flag missing default value. Per project conventions, feature flags should use .default(false) to avoid undefined values in boolean checks.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/web/env.ts, line 192:

<comment>Feature flag missing default value. Per project conventions, feature flags should use `.default(false)` to avoid `undefined` values in boolean checks.</comment>

<file context>
@@ -187,6 +187,9 @@ export const env = createEnv({
     NEXT_PUBLIC_BYPASS_PREMIUM_CHECKS: z.coerce.boolean().optional(),
+    NEXT_PUBLIC_DIGEST_ENABLED: z.coerce.boolean().optional(),
+    NEXT_PUBLIC_MEETING_BRIEFS_ENABLED: z.coerce.boolean().optional(),
+    NEXT_PUBLIC_INTEGRATIONS_ENABLED: z.coerce.boolean().optional(),
   },
   // For Next.js &gt;= 13.4.4, you only need to destructure client variables:
</file context>
Suggested change
NEXT_PUBLIC_INTEGRATIONS_ENABLED: z.coerce.boolean().optional(),
NEXT_PUBLIC_INTEGRATIONS_ENABLED: z.coerce.boolean().optional().default(false),
Fix with Cubic

NEXT_PUBLIC_USE_AEONIK_FONT: z.coerce.boolean().optional().default(false),
NEXT_PUBLIC_BYPASS_PREMIUM_CHECKS: z.coerce.boolean().optional(),
NEXT_PUBLIC_DIGEST_ENABLED: z.coerce.boolean().optional(),
NEXT_PUBLIC_MEETING_BRIEFS_ENABLED: z.coerce.boolean().optional(),
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Dec 16, 2025

Choose a reason for hiding this comment

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

P2: Feature flag missing default value. Per project conventions, feature flags should use .default(false) to avoid undefined values in boolean checks.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/web/env.ts, line 191:

<comment>Feature flag missing default value. Per project conventions, feature flags should use `.default(false)` to avoid `undefined` values in boolean checks.</comment>

<file context>
@@ -187,6 +187,9 @@ export const env = createEnv({
     NEXT_PUBLIC_USE_AEONIK_FONT: z.coerce.boolean().optional().default(false),
     NEXT_PUBLIC_BYPASS_PREMIUM_CHECKS: z.coerce.boolean().optional(),
+    NEXT_PUBLIC_DIGEST_ENABLED: z.coerce.boolean().optional(),
+    NEXT_PUBLIC_MEETING_BRIEFS_ENABLED: z.coerce.boolean().optional(),
+    NEXT_PUBLIC_INTEGRATIONS_ENABLED: z.coerce.boolean().optional(),
   },
</file context>
Suggested change
NEXT_PUBLIC_MEETING_BRIEFS_ENABLED: z.coerce.boolean().optional(),
NEXT_PUBLIC_MEETING_BRIEFS_ENABLED: z.coerce.boolean().optional().default(false),
Fix with Cubic

.default(false),
NEXT_PUBLIC_USE_AEONIK_FONT: z.coerce.boolean().optional().default(false),
NEXT_PUBLIC_BYPASS_PREMIUM_CHECKS: z.coerce.boolean().optional(),
NEXT_PUBLIC_DIGEST_ENABLED: z.coerce.boolean().optional(),
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Dec 16, 2025

Choose a reason for hiding this comment

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

P2: Feature flag missing default value. Per project conventions, feature flags should use .default(false) to avoid undefined values in boolean checks. Other similar flags like NEXT_PUBLIC_CONTACTS_ENABLED follow this pattern.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/web/env.ts, line 190:

<comment>Feature flag missing default value. Per project conventions, feature flags should use `.default(false)` to avoid `undefined` values in boolean checks. Other similar flags like `NEXT_PUBLIC_CONTACTS_ENABLED` follow this pattern.</comment>

<file context>
@@ -187,6 +187,9 @@ export const env = createEnv({
       .default(false),
     NEXT_PUBLIC_USE_AEONIK_FONT: z.coerce.boolean().optional().default(false),
     NEXT_PUBLIC_BYPASS_PREMIUM_CHECKS: z.coerce.boolean().optional(),
+    NEXT_PUBLIC_DIGEST_ENABLED: z.coerce.boolean().optional(),
+    NEXT_PUBLIC_MEETING_BRIEFS_ENABLED: z.coerce.boolean().optional(),
+    NEXT_PUBLIC_INTEGRATIONS_ENABLED: z.coerce.boolean().optional(),
</file context>
Suggested change
NEXT_PUBLIC_DIGEST_ENABLED: z.coerce.boolean().optional(),
NEXT_PUBLIC_DIGEST_ENABLED: z.coerce.boolean().optional().default(false),
Fix with Cubic

@elie222 elie222 merged commit 1a0dca3 into main Dec 16, 2025
21 checks passed
@elie222 elie222 deleted the feat/enable-meeting-briefs branch December 16, 2025 12:41
@coderabbitai coderabbitai bot mentioned this pull request Dec 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments