Skip to content

Feature: add Mark as read action#310

Merged
elie222 merged 5 commits intoelie222:mainfrom
arndom:feature/read-action
Jan 30, 2025
Merged

Feature: add Mark as read action#310
elie222 merged 5 commits intoelie222:mainfrom
arndom:feature/read-action

Conversation

@arndom
Copy link
Contributor

@arndom arndom commented Jan 16, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Added "Mark as Read" action for email threads
    • Expanded action type capabilities across the application
  • Database Changes

    • Updated database schema to support new action type
    • Added unique constraint for user accounts
  • Improvements

    • Enhanced action handling and validation mechanisms
    • Introduced new action type with consistent styling and labeling

@vercel
Copy link

vercel bot commented Jan 16, 2025

@arndom is attempting to deploy a commit to the Inbox Zero Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 16, 2025

Warning

Rate limit exceeded

@elie222 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 11 minutes and 27 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between e0f1c16 and b632a5a.

📒 Files selected for processing (1)
  • apps/web/app/(app)/automation/RuleForm.tsx (2 hunks)

Walkthrough

This pull request introduces a new action type MARK_READ across multiple files in the web application. The changes involve updating the Prisma schema, database migration, action validation, AI action definitions, and component rendering to support marking email threads as read. The modifications extend the existing action handling infrastructure to accommodate this new functionality while maintaining the current system's architecture.

Changes

File Change Summary
apps/web/prisma/schema.prisma - Added @unique constraint to userId in Account model
- Added MARK_READ to ActionType enum
apps/web/prisma/migrations/... Added MARK_READ to database ActionType enum
apps/web/utils/actions/validation.ts Updated zodActionType enum to include MARK_READ
apps/web/utils/ai/actions.ts - Added MARK_READ action function definition
- Created mark_read function
- Updated actionFunctionDefs and runActionFunction
apps/web/utils/action-item.ts Added MARK_READ to actionInputs with empty fields
apps/web/components/PlanBadge.tsx Updated to handle ActionType.MARK_READ in badge rendering

Assessment against linked issues

Objective Addressed Explanation
Implement read/unread as an Action [#280]

Possibly related PRs

Poem

🐰 A rabbit's tale of actions new,
Mark as read, a feature true!
Enum expanded, schema bright,
Emails dance in digital light 📧
Code hops forward with glee! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

🧹 Nitpick comments (1)
apps/web/utils/ai/actions.ts (1)

436-441: Add error handling and improve type safety.

While the implementation is correct, consider these improvements:

  1. Add error handling to match other functions
  2. Use a more specific type instead of any
-const mark_read: ActionFunction<any> = async (
+const mark_read: ActionFunction<Record<string, never>> = async (
   gmail: gmail_v1.Gmail,
   email: EmailForAction,
 ) => {
-  return await markReadThread({ gmail, threadId: email.threadId, read: true });
+  try {
+    return await markReadThread({ gmail, threadId: email.threadId, read: true });
+  } catch (error) {
+    logger.error("Failed to mark thread as read", { error, threadId: email.threadId });
+    throw error;
+  }
 };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 70b0fa0 and ec5d987.

📒 Files selected for processing (6)
  • apps/web/components/PlanBadge.tsx (3 hunks)
  • apps/web/prisma/migrations/20250116101856_mark_read_action/migration.sql (1 hunks)
  • apps/web/prisma/schema.prisma (2 hunks)
  • apps/web/utils/actionType.ts (1 hunks)
  • apps/web/utils/actions/validation.ts (1 hunks)
  • apps/web/utils/ai/actions.ts (5 hunks)
🔇 Additional comments (9)
apps/web/utils/actionType.ts (1)

119-119: Implementation looks good!

The MARK_READ action is correctly implemented with no input fields, consistent with other similar actions like ARCHIVE and MARK_SPAM.

apps/web/components/PlanBadge.tsx (1)

123-124: UI implementation is consistent and well-designed!

The MARK_READ action is properly integrated into the UI components:

  • Badge component follows the same pattern as other actions
  • Clear and user-friendly label "Mark as read"
  • Consistent color scheme with similar actions (yellow, same as Archive)

Also applies to: 156-157, 189-189

apps/web/utils/actions/validation.ts (1)

39-39: Validation schema correctly updated!

The MARK_READ action type is properly added to the zodActionType enum. No additional validation rules are needed since this action doesn't require any input fields.

apps/web/prisma/migrations/20250116101856_mark_read_action/migration.sql (1)

1-2: Database migration is properly implemented!

The migration correctly adds the MARK_READ value to the ActionType enum using standard PostgreSQL syntax. The migration file is well-named with date and purpose.

apps/web/utils/ai/actions.ts (3)

13-13: LGTM! Import added correctly.

The markReadThread import is appropriately grouped with other Gmail label utilities.


252-261: LGTM! Action definition is well-structured.

The MARK_READ action definition follows the established pattern and correctly specifies no required parameters.


475-476: LGTM! Switch case added correctly.

The MARK_READ case is properly integrated into the action function dispatcher.

apps/web/prisma/schema.prisma (2)

378-378: LGTM! Enum value added correctly.

The MARK_READ action type is properly added to the enum and follows the established naming convention.


Line range hint 17-17: Verify the impact of adding @unique constraint.

Adding a unique constraint to userId is a breaking change that:

  1. Enforces one account per user
  2. Could fail if existing users have multiple accounts

Run this script to check for potential conflicts:

✅ Verification successful

The unique constraint on Account.userId is safe to add

The multi-account functionality in the codebase is implemented through the premium relation for sharing premium features, not through multiple OAuth accounts. The Account model is strictly used for authentication, and no code patterns were found that rely on multiple accounts per user. The migration warning is precautionary but not a concern in this case.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if any users have multiple accounts that would violate the new constraint

# Use ast-grep to find the Account model definition and analyze its structure
echo "Current Account model structure:"
ast-grep --pattern 'model Account {
  $$$
}'

# Use ripgrep to find any migration files that might have relevant history
echo -e "\nRelevant migration history:"
rg -l "Account" --glob "migrations/*.sql"

Length of output: 383


Script:

#!/bin/bash
# First, find all prisma schema files
echo "Prisma schema files:"
fd -e prisma

# Find migration files in various possible locations
echo -e "\nMigration files:"
fd -e sql

# Look for Account model definition and its usage
echo -e "\nAccount model structure and usage:"
rg -A 10 "model Account" --type-not sql

# Check for any code that might be accessing multiple accounts per user
echo -e "\nCode patterns accessing accounts:"
rg "findMany.*where.*userId" --type typescript

Length of output: 5542


Script:

#!/bin/bash
# Check content of migration that added unique constraint
echo "Migration that added unique constraint:"
cat "apps/web/prisma/migrations/20231027022923_unique_account/migration.sql"

# Search for Account-related patterns in TypeScript/JavaScript files
echo -e "\nCode patterns accessing accounts:"
rg "Account.*findMany|findMany.*Account" --type js --type ts

# Look for any imports or uses of Account model
echo -e "\nAccount model usage:"
rg "Account.*from.*prisma|import.*Account" --type js --type ts

Length of output: 1132


Script:

#!/bin/bash
# Check content of multi-account related files
echo "Multi-account component content:"
cat "apps/web/app/(app)/settings/MultiAccountSection.tsx"

echo -e "\nMulti-account API route:"
cat "apps/web/app/api/user/settings/multi-account/route.ts"

Length of output: 8935

@elie222
Copy link
Owner

elie222 commented Jan 26, 2025

Thanks! Will try get this merged tomorrow. I caused a merge conflict here today

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

🧹 Nitpick comments (1)
apps/web/utils/ai/actions.ts (1)

437-442: Improve type safety by using Record<string, unknown> instead of any.

The mark_read function implementation is correct, but it's using the any type for the args parameter. For better type safety, use Record<string, unknown> since this action doesn't require any parameters.

Apply this diff:

-const mark_read: ActionFunction<any> = async (
+const mark_read: ActionFunction<Record<string, unknown>> = async (
   gmail: gmail_v1.Gmail,
   email: EmailForAction,
 ) => {
   return await markReadThread({ gmail, threadId: email.threadId, read: true });
 };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec5d987 and 14e8764.

📒 Files selected for processing (4)
  • apps/web/prisma/schema.prisma (2 hunks)
  • apps/web/utils/action-item.ts (1 hunks)
  • apps/web/utils/actions/validation.ts (1 hunks)
  • apps/web/utils/ai/actions.ts (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/web/utils/actions/validation.ts
  • apps/web/prisma/schema.prisma
🔇 Additional comments (3)
apps/web/utils/ai/actions.ts (3)

265-274: LGTM!

The MARK_READ action function definition follows the same pattern as other no-parameter actions and has a clear description.


285-285: LGTM!

The new action type is correctly added to the actionFunctionDefs record.


476-477: LGTM!

The new case is correctly added to the runActionFunction switch statement.

},
],
},
[ActionType.MARK_READ]: { fields: [] },
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

