Skip to content

Better env docs#1011

Merged
elie222 merged 10 commits intomainfrom
chore/self-host-docs
Nov 25, 2025
Merged

Better env docs#1011
elie222 merged 10 commits intomainfrom
chore/self-host-docs

Conversation

@elie222
Copy link
Owner

@elie222 elie222 commented Nov 25, 2025

Document environment variables and switch LLM provider defaults while adding Bedrock as a distinct provider in apps/web/utils/llms/model.selectModel and apps/web/utils/llms/config

Adds a new Environment Variables Reference and updates README and hosting docs. Refactors LLM selection by introducing Provider.BEDROCK, removing model constants, and inlining default models; Anthropic now defaults to claude-sonnet-4-5-20250929 and Bedrock uses global.anthropic.claude-sonnet-4-5-20250929-v1:0. Removes NEXT_PUBLIC_BEDROCK_SONNET_MODEL from env validation and pipeline config. Updates tests to use string model names and adds cost entries for new models.

📍Where to Start

Start with LLM selection logic in selectModel and provider/API key handling in apps/web/utils/llms/model.ts, then review provider constants in apps/web/utils/llms/config.ts and env schema changes in apps/web/env.ts.


📊 Macroscope summarized aaec62b. 5 files reviewed, 6 issues evaluated, 6 issues filtered, 0 comments posted

🗂️ Filtered Issues

apps/unsubscriber/src/llm.ts — 0 comments posted, 1 evaluated, 1 filtered
  • line 15: The Anthropic model identifier passed to anthropic() is likely invalid: "claude-sonnet-4-5-20250929". Anthropic model IDs follow patterns like "claude-3-7-sonnet-20250219". Using a non-existent/incorrect model ID will cause runtime failures when the model is used (either immediately if validated by the SDK or on first request). This was introduced by the change in the diff replacing the previous valid-looking ID. [ Low confidence ]
apps/web/env.ts — 0 comments posted, 3 evaluated, 3 filtered
  • line 128: Contract change: NEXT_PUBLIC_BEDROCK_SONNET_MODEL was removed from the client schema and from experimental__runtimeEnv. Any code that previously read env.NEXT_PUBLIC_BEDROCK_SONNET_MODEL in the client, or expected it to be exposed to the browser, will now see it as missing/undefined and may crash or change behavior. If this removal is not intentional, restore it or migrate all usages before removal. [ Low confidence ]
  • line 145: NEXT_PUBLIC_FREE_UNSUBSCRIBE_CREDITS is defined as z.number().default(5) in the client schema (line 145), but values coming from process.env (wired via experimental__runtimeEnv) are strings. If the env var is set (e.g., "5"), Zod will fail parsing because it's a string, causing a runtime config validation error. Use z.coerce.number() to accept numeric strings. [ Out of scope ]
  • line 187: NEXT_PUBLIC_BEDROCK_SONNET_MODEL was also removed from experimental__runtimeEnv mapping. Even if defined on the process env, it will no longer be exposed to the client bundle, breaking reads in browser code. Ensure all client usages are removed or migrated. [ Already posted ]
apps/web/utils/llms/model.ts — 0 comments posted, 2 evaluated, 2 filtered
  • line 151: In the Bedrock branch of selectModel, env.BEDROCK_ACCESS_KEY! and env.BEDROCK_SECRET_KEY! use non‑null assertions without any guard ensuring these env vars are set. If DEFAULT_LLM_PROVIDER (or a user choice) is "bedrock" but the credentials are unset, this path will still be taken and createAmazonBedrock will receive undefined credentials via the async credentialProvider, causing runtime failures later. Add a concrete guard (or fallback) before constructing the Bedrock client, or reject Bedrock as default when credentials are absent. [ Already posted ]
  • line 326: getProviderApiKey returns the placeholder string "bedrock-credentials" for Provider.BEDROCK when creds exist. This value is passed to selectModel as aiApiKey, and subsequently to getBackupModel(aiApiKey), which disables the backup model whenever a truthy userApiKey is present. This incorrectly disables backup models for Bedrock selections even when no user-supplied API key is used, contradicting the intent noted in getBackupModel (disable only when the user is using their own API key). Consider returning undefined here and letting the Bedrock branch infer credentials from env, or change the backup check to differentiate user keys from provider/env credentials. [ Low confidence ]

Summary by CodeRabbit

  • Documentation

    • Added a comprehensive Environment Variables reference for self-hosting; updated hosting docs and clarified domain deployment notes.
    • Reworked example environment file with a provider-selection template and secret-generation guidance.
  • New Features

    • Added AWS Bedrock as a selectable LLM provider and updated default model selections across the web app.
    • Extended cost/pricing coverage for new model identifiers.
  • Chores

    • Version bumped to v2.20.23
  • Breaking Changes

    • Removed a previously exposed public client environment variable (update env/config as needed).

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

@vercel
Copy link

vercel bot commented Nov 25, 2025

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

Project Deployment Preview Updated (UTC)
inbox-zero Ready Ready Preview Nov 25, 2025 9:04pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 25, 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 a comprehensive environment-variables reference and updates hosting docs; removes NEXT_PUBLIC_BEDROCK_SONNET_MODEL from client env surface and build/env lists; replaces Model constants with string literals, adds BEDROCK provider handling and Anthropic model updates across model selection, tests, and usage cost mapping; updates .env.example and bumps version.

Changes

Cohort / File(s) Summary
New reference file
docs/hosting/environment-variables.md
Added a complete Environment Variables reference for self-hosting: quick start, secret generation examples, categorized variables table (Core, Encryption, OAuth, PubSub, Redis, LLM config, API keys, AWS Bedrock, Ollama, Background Jobs, Sentry, Resend, Admin & Access, Feature Flags, Debugging), setup guides and notes.
Docs — links & notes
README.md, docs/hosting/docker.md, docs/hosting/aws-copilot.md
README.md: added link to the new Environment Variables Guide. docker.md: updated Configure link to point to the new reference. aws-copilot.md: added note clarifying --domain requires Route53-hosted domains and to omit/adjust the flag/manifest if domain is managed elsewhere.
Env surface — removed variable
apps/web/env.ts, turbo.json
Removed NEXT_PUBLIC_BEDROCK_SONNET_MODEL from the client env schema and from the build task env list; removed its runtime mapping.
LLM config — provider enum change
apps/web/utils/llms/config.ts
Removed exported Model constant/enum and added BEDROCK to the Provider export; providerOptions otherwise unchanged.
Model selection & provider logic
apps/web/utils/llms/model.ts, apps/unsubscriber/src/llm.ts
Replaced enum-based model resolution with hard-coded model name strings; added BEDROCK provider handling (constructs Bedrock model with regional creds + backup); updated Anthropic default model to claude-sonnet-4-5-20250929 and aligned other provider defaults. apps/unsubscriber Anthropic identifier updated.
Tests — adapt to literals & env changes
apps/web/utils/llms/model.test.ts
Removed imports of Model, switched expectations to explicit model-name strings, and removed NEXT_PUBLIC_BEDROCK_SONNET_MODEL from mocked env.
Usage — cost mapping additions
apps/web/utils/usage.ts
Added new cost mapping entries and introduced a haiku cost tier for newly referenced Anthropic models (and sonnet entries).
Env example — provider template
apps/web/.env.example
Replaced flat LLM config with a commented provider-selection template (uncomment one block), added MICROSOFT_WEBHOOK_CLIENT_STATE comment placeholder, and removed prior flat GROQ/OPENROUTER entries.
Version bump
version.txt
Bumped version from v2.20.22 to v2.20.23.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant UI as Web UI
  participant ModelLogic as Model selection logic
  participant Env as Env/runtime
  participant Provider as LLM Provider

  Note over ModelLogic,Env: `NEXT_PUBLIC_BEDROCK_SONNET_MODEL` removed from env surface
  UI->>ModelLogic: request default model
  ModelLogic->>Env: read provider settings & envs
  Env-->>ModelLogic: returns available envs (without bedrock sonnet var)
  alt provider == BEDROCK
    ModelLogic->>Provider: build Bedrock model (regional creds + backup)
  else other providers
    ModelLogic->>Provider: select model (uses hard-coded string literals)
  end
  Provider-->>ModelLogic: selected model identifier
  ModelLogic-->>UI: model chosen for requests
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas needing extra attention:
    • Removal of exported Model in apps/web/utils/llms/config.ts and all call sites/tests updated to literals.
    • BEDROCK addition: ensure apps/web/utils/llms/model.ts Bedrock construction logic and credential wiring are correct.
    • Removal of NEXT_PUBLIC_BEDROCK_SONNET_MODEL from apps/web/env.ts and turbo.json — verify no remaining references.
    • Cost mapping additions in apps/web/utils/usage.ts and test adjustments in apps/web/utils/llms/model.test.ts.
    • Large new docs file for accuracy/consistency with existing hosting instructions.

Possibly related PRs

Poem

🐰 I hopped through docs and code tonight,
Tuned models to strings and set Bedrock right,
A guide for envs now grows by the burrow,
Tests updated, versions nudged — soft furrow,
A rabbit's quick commit, neat and light.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
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.
Title check ❓ Inconclusive The title 'Better env docs' is vague and generic, failing to convey the substantive changes in this pull request such as adding Bedrock as a provider, updating model identifiers, or restructuring environment configuration. Consider a more descriptive title like 'Add Bedrock provider support and improve environment variables documentation' to clearly communicate the main changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/self-host-docs

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: 1

📜 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 d666fb2 and 43ee688.

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

📄 CodeRabbit inference engine (.cursor/rules/task-list.mdc)

*.md: Create task lists in markdown files named TASKS.md or with a descriptive feature-specific name (e.g., ASSISTANT_CHAT.md) in the project root to track project progress
Structure task list markdown files with sections: Feature Name Implementation (title), description, Completed Tasks, In Progress Tasks, Future Tasks, Implementation Plan, and Relevant Files subsections
Update task list markdown files by marking tasks as completed with [x], adding new identified tasks, and moving tasks between Completed/In Progress/Future sections as appropriate
Keep the 'Relevant Files' section in task list markdown files updated with file paths that have been created or modified, brief descriptions of each file's purpose, and status indicators (e.g., ✅) for completed components

Files:

  • README.md
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
Learning: Applies to .env.example : Add new environment variables to `.env.example` with example values
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 .env.example : Add environment variables to `.env.example` with example values in the format `VARIABLE_NAME=value_example`
📚 Learning: 2025-11-25T14:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
Learning: Applies to .env.example : Add new environment variables to `.env.example` with example values

Applied to files:

  • docs/hosting/environment-variables.md
  • docs/hosting/docker.md
  • README.md
📚 Learning: 2025-11-25T14:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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
  • docs/hosting/docker.md
  • README.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
  • docs/hosting/docker.md
  • README.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 .env.example : Add environment variables to `.env.example` with example values in the format `VARIABLE_NAME=value_example`

Applied to files:

  • docs/hosting/environment-variables.md
  • docs/hosting/docker.md
  • README.md
📚 Learning: 2025-11-25T14:39:04.892Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security-audit.mdc:0-0
Timestamp: 2025-11-25T14:39:04.892Z
Learning: No hardcoded secrets in code; all secrets must be stored in environment variables (e.g., CRON_SECRET)

Applied to files:

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

  • docs/hosting/environment-variables.md
  • README.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 : Define environment variables in `apps/web/env.ts` using Zod schema validation, organizing them into `server` and `client` sections

Applied to files:

  • docs/hosting/environment-variables.md
  • docs/hosting/docker.md
  • README.md
📚 Learning: 2025-11-25T14:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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
  • docs/hosting/docker.md
  • README.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
  • docs/hosting/docker.md
  • README.md
📚 Learning: 2025-11-25T14:36:18.404Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.404Z
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.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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
  • docs/hosting/docker.md
  • README.md
⏰ 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: Jit Security
  • GitHub Check: test
🔇 Additional comments (7)
version.txt (1)

1-1: Version bump looks good.

The patch version increment is appropriate for documentation updates.

docs/hosting/docker.md (1)

49-49: Link update to new environment variables reference is appropriate.

The Configure section now directs users to the comprehensive environment variables guide, improving discoverability.

README.md (1)

143-143: Reference link placement is helpful and logical.

Linking to the comprehensive environment variables guide from this section reduces redundancy and improves user experience by providing a single source of truth.

docs/hosting/environment-variables.md (4)

1-40: Excellent documentation structure and organization.

The environment variables reference is well-organized with logical grouping by category (following learnings about preferring logical grouping over alphabetical order), clear descriptions, and practical examples. The Quick Start and secret generation sections provide immediate value.


45-48: Good use of asterisk notation for conditional requirements.

The Redis variables are correctly marked as "No*" with a note explaining they're required only if not using Docker Compose. This matches the guidance in the README and aligns with learnings about conditional environment variable requirements.


113-116: Helpful operational notes for self-hosted deployments.

The notes section provides practical guidance for Ollama Docker networking and Redis requirements, which directly addresses common self-hosting deployment issues.


104-111: All anchor links resolve correctly—no action needed.

Verification confirms that all four anchor links in the setup guides section match their corresponding README section headers exactly. The markdown anchor format (lowercase, hyphens replacing spaces) is correctly applied throughout.

Copy link

@jit-ci jit-ci bot left a comment

Choose a reason for hiding this comment

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

❌ The following Jit checks failed to run:

  • secret-detection

#jit_bypass_commit in this PR to bypass, Jit Admin privileges required.

More info in the Jit platform.

Copy link

@jit-ci jit-ci bot left a comment

Choose a reason for hiding this comment

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

❌ The following Jit checks failed to run:

  • secret-detection

#jit_bypass_commit in this PR to bypass, Jit Admin privileges required.

More info in the Jit platform.

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.

1 issue found across 5 files

Prompt for AI agents (all 1 issues)

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


<file name="docs/hosting/environment-variables.md">

<violation number="1" location="docs/hosting/environment-variables.md:29">
Document states AUTH_SECRET is optional, but the build fails unless either AUTH_SECRET or NEXTAUTH_SECRET is provided.</violation>
</file>

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

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

♻️ Duplicate comments (2)
docs/hosting/environment-variables.md (2)

29-30: Clarify AUTH_SECRET / NEXTAUTH_SECRET requirement semantics

These rows mark both AUTH_SECRET and NEXTAUTH_SECRET as “No” in the Required column, but in practice at least one of them must be provided for NextAuth to run correctly. Consider updating the description or Required column to something like “No (but one of AUTH_SECRET or NEXTAUTH_SECRET is required)” to avoid confusion. Please confirm this against the actual NextAuth/Inbox Zero auth behavior before changing the docs.


69-76: Sync NEXT_PUBLIC_BEDROCK_SONNET_MODEL default with code

The table still shows the old default us.anthropic.claude-3-7-sonnet-20250219-v1:0, but apps/web/env.ts now defaults NEXT_PUBLIC_BEDROCK_SONNET_MODEL to global.anthropic.claude-sonnet-4-5-20250929-v1:0, and the LLM config/usage paths assume that 4.5 ID. Update this default here (and any related text) so the docs match the actual runtime default. Based on learnings, env.ts should be the source of truth for these values.

🧹 Nitpick comments (2)
docs/hosting/environment-variables.md (2)

69-69: Use more descriptive link text than “here”

The Bedrock row uses “See more here”. For accessibility and to satisfy markdownlint (MD059), replace “here” with descriptive text like [Amazon Bedrock provider docs] or similar.


104-112: Double‑check README anchor targets used in Setup Guides