LGTM! But handle the new action type in sanitizeActionFields.

The MARK_READ action is correctly added to actionInputs. However, it needs to be handled in the sanitizeActionFields function's switch statement to maintain type safety.

Add this case before the default case:

    case ActionType.CALL_WEBHOOK: {
      return {
        ...base,
        url: action.url ?? null,
      };
    }
+   case ActionType.MARK_READ:
+     return base;
    default:
      // biome-ignore lint/correctness/noSwitchDeclarations: intentional exhaustive check
      const exhaustiveCheck: never = action.type;
      return exhaustiveCheck;

Committable suggestion skipped: line range outside the PR's diff.

@elie222 elie222 merged commit 0ef78f3 into elie222:main Jan 30, 2025
2 of 3 checks passed
@elie222
Copy link
Owner

elie222 commented Jan 30, 2025

Thanks! Merged!

salja03-t21 added a commit to salja03-t21/inbox-zero that referenced this pull request Dec 16, 2025
…oviders

Root cause of React Error elie222#310 (Rendered more hooks than during the previous render):
- GlobalProviders (root layout) wraps children in NuqsAdapter and ComposeModalProvider
- AppProviders ((app) layout) was ALSO wrapping children in NuqsAdapter and ComposeModalProvider
- This nested duplication caused inconsistent hook counts during hydration/navigation

The fix:
- Remove NuqsAdapter from AppProviders (already provided by GlobalProviders)
- Remove ComposeModalProvider from AppProviders (already provided by GlobalProviders)
- Sync ChatProvider with upstream (use useAccount() instead of useParams())

Provider hierarchy is now:
Root Layout → GlobalProviders → NuqsAdapter → EmailAccountProvider → SWRProvider → ...
  └── (app) Layout → AppProviders → ThemeProvider → Jotai → ChatProvider → children

This also includes the SSO fix from earlier commits:
- handleLinkAccount skips EmailAccount creation for SSO providers
- API filters to only valid email providers (Google/Microsoft)
- Client-side filtering in EmailAccountProvider
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.

Read/unread as an Action

2 participants

Comments