The links to ../../README.md#updating-env-file-with-google-oauth-credentials (and similar anchors) assume specific heading slugs in README.md. Since we don’t see README in this diff, please verify that those sections and IDs actually exist or adjust the anchors accordingly so these links don’t 404 in rendered docs.

📜 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 542d3cb and 603ee58.

📒 Files selected for processing (5)
  • apps/web/env.ts (1 hunks)
  • apps/web/utils/llms/config.ts (1 hunks)
  • apps/web/utils/llms/model.ts (1 hunks)
  • apps/web/utils/usage.ts (1 hunks)
  • docs/hosting/environment-variables.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
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/utils/usage.ts
  • apps/web/env.ts
  • apps/web/utils/llms/config.ts
  • apps/web/utils/llms/model.ts
**/*.{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/utils/usage.ts
  • apps/web/env.ts
  • apps/web/utils/llms/config.ts
  • apps/web/utils/llms/model.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/usage.ts
  • apps/web/utils/llms/config.ts
  • apps/web/utils/llms/model.ts
**/*.{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/utils/usage.ts
  • apps/web/env.ts
  • apps/web/utils/llms/config.ts
  • apps/web/utils/llms/model.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/utils/usage.ts
  • apps/web/env.ts
  • apps/web/utils/llms/config.ts
  • apps/web/utils/llms/model.ts
**/*.{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/utils/usage.ts
  • apps/web/env.ts
  • apps/web/utils/llms/config.ts
  • apps/web/utils/llms/model.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/utils/usage.ts
  • apps/web/env.ts
  • apps/web/utils/llms/config.ts
  • apps/web/utils/llms/model.ts
**/*.{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/utils/usage.ts
  • apps/web/env.ts
  • apps/web/utils/llms/config.ts
  • apps/web/utils/llms/model.ts
!(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/utils/usage.ts
  • apps/web/env.ts
  • apps/web/utils/llms/config.ts
  • apps/web/utils/llms/model.ts
  • docs/hosting/environment-variables.md
**/*.{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/utils/usage.ts
  • apps/web/env.ts
  • apps/web/utils/llms/config.ts
  • apps/web/utils/llms/model.ts
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.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
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, and apps/web/__tests__/ for LLM-specific tests

Files:

  • apps/web/utils/llms/config.ts
  • apps/web/utils/llms/model.ts
apps/web/utils/llms/{index,model}.ts

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

Core LLM functionality must be defined in utils/llms/index.ts, model definitions and configurations in utils/llms/model.ts, and usage tracking in utils/usage.ts

Files:

  • apps/web/utils/llms/model.ts
🧠 Learnings (16)
📓 Common learnings
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
Learning: Applies to .env.example : Add new environment variables to `.env.example` with example values
📚 Learning: 2025-11-25T14:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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/env.ts
  • apps/web/utils/llms/config.ts
  • 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:

  • apps/web/env.ts
  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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
  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:36:18.404Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.404Z
Learning: Applies to apps/web/**/*NEXT_PUBLIC_* : Prefix client-side environment variables with `NEXT_PUBLIC_`

Applied to files:

  • apps/web/env.ts
  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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
  • 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 : 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
  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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
  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:38:07.585Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.585Z
Learning: Applies to apps/web/utils/llms/{index,model}.ts : Core LLM functionality must be defined in `utils/llms/index.ts`, model definitions and configurations in `utils/llms/model.ts`, and usage tracking in `utils/usage.ts`

Applied to files:

  • apps/web/utils/llms/config.ts
  • apps/web/utils/llms/model.ts
📚 Learning: 2025-11-25T14:38:07.585Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.585Z
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/llms/model.ts
📚 Learning: 2025-11-25T14:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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:39:04.892Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security-audit.mdc:0-0
Timestamp: 2025-11-25T14:39:04.892Z
Learning: No hardcoded secrets in code; all secrets must be stored in environment variables (e.g., CRON_SECRET)

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
📚 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: Ensure `CRON_SECRET` environment variable is configured with a strong random secret - never use predictable secrets like 'secret', 'password', 'cron', or short/simple strings

Applied to files:

  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:39:27.901Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security.mdc:0-0
Timestamp: 2025-11-25T14:39:27.901Z
Learning: Ensure `CRON_SECRET` environment variable is properly configured with a secure random secret, never using predictable values like 'secret', 'password', 'cron', or short/simple strings

Applied to files:

  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:42:08.846Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-11-25T14:42:08.846Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't hardcode sensitive data like API keys and tokens

Applied to files:

  • docs/hosting/environment-variables.md
🧬 Code graph analysis (1)
apps/web/utils/llms/model.ts (1)
apps/web/utils/llms/config.ts (1)
  • Model (17-38)
🪛 markdownlint-cli2 (0.18.1)
docs/hosting/environment-variables.md

69-69: Link text should be descriptive

(MD059, descriptive-link-text)

⏰ 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). (5)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: Jit Security
  • GitHub Check: Review for correctness
  • GitHub Check: test
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (4)
apps/web/utils/usage.ts (1)

90-100: Cost map entry for global Claude Sonnet 4.5 looks consistent

Adding "global.anthropic.claude-sonnet-4-5-20250929-v1:0": sonnet aligns pricing with the existing Sonnet profile and matches the new default Bedrock model ID used elsewhere.

apps/web/env.ts (1)

176-179: Bedrock Sonnet default updated cleanly to 4.5 global model

The new default global.anthropic.claude-sonnet-4-5-20250929-v1:0 is consistent with Model.CLAUDE_4_5_SONNET_BEDROCK and the pricing map in apps/web/utils/usage.ts, so the Bedrock path will correctly prefer the 4.5 Sonnet variant by default. Based on learnings, this keeps the env schema aligned with client-side usage.

apps/web/utils/llms/model.ts (1)

143-165: Bedrock Anthropic default correctly switched to 4.5 Sonnet

Using Model.CLAUDE_4_5_SONNET_BEDROCK as the fallback when Bedrock credentials are present (and no user apiKey/model override) lines up with the new env default and pricing entry, while preserving the non‑Bedrock Anthropic 3.7 path in the else branch. The selection logic remains coherent.

apps/web/utils/llms/config.ts (1)

17-23: Model constants for Bedrock 3.7 vs 4.5 are cleanly separated

Making CLAUDE_3_7_SONNET_BEDROCK a fixed 3.7 ID and introducing CLAUDE_4_5_SONNET_BEDROCK sourced from env.NEXT_PUBLIC_BEDROCK_SONNET_MODEL gives you an explicit legacy constant and a configurable “current” default, which matches how getModel now prefers 4.5 when using Bedrock.

Copy link

@jit-ci jit-ci bot left a comment

Choose a reason for hiding this comment

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

❌ The following Jit checks failed to run:

  • secret-detection
  • static-code-analysis-js

#jit_bypass_commit in this PR to bypass, Jit Admin privileges required.

More info in the Jit platform.

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: 2

♻️ Duplicate comments (1)
docs/hosting/environment-variables.md (1)

29-30: Clarify AUTH_SECRET requirement.

Based on the past review comment, the build fails unless either AUTH_SECRET or NEXTAUTH_SECRET is provided. The current "No" marking for both variables is misleading. Update the documentation to indicate that at least one of these is required.

Consider updating the table to:

-| `AUTH_SECRET` | No | NextAuth secret (random string) | — |
-| `NEXTAUTH_SECRET` | No | Alternative to AUTH_SECRET | — |
+| `AUTH_SECRET` | Yes* | NextAuth secret (random string) (*or NEXTAUTH_SECRET) | — |
+| `NEXTAUTH_SECRET` | No | Alternative to AUTH_SECRET | — |
🧹 Nitpick comments (3)
apps/web/utils/llms/model.ts (1)

70-120: Consider centralizing default model IDs.

The default model identifiers are now hard-coded across multiple provider cases. While this works, consider extracting them to a single configuration object at the top of the file for easier maintenance and visibility.

For example:

const DEFAULT_MODELS = {
  [Provider.OPEN_AI]: "gpt-4o",
  [Provider.GOOGLE]: "gemini-2.0-flash",
  [Provider.GROQ]: "llama-3.3-70b-versatile",
  [Provider.OPENROUTER]: "anthropic/claude-sonnet-4.5",
  [Provider.AI_GATEWAY]: "google/gemini-2.5-pro",
} as const;

Then use: const modelName = aiModel || DEFAULT_MODELS[Provider.OPEN_AI];

docs/hosting/environment-variables.md (2)

69-69: Use descriptive link text for better accessibility.

Replace "here" with descriptive text that indicates what the link points to.

-| `BEDROCK_ACCESS_KEY` | No | AWS access key for Bedrock. See more [here](https://ai-sdk.dev/providers/ai-sdk-providers/amazon-bedrock). | — |
+| `BEDROCK_ACCESS_KEY` | No | AWS access key for Bedrock. See the [Amazon Bedrock setup guide](https://ai-sdk.dev/providers/ai-sdk-providers/amazon-bedrock). | — |

68-71: Consider documenting the default Bedrock model.

Since the Bedrock model ID is now hard-coded in the application (see apps/web/utils/llms/model.ts line 147), consider adding a note about which model is used by default to help users understand the behavior.

For example, add a note in the Description column:

-| `BEDROCK_REGION` | No | AWS region for Bedrock | `us-west-2` |
+| `BEDROCK_REGION` | No | AWS region for Bedrock. Default model: `global.anthropic.claude-sonnet-4-5-20250929-v1:0` | `us-west-2` |
📜 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 603ee58 and b5bc9fc.

📒 Files selected for processing (6)
  • apps/web/env.ts (0 hunks)
  • apps/web/utils/llms/config.ts (0 hunks)
  • apps/web/utils/llms/model.test.ts (4 hunks)
  • apps/web/utils/llms/model.ts (8 hunks)
  • docs/hosting/environment-variables.md (1 hunks)
  • turbo.json (0 hunks)
💤 Files with no reviewable changes (3)
  • turbo.json
  • apps/web/utils/llms/config.ts
  • apps/web/env.ts
🧰 Additional context used
📓 Path-based instructions (14)
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/utils/llms/model.test.ts
  • apps/web/utils/llms/model.ts
**/*.{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/utils/llms/model.test.ts
  • apps/web/utils/llms/model.ts
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, and apps/web/__tests__/ for LLM-specific tests

Files:

  • apps/web/utils/llms/model.test.ts
  • apps/web/utils/llms/model.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/llms/model.test.ts
  • apps/web/utils/llms/model.ts
**/*.{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/utils/llms/model.test.ts
  • apps/web/utils/llms/model.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/utils/llms/model.test.ts
  • apps/web/utils/llms/model.ts
**/*.test.{ts,tsx}

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

**/*.test.{ts,tsx}: Use vitest for testing the application
Tests should be colocated next to the tested file with .test.ts or .test.tsx extension (e.g., dir/format.ts and dir/format.test.ts)
Mock server-only using vi.mock("server-only", () => ({}))
Mock Prisma using vi.mock("@/utils/prisma") and import the mock from @/utils/__mocks__/prisma
Use vi.clearAllMocks() in beforeEach to clean up mocks between tests
Each test should be independent
Use descriptive test names
Mock external dependencies in tests
Do not mock the Logger
Avoid testing implementation details
Use test helpers getEmail, getEmailAccount, and getRule from @/__tests__/helpers for mocking emails, accounts, and rules

Files:

  • apps/web/utils/llms/model.test.ts
**/*.{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/utils/llms/model.test.ts
  • apps/web/utils/llms/model.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/utils/llms/model.test.ts
  • apps/web/utils/llms/model.ts
**/*.{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/utils/llms/model.test.ts
  • apps/web/utils/llms/model.ts
**/*.{test,spec}.{js,jsx,ts,tsx}

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

**/*.{test,spec}.{js,jsx,ts,tsx}: Don't nest describe() blocks too deeply in test files
Don't use callbacks in asynchronous tests and hooks
Don't have duplicate hooks in describe blocks
Don't use export or module.exports in test files
Don't use focused tests
Make sure the assertion function, like expect, is placed inside an it() function call
Don't use disabled tests

Files:

  • apps/web/utils/llms/model.test.ts
!(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/utils/llms/model.test.ts
  • apps/web/utils/llms/model.ts
  • docs/hosting/environment-variables.md
**/*.{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/utils/llms/model.test.ts
  • apps/web/utils/llms/model.ts
apps/web/utils/llms/{index,model}.ts

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

Core LLM functionality must be defined in utils/llms/index.ts, model definitions and configurations in utils/llms/model.ts, and usage tracking in utils/usage.ts

Files:

  • apps/web/utils/llms/model.ts
🧠 Learnings (31)
📓 Common learnings
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
Learning: Applies to .env.example : Add new environment variables to `.env.example` with example values
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.404Z
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: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.404Z
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.797Z
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/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:43.454Z
Learning: Applies to .env.example : Add environment variables to `.env.example` with example values in the format `VARIABLE_NAME=value_example`
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
Learning: Applies to turbo.json : Add new environment variables to `turbo.json` under `tasks.build.env` as a global dependency for the build task
📚 Learning: 2025-11-25T14:38:07.585Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.585Z
Learning: Applies to apps/web/utils/llms/{index,model}.ts : Core LLM functionality must be defined in `utils/llms/index.ts`, model definitions and configurations in `utils/llms/model.ts`, and usage tracking in `utils/usage.ts`

Applied to files:

  • apps/web/utils/llms/model.test.ts
  • apps/web/utils/llms/model.ts
📚 Learning: 2025-11-25T14:37:56.072Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.072Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Use vitest imports (`describe`, `expect`, `test`, `vi`, `beforeEach`) in LLM test files

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:40:00.802Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-25T14:40:00.802Z
Learning: Applies to **/*.test.{ts,tsx} : Avoid testing implementation details

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:42:08.846Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-11-25T14:42:08.846Z
Learning: Applies to **/*.{test,spec}.{js,jsx,ts,tsx} : Don't use export or module.exports in test files

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:40:00.802Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-25T14:40:00.802Z
Learning: Applies to **/__tests__/**/*.{ts,tsx} : AI tests must be placed in the `__tests__` directory and are not run by default (they use a real LLM)

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:37:56.072Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.072Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Place all LLM-related tests in `apps/web/__tests__/` directory

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:38:07.585Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.585Z
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/llms/model.test.ts
  • apps/web/utils/llms/model.ts
📚 Learning: 2025-11-25T14:38:07.585Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.585Z
Learning: Applies to apps/web/{utils/ai,utils/llms,__tests__}/**/*.ts : 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, and `apps/web/__tests__/` for LLM-specific tests

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:37:56.072Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.072Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Use `describe.runIf(isAiTest)` with environment variable `RUN_AI_TESTS === "true"` to conditionally run LLM tests

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:37:56.072Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.072Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Use `console.debug()` for outputting generated LLM content in tests, e.g., `console.debug("Generated content:\n", result.content);`

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:40:00.801Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-25T14:40:00.801Z
Learning: Applies to **/*.test.{ts,tsx} : Use `vitest` for testing the application

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:40:00.802Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-25T14:40:00.802Z
Learning: Applies to **/*.test.{ts,tsx} : Mock Prisma using `vi.mock("@/utils/prisma")` and import the mock from `@/utils/__mocks__/prisma`

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:40:00.802Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-25T14:40:00.802Z
Learning: Applies to **/*.test.{ts,tsx} : Use `vi.clearAllMocks()` in `beforeEach` to clean up mocks between tests

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:42:08.846Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-11-25T14:42:08.846Z
Learning: Applies to **/*.{test,spec}.{js,jsx,ts,tsx} : Make sure the assertion function, like expect, is placed inside an it() function call

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:37:56.072Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.072Z
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/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:37:56.072Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.072Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Mock 'server-only' module with empty object in LLM test files: `vi.mock("server-only", () => ({}))`

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:38:07.585Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.585Z
Learning: Applies to apps/web/utils/ai/**/*.ts : Use TypeScript types for all LLM function parameters and return values, and define clear interfaces for complex input/output structures

Applied to files:

  • apps/web/utils/llms/model.ts
📚 Learning: 2025-11-25T14:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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:

  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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: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:39:04.892Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security-audit.mdc:0-0
Timestamp: 2025-11-25T14:39:04.892Z
Learning: No hardcoded secrets in code; all secrets must be stored in environment variables (e.g., CRON_SECRET)

Applied to files:

  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:36:18.404Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.404Z
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: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: Ensure `CRON_SECRET` environment variable is configured with a strong random secret - never use predictable secrets like 'secret', 'password', 'cron', or short/simple strings

Applied to files:

  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:39:27.901Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security.mdc:0-0
Timestamp: 2025-11-25T14:39:27.901Z
Learning: Ensure `CRON_SECRET` environment variable is properly configured with a secure random secret, never using predictable values like 'secret', 'password', 'cron', or short/simple strings

Applied to files:

  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:42:08.846Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-11-25T14:42:08.846Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't hardcode sensitive data like API keys and tokens

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
📚 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:

  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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
🧬 Code graph analysis (1)
apps/web/utils/llms/model.test.ts (3)
apps/web/utils/llms/model.ts (1)
  • getModel (27-41)
apps/web/utils/llms/config.ts (1)
  • Provider (7-15)
apps/web/utils/llms/types.ts (1)
  • UserAIFields (3-9)
🪛 markdownlint-cli2 (0.18.1)
docs/hosting/environment-variables.md

69-69: Link text should be descriptive

(MD059, descriptive-link-text)

⏰ 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). (5)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: Jit Security
  • GitHub Check: Review for correctness
  • GitHub Check: test
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
apps/web/utils/llms/model.test.ts (1)

3-196: LGTM! Tests align with implementation changes.

The test updates correctly reflect the removal of the Model export and the shift to hard-coded string literals. The removal of NEXT_PUBLIC_BEDROCK_SONNET_MODEL from the mocked environment aligns with its removal from apps/web/env.ts. All test cases properly verify the expected model IDs for each provider.

Copy link

@jit-ci jit-ci bot left a comment

Choose a reason for hiding this comment

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

❌ Jit security check failed to run.

#jit_bypass_commit in this PR to bypass, Jit Admin privileges required.

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: 1

📜 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 b5bc9fc and 822b988.

📒 Files selected for processing (3)
  • apps/unsubscriber/src/llm.ts (1 hunks)
  • apps/web/utils/llms/model.ts (8 hunks)
  • apps/web/utils/usage.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/web/utils/usage.ts
  • apps/web/utils/llms/model.ts
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{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/unsubscriber/src/llm.ts
**/*.{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/unsubscriber/src/llm.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/unsubscriber/src/llm.ts
**/*.{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/unsubscriber/src/llm.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/unsubscriber/src/llm.ts
**/*.{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/unsubscriber/src/llm.ts
!(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/unsubscriber/src/llm.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/unsubscriber/src/llm.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
Learning: Applies to .env.example : Add new environment variables to `.env.example` with example values
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.404Z
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: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.404Z
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.797Z
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/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:43.454Z
Learning: Applies to .env.example : Add environment variables to `.env.example` with example values in the format `VARIABLE_NAME=value_example`
📚 Learning: 2025-11-25T14:38:07.585Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.585Z
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/unsubscriber/src/llm.ts
⏰ 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: Jit Security
  • GitHub Check: Review for correctness
  • GitHub Check: test
🔇 Additional comments (1)
apps/unsubscriber/src/llm.ts (1)

15-15: The model identifier is valid and supported by @ai-sdk/anthropic.

The Anthropic SDK accepts the snapshot-style model ID claude-sonnet-4-5-20250929, which is documented in Anthropic/Claude docs and SDK references. The update at line 15 is correct.

Copy link

@jit-ci jit-ci bot left a comment

Choose a reason for hiding this comment

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

❌ Jit security check failed to run.

#jit_bypass_commit in this PR to bypass, Jit Admin privileges required.

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: 3

🧹 Nitpick comments (1)
docs/hosting/environment-variables.md (1)

38-48: Clarify provider-specific default models.

Line 40's description "Provider default" is vague. Users won't know what model will actually be used if they specify a provider in DEFAULT_LLM_PROVIDER without setting DEFAULT_LLM_MODEL. Consider expanding the table or adding a note explaining the default model for each provider (especially since the PR changes Bedrock's default).

Update line 40 to be more explicit:

-| `DEFAULT_LLM_MODEL` | No | Model to use with default provider | Provider default |
+| `DEFAULT_LLM_MODEL` | No | Model to use with default provider (if not set, uses provider's default) | Provider default |

Or add a separate row documenting defaults for each provider, e.g., a note section explaining that bedrock defaults to anthropic.claude-sonnet-4-5-20250929-v1:0.

📜 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 822b988 and bad95c4.

📒 Files selected for processing (5)
  • apps/web/.env.example (1 hunks)
  • apps/web/utils/llms/config.ts (1 hunks)
  • apps/web/utils/llms/model.ts (7 hunks)
  • apps/web/utils/usage.ts (2 hunks)
  • docs/hosting/environment-variables.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/utils/llms/config.ts
🧰 Additional context used
📓 Path-based instructions (13)
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/utils/llms/model.ts
  • apps/web/utils/usage.ts
**/*.{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/utils/llms/model.ts
  • apps/web/utils/usage.ts
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, and apps/web/__tests__/ for LLM-specific tests

Files:

  • apps/web/utils/llms/model.ts
apps/web/utils/llms/{index,model}.ts

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

Core LLM functionality must be defined in utils/llms/index.ts, model definitions and configurations in utils/llms/model.ts, and usage tracking in utils/usage.ts

Files:

  • apps/web/utils/llms/model.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/llms/model.ts
  • apps/web/utils/usage.ts
**/*.{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/utils/llms/model.ts
  • apps/web/utils/usage.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/utils/llms/model.ts
  • apps/web/utils/usage.ts
**/*.{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/utils/llms/model.ts
  • apps/web/utils/usage.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/utils/llms/model.ts
  • apps/web/utils/usage.ts
**/*.{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/utils/llms/model.ts
  • apps/web/utils/usage.ts
!(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/utils/llms/model.ts
  • apps/web/utils/usage.ts
  • apps/web/.env.example
  • docs/hosting/environment-variables.md
**/*.{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/utils/llms/model.ts
  • apps/web/utils/usage.ts
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.example
🧠 Learnings (20)
📓 Common learnings
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
Learning: Applies to .env.example : Add new environment variables to `.env.example` with example values
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.404Z
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.797Z
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/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:43.454Z
Learning: Applies to .env.example : Add environment variables to `.env.example` with example values in the format `VARIABLE_NAME=value_example`
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.404Z
Learning: Applies to apps/web/**/{.env.example,env.ts,turbo.json} : Add environment variables to `.env.example`, `env.ts`, and `turbo.json`
📚 Learning: 2025-11-25T14:38:07.585Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.585Z
Learning: Applies to apps/web/utils/llms/{index,model}.ts : Core LLM functionality must be defined in `utils/llms/index.ts`, model definitions and configurations in `utils/llms/model.ts`, and usage tracking in `utils/usage.ts`

Applied to files:

  • apps/web/utils/llms/model.ts
📚 Learning: 2025-11-25T14:38:07.585Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.585Z
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/llms/model.ts
📚 Learning: 2025-11-25T14:38:07.585Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.585Z
Learning: Applies to apps/web/utils/ai/**/*.ts : Use TypeScript types for all LLM function parameters and return values, and define clear interfaces for complex input/output structures

Applied to files:

  • apps/web/utils/llms/model.ts
📚 Learning: 2025-11-25T14:38:07.585Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.585Z
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/llms/model.ts
📚 Learning: 2025-11-25T14:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
Learning: Applies to .env.example : Add new environment variables to `.env.example` with example values

Applied to files:

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

  • apps/web/.env.example
  • 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 .env.example : Add environment variables to `.env.example` with example values in the format `VARIABLE_NAME=value_example`

Applied to files:

  • apps/web/.env.example
  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:36:18.404Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.404Z
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.example
📚 Learning: 2025-11-25T14:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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: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:39:04.892Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security-audit.mdc:0-0
Timestamp: 2025-11-25T14:39:04.892Z
Learning: No hardcoded secrets in code; all secrets must be stored in environment variables (e.g., CRON_SECRET)

Applied to files:

  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:36:18.404Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.404Z
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: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: Ensure `CRON_SECRET` environment variable is configured with a strong random secret - never use predictable secrets like 'secret', 'password', 'cron', or short/simple strings

Applied to files:

  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:39:27.901Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/security.mdc:0-0
Timestamp: 2025-11-25T14:39:27.901Z
Learning: Ensure `CRON_SECRET` environment variable is properly configured with a secure random secret, never using predictable values like 'secret', 'password', 'cron', or short/simple strings

Applied to files:

  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:42:08.846Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-11-25T14:42:08.846Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't hardcode sensitive data like API keys and tokens

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 : Define environment variables in `apps/web/env.ts` using Zod schema validation, organizing them into `server` and `client` sections

Applied to files:

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

  • docs/hosting/environment-variables.md
📚 Learning: 2025-11-25T14:36:45.797Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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
🧬 Code graph analysis (1)
apps/web/utils/llms/model.ts (2)
apps/web/utils/llms/config.ts (1)
  • Provider (7-16)
apps/web/env.ts (1)
  • env (16-244)
🪛 dotenv-linter (4.0.0)
apps/web/.env.example

[warning] 21-21: [SpaceCharacter] The line has spaces around equal sign

(SpaceCharacter)


[warning] 21-21: [ValueWithoutQuotes] This value needs to be surrounded in quotes

(ValueWithoutQuotes)

🪛 markdownlint-cli2 (0.18.1)
docs/hosting/environment-variables.md

58-58: Link text should be descriptive

(MD059, descriptive-link-text)

⏰ 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: Jit Security
  • GitHub Check: Review for correctness
  • GitHub Check: test
🔇 Additional comments (11)
apps/web/utils/usage.ts (2)

48-51: LGTM!

The haiku pricing constant is correctly defined with appropriate input/output token costs for the Claude Haiku 4.5 model tier.


90-103: **Verify Bedrock model ID format.**Based on the web search results, the correct format for AWS Bedrock Claude Sonnet 4.5 global inference profile ID is indeed global.anthropic.claude-sonnet-4-5-20250929-v1:0. The past review comments flagging this as incorrect appear to be mistaken.

AWS changed the prefix rule starting with Sonnet 4.5, where the default model uses the global.anthropic. prefix instead of regional prefixes. To use regional endpoints, you would remove the global. prefix from the model ID.

The new cost mappings correctly include pricing for both the new Anthropic API model IDs and the Bedrock global inference profile IDs. The mappings are consistent across the files being reviewed.

apps/web/.env.example (2)

21-21: LGTM!

The MICROSOFT_WEBHOOK_CLIENT_STATE variable follows the same format pattern as other secret environment variables in this file (lines 5, 8, 16, etc.). The static analysis warnings can be safely ignored as they are false positives for this file's convention.


26-80: Excellent developer experience improvement!

The new provider-block structure with clear section headers makes it much easier for developers to configure LLM providers. The commented template approach with "Uncomment ONE provider block" guidance is intuitive and reduces configuration errors.

apps/web/utils/llms/model.ts (7)

11-11: LGTM!

Correctly imports only Provider after removing the Model constant export, aligning with the refactor to use string literal model IDs throughout the codebase.


69-78: LGTM!

The OpenAI provider correctly defaults to "gpt-4o" using a string literal, which is properly mapped in the usage cost tracking.


80-89: LGTM!

The Google provider correctly defaults to "gemini-2.0-flash" using a string literal, which is properly mapped in the usage cost tracking.


91-98: LGTM!

The Groq provider correctly defaults to "llama-3.3-70b-versatile" using a string literal, which is properly mapped in the usage cost tracking.


100-117: LGTM!

The OpenRouter provider correctly defaults to "anthropic/claude-sonnet-4.5" using a string literal, which is properly mapped in the usage cost tracking.


119-128: LGTM!

The AI Gateway provider correctly defaults to "google/gemini-2.5-pro" using a string literal, which is properly mapped in the usage cost tracking.


161-171: LGTM!

The Anthropic provider correctly defaults to "claude-sonnet-4-5-20250929" (the direct Anthropic API model ID format), which is properly mapped in the usage cost tracking. This was correctly updated from the previous version.

Comment on lines 57 to 60
| **AWS Bedrock** ||||
| `BEDROCK_ACCESS_KEY` | No | AWS access key for Bedrock. See more [here](https://ai-sdk.dev/providers/ai-sdk-providers/amazon-bedrock). | — |
| `BEDROCK_SECRET_KEY` | No | AWS secret key for Bedrock | — |
| `BEDROCK_REGION` | No | AWS region for Bedrock | `us-west-2` |
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

I'll verify the review comment by examining the AWS Bedrock implementation and documentation to confirm whether the model configuration documentation gap is legitimate.
<function_calls>

find . -type f ( -name ".md" -o -name ".ts" -o -name ".tsx" -o -name ".js" -o -name "*.json" ) | grep -E "(bedrock|provider)" | head -20

</function_calls>

Let me search more broadly for Bedrock-related files:
<function_calls>

find . -type f ( -name ".ts" -o -name ".tsx" -o -name "*.js" ) | xargs rg -l "bedrock|Bedrock" -i | head -20

</function_calls>

Let me first check the repository structure:
<function_calls>

git ls-files | grep -E "(bedrock|provider)" | head -20

</function_calls>

Now let me search for Bedrock references in the codebase:
<function_calls>

rg -i "bedrock" --type ts --type tsx --type js -n -C 2 | head -100

</function_calls>

Let me also check the environment variables documentation file directly:
<function_calls>

cat -n docs/hosting/environment-variables.md | head -80

</function_calls>

Let me search for references to BEDROCK_SONNET_MODEL and claude-sonnet:
<function_calls>

rg "BEDROCK.*MODEL|claude-sonnet|4-5-20250929" -i --type ts --type tsx --type js --type md -n

</function_calls>

Let me try a different approach and look for provider-related files:
<function_calls>

find . -path ./node_modules -prune -o -type f -name "provider" -print

</function_calls>

Let me check what files exist in the repository and focus on the source code:
<function_calls>

git ls-files | grep -v node_modules | head -30

</function_calls>

Let me look at the full environment-variables.md file to understand the context better:
<function_calls>

wc -l docs/hosting/environment-variables.md

</function_calls>

<function_calls>

cat docs/hosting/environment-variables.md

</function_calls>

Now let me search for source code files related to AI/LLM providers:
<function_calls>

git ls-files | grep -E "^(src|lib|app)" | grep -v node_modules | head -40

</function_calls>

<function_calls>

find . -path ./node_modules -prune -o -type d -name "provider*" -print

</function_calls>

Let me search all files for "bedrock" more broadly:
<function_calls>

rg -i "bedrock" --type-list | head -20

</function_calls>

<function_calls>

rg -i "bedrock" -g "!node_modules" -n

</function_calls>

Now search for references to the claude model variant:
<function_calls>

rg "claude-sonnet|sonnet.*model|BEDROCK.*MODEL|NEXT_PUBLIC_BEDROCK" -i -g "!node_modules" -n

</function_calls>

Let me check git log for recent commits related to this change:
<function_calls>

git log --oneline -20

</function_calls>

Let me check the git diff of the PR branch to understand what changed:
<function_calls>

git diff main --name-only | head -20

</function_calls>

<function_calls>

git diff main -- docs/hosting/environment-variables.md | head -100

</function_calls>

Let me search for any mentions of environment variables configuration or Bedrock setup:
<function_calls>

find . -path ./node_modules -prune -o -type f ( -name ".ts" -o -name ".tsx" -o -name ".js" -o -name ".md" ) -print | xargs grep -l -i "bedrock" 2>/dev/null

</function_calls>

Let me check the current branch state:
<function_calls>

git branch -a

</function_calls>

<function_calls>

git status

</function_calls>

Let me look at the full environment-variables.md to search for other Bedrock mentions:
<function_calls>

grep -n -i "bedrock|sonnet|anthropic" docs/hosting/environment-variables.md

</function_calls>

Since the environment-variables.md doesn't seem to have other Bedrock references and I can't find implementation details, let me check if there are any related provider configuration files:
<function_calls>

find . -path ./node_modules -prune -o -type f ( -name ".env" -o -name "config" ) -print | grep -v node_modules | head -20

</function_calls>

Let me check git diff more comprehensively:
<function_calls>

git diff main -- . | grep -A 5 -B 5 -i "bedrock|sonnet" | head -100

</function_calls>

Let me check what's in the current HEAD:
<function_calls>

git show HEAD:docs/hosting/environment-variables.md | grep -n -i "bedrock" -A 3

</function_calls>

Let me verify if the environment-variables.md file matches what was shown in the review:
<function_calls>

sed -n '55,65p' docs/hosting/environment-variables.md

</function_calls>

Perfect. Now let me check if there are any other references to model configuration in the codebase. Let me search for configuration files, environment setup, or provider initialization:
<function_calls>

git ls-files | wc -l

</function_calls>

<function_calls>

git ls-files | grep -v "node_modules|.next|dist|build" | head -50

</function_calls>

Let me look at the repository structure:
<function_calls>

ls -la

</function_calls>

<function_calls>

find . -maxdepth 2 -type d | grep -v ".git|node_modules" | sort

</function_calls>

<function_calls>

ls -la src/ 2>/dev/null || ls -la app/ 2>/dev/null || ls -la lib/ 2>/dev/null || find . -maxdepth 1 -type d

</function_calls>

Let me search recursively for any source code:
<function_calls>

find . -name ".ts" -o -name ".tsx" -o -name "*.js" | grep -v node_modules | head -30

</function_calls>

Let me try to find what's actually in the repo:
<function_calls>

find . -type f -name "*.md" | grep -v node_modules | head -20

</function_calls>

Let me look at what files we have available:
<function_calls>

git ls-files

</function_calls>

Good! Now let me search these files for Bedrock references:
<function_calls>

for file in $(git ls-files); do grep -l -i "bedrock|claude-sonnet|sonnet.*model" "$file" 2>/dev/null && echo "Found in: $file"; done

</function_calls>

Let me check the full content of environment-variables.md to better understand the context:
<function_calls>

cat docs/hosting/environment-variables.md | grep -n . | tail -50

</function_calls>

Let me view the entire file in sections:
<function_calls>

cat docs/hosting/environment-variables.md

</function_calls>

Now let me check the git diff to see what changed in this PR:
<function_calls>

git diff $(git merge-base HEAD main) HEAD -- docs/hosting/environment-variables.md

</function_calls>

Let me check if there's a different main branch or check recent commits:
<function_calls>

git log --oneline --all | head -20

</function_calls>

<function_calls>

git show --stat | head -40

</function_calls>

Let me check git log for environment-variables.md specifically:
<function_calls>

git log --oneline docs/hosting/environment-variables.md | head -10

</function_calls>

<function_calls>

git show HEAD~1:docs/hosting/environment-variables.md | grep -n -i bedrock -A 3

</function_calls>

Let me check if there are any changes in this commit:
<function_calls>

git diff HEAD~1 HEAD -- docs/hosting/environment-variables.md

</function_calls>

Since there don't seem to be implementation files in this repo (looks like a docs-focused repository), let me search for any references to model IDs or BEDROCK environment variables:
<function_calls>

rg -i "BEDROCK|claude-sonnet|4-5-20250929" . 2>/dev/null

</function_calls>

Let me check the PR description or any related files that might explain the changes:
<function_calls>

cat README.md 2>/dev/null | head -50

</function_calls>

Let me check what GitHub details we can get via CLI:
<function_calls>

gh pr view --json title,body,files 2>/dev/null || echo "GitHub CLI not available or not in PR context"

</function_calls>

Let me search the documentation more thoroughly for how other providers or models are documented:
<function_calls>

rg -i "default.*model|model.*id|claude|gpt|provider" docs/ -n | head -50

</function_calls>

<function_calls>

find docs/ -name "*.md" | head -20

</function_calls>

<function_calls>

cat docs/hosting/environment-variables.md | sed -n '30,50p'

</function_calls>

Let me look at the full context around the AWS Bedrock section:
<function_calls>

cat docs/hosting/environment-variables.md | sed -n '35,70p'

</function_calls>

Let me check if there's any mention of removed environment variables or migration notes:
<function_calls>

rg "NEXT_PUBLIC|removed|deprecated|migration" docs/ -i

</function_calls>

Let me check git history for references to BEDROCK_SONNET_MODEL:
<function_calls>

git log -p -S "BEDROCK_SONNET_MODEL" --all -- docs/hosting/environment-variables.md | head -100

</function_calls>

<function_calls>

git log -S "BEDROCK" --all --oneline -- docs/hosting/environment-variables.md

</function_calls>

Let me check the commit history of this file:
<function_calls>

git log --follow -p docs/hosting/environment-variables.md | grep -A 10 -B 10 -i "bedrock" | head -100

</function_calls>

Let me check if there are any related documentation files:
<function_calls>

find docs/ -type f -name "*.md" -exec grep -l "bedrock|provider|model" {} ;

</function_calls>

<function_calls>

cat docs/providers/bedrock.md 2>/dev/null || echo "No bedrock.md file"

</function_calls>

Let me search all docs for provider references:
<function_calls>

find docs -name "*.md" -type f | xargs ls -la 2>/dev/null

</function_calls>

Let me check if the review comment's assertion about PR objectives actually matches what's in the PR:
<function_calls>

git log HEAD -1 --format="%B"

</function_calls>

Based on my verification, I found that this is a documentation-only repository. The review comment makes specific claims about PR objectives and removed environment variables that cannot be verified here. However, the underlying documentation gap is real—the AWS Bedrock section doesn't explain model configuration.

Document how Bedrock models are configured or selected.

The AWS Bedrock section documents authentication credentials but doesn't explain which model will be used or whether it's configurable. Clarify either:

  1. That a specific model is hardcoded as the default (if so, document which one), or
  2. How users can configure the Bedrock model via environment variables.

Alternatively, add this clarification to the LLM Provider Selection section (line 36) where bedrock is listed as a provider option.

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

58-58: Link text should be descriptive

(MD059, descriptive-link-text)

🤖 Prompt for AI Agents
In docs/hosting/environment-variables.md around lines 57-60, the AWS Bedrock
section documents auth variables but omits how to choose/configure the Bedrock
model; update the doc to state the default model (if hardcoded) or the exact
environment variable name(s) users should set (e.g., BEDROCK_MODEL or
BEDROCK_SONNET_MODEL), describe valid model IDs/format and an example value, and
add a short pointer in the LLM Provider Selection section indicating where to
configure/select the Bedrock model.

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: 1

📜 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 bad95c4 and 680dc35.

📒 Files selected for processing (2)
  • apps/web/utils/llms/config.ts (1 hunks)
  • apps/web/utils/llms/model.test.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/utils/llms/config.ts
🧰 Additional context used
📓 Path-based instructions (13)
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/utils/llms/model.test.ts
**/*.{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/utils/llms/model.test.ts
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, and apps/web/__tests__/ for LLM-specific tests

Files:

  • apps/web/utils/llms/model.test.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/llms/model.test.ts
**/*.{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/utils/llms/model.test.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/utils/llms/model.test.ts
**/*.test.{ts,tsx}

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

**/*.test.{ts,tsx}: Use vitest for testing the application
Tests should be colocated next to the tested file with .test.ts or .test.tsx extension (e.g., dir/format.ts and dir/format.test.ts)
Mock server-only using vi.mock("server-only", () => ({}))
Mock Prisma using vi.mock("@/utils/prisma") and import the mock from @/utils/__mocks__/prisma
Use vi.clearAllMocks() in beforeEach to clean up mocks between tests
Each test should be independent
Use descriptive test names
Mock external dependencies in tests
Do not mock the Logger
Avoid testing implementation details
Use test helpers getEmail, getEmailAccount, and getRule from @/__tests__/helpers for mocking emails, accounts, and rules

Files:

  • apps/web/utils/llms/model.test.ts
**/*.{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/utils/llms/model.test.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/utils/llms/model.test.ts
**/*.{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/utils/llms/model.test.ts
**/*.{test,spec}.{js,jsx,ts,tsx}

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

**/*.{test,spec}.{js,jsx,ts,tsx}: Don't nest describe() blocks too deeply in test files
Don't use callbacks in asynchronous tests and hooks
Don't have duplicate hooks in describe blocks
Don't use export or module.exports in test files
Don't use focused tests
Make sure the assertion function, like expect, is placed inside an it() function call
Don't use disabled tests

Files:

  • apps/web/utils/llms/model.test.ts
!(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/utils/llms/model.test.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/utils/llms/model.test.ts
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
Learning: Applies to .env.example : Add new environment variables to `.env.example` with example values
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/environment-variables.mdc:0-0
Timestamp: 2025-11-25T14:36:45.797Z
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: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.404Z
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:43.454Z
Learning: Applies to .env.example : Add environment variables to `.env.example` with example values in the format `VARIABLE_NAME=value_example`
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: apps/web/CLAUDE.md:0-0
Timestamp: 2025-11-25T14:36:18.404Z
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.797Z
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
📚 Learning: 2025-11-25T14:38:07.585Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.585Z
Learning: Applies to apps/web/utils/llms/{index,model}.ts : Core LLM functionality must be defined in `utils/llms/index.ts`, model definitions and configurations in `utils/llms/model.ts`, and usage tracking in `utils/usage.ts`

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:37:56.072Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.072Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Use vitest imports (`describe`, `expect`, `test`, `vi`, `beforeEach`) in LLM test files

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:40:00.802Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-25T14:40:00.802Z
Learning: Applies to **/__tests__/**/*.{ts,tsx} : AI tests must be placed in the `__tests__` directory and are not run by default (they use a real LLM)

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:40:00.802Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-25T14:40:00.802Z
Learning: Applies to **/*.test.{ts,tsx} : Avoid testing implementation details

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:38:07.585Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.585Z
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/llms/model.test.ts
📚 Learning: 2025-11-25T14:37:56.072Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.072Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Place all LLM-related tests in `apps/web/__tests__/` directory

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:42:08.846Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-11-25T14:42:08.846Z
Learning: Applies to **/*.{test,spec}.{js,jsx,ts,tsx} : Don't use export or module.exports in test files

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:37:56.072Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.072Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Use `describe.runIf(isAiTest)` with environment variable `RUN_AI_TESTS === "true"` to conditionally run LLM tests

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:38:07.585Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm.mdc:0-0
Timestamp: 2025-11-25T14:38:07.585Z
Learning: Applies to apps/web/{utils/ai,utils/llms,__tests__}/**/*.ts : 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, and `apps/web/__tests__/` for LLM-specific tests

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:37:56.072Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.072Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Use `console.debug()` for outputting generated LLM content in tests, e.g., `console.debug("Generated content:\n", result.content);`

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:40:00.801Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-25T14:40:00.801Z
Learning: Applies to **/*.test.{ts,tsx} : Use `vitest` for testing the application

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:40:00.802Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-25T14:40:00.802Z
Learning: Applies to **/*.test.{ts,tsx} : Mock Prisma using `vi.mock("@/utils/prisma")` and import the mock from `@/utils/__mocks__/prisma`

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:40:00.802Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-25T14:40:00.802Z
Learning: Applies to **/*.test.{ts,tsx} : Use `vi.clearAllMocks()` in `beforeEach` to clean up mocks between tests

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:42:08.846Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-11-25T14:42:08.846Z
Learning: Applies to **/*.{test,spec}.{js,jsx,ts,tsx} : Make sure the assertion function, like expect, is placed inside an it() function call

Applied to files:

  • apps/web/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:37:56.072Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.072Z
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/utils/llms/model.test.ts
📚 Learning: 2025-11-25T14:37:56.072Z
Learnt from: CR
Repo: elie222/inbox-zero PR: 0
File: .cursor/rules/llm-test.mdc:0-0
Timestamp: 2025-11-25T14:37:56.072Z
Learning: Applies to apps/web/__tests__/**/*.test.ts : Mock 'server-only' module with empty object in LLM test files: `vi.mock("server-only", () => ({}))`

Applied to files:

  • apps/web/utils/llms/model.test.ts
🧬 Code graph analysis (1)
apps/web/utils/llms/model.test.ts (3)
apps/web/utils/llms/model.ts (1)
  • getModel (27-41)
apps/web/utils/llms/config.ts (1)
  • Provider (7-16)
apps/web/utils/llms/types.ts (1)
  • UserAIFields (3-9)
🪛 GitHub Actions: Run Tests
apps/web/utils/llms/model.test.ts

[error] 193-193: Bedrock model test failed. Expected provider to be BEDROCK but received OPENAI in test 'should configure Bedrock model correctly'.

🪛 GitHub Check: test
apps/web/utils/llms/model.test.ts

[failure] 193-193: utils/llms/model.test.ts > Models > getModel > should configure Bedrock model correctly
AssertionError: expected 'openai' to be 'bedrock' // Object.is equality

Expected: "bedrock"
Received: "openai"

❯ utils/llms/model.test.ts:193:31

⏰ 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: Jit Security
🔇 Additional comments (1)
apps/web/utils/llms/model.test.ts (1)

3-59: String-literal model IDs and Provider usage look consistent

Using Provider plus explicit string model IDs across Google/Groq/OpenRouter/Anthropic, and extending the env mock with Bedrock fields, keeps tests aligned with the new config shape while avoiding tight coupling to removed Model constants. Nothing blocking here from a testing perspective.

Also applies to: 90-151, 166-171

Copy link

@jit-ci jit-ci bot left a comment

Choose a reason for hiding this comment

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

❌ Jit security check failed to run.

#jit_bypass_commit in this PR to bypass, Jit Admin privileges required.

Copy link

@jit-ci jit-ci bot left a comment

Choose a reason for hiding this comment

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

❌ Jit security check failed to run.

#jit_bypass_commit in this PR to bypass, Jit Admin privileges required.

Copy link

@jit-ci jit-ci bot left a comment

Choose a reason for hiding this comment

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

❌ Jit security check failed to run.

#jit_bypass_commit in this PR to bypass, Jit Admin privileges required.

Copy link

@jit-ci jit-ci bot left a comment

Choose a reason for hiding this comment

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

❌ Jit security check failed to run.

#jit_bypass_commit in this PR to bypass, Jit Admin privileges required.

Copy link

@jit-ci jit-ci bot left a comment

Choose a reason for hiding this comment

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

❌ Jit security check failed to run.

#jit_bypass_commit in this PR to bypass, Jit Admin privileges required.

@elie222 elie222 merged commit 43a2e8b into main Nov 25, 2025
17 of 18 checks passed
@elie222 elie222 deleted the chore/self-host-docs branch November 25, 2025 21:28
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