Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThe changes introduce a new component for visualizing email actions, enhance existing components by updating UI elements, and improve data handling and API interactions related to email archiving and deletion. Additionally, new endpoints and data structures are established for better tracking and analytics of user email actions. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant EmailActionsAnalytics
participant API
participant Tinybird
User->>EmailActionsAnalytics: Request email action stats
EmailActionsAnalytics->>API: Fetch stats from /api/user/stats/email-actions
API->>Tinybird: Retrieve email actions data
Tinybird-->>API: Return email actions data
API-->>EmailActionsAnalytics: Return stats
EmailActionsAnalytics-->>User: Display email actions in bar chart
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? TipsChatThere are 3 ways to chat with CodeRabbit:
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 as PR comments)
Additionally, you can add CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 9
Outside diff range, codebase verification and nitpick comments (1)
apps/web/app/api/user/stats/email-actions/route.ts (1)
13-13: Avoid unnecessary use of template literals.The use of template literals without interpolation is unnecessary. Replace with a string literal.
Apply this diff to replace the template literal with a string literal:
- await getEmailActionsByDay({ ownerEmail: options.email }) + await getEmailActionsByDay({ ownerEmail: options.email })
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (14)
- apps/web/app/(app)/stats/EmailActionsAnalytics.tsx (1 hunks)
- apps/web/app/(app)/stats/LargestEmails.tsx (3 hunks)
- apps/web/app/(app)/stats/page.tsx (2 hunks)
- apps/web/app/api/google/threads/archive/controller.ts (1 hunks)
- apps/web/app/api/user/stats/email-actions/route.ts (1 hunks)
- apps/web/utils/actions/helpers.ts (1 hunks)
- apps/web/utils/actions/mail.ts (3 hunks)
- apps/web/utils/ai/actions.ts (1 hunks)
- apps/web/utils/gmail/label.ts (2 hunks)
- apps/web/utils/gmail/trash.ts (2 hunks)
- packages/tinybird/datasources/email_action.datasource (1 hunks)
- packages/tinybird/pipes/get_email_actions_by_period.pipe (1 hunks)
- packages/tinybird/src/publish.ts (1 hunks)
- packages/tinybird/src/query.ts (1 hunks)
Additional context used
Biome
apps/web/app/(app)/stats/EmailActionsAnalytics.tsx
[error] 14-14: Do not use template literals if interpolation and special-character handling are not needed.
Unsafe fix: Replace with string literal
(lint/style/noUnusedTemplateLiteral)
apps/web/utils/gmail/trash.ts
[error] 1-1: Some named imports are only used as types.
This import is only used as a type.
Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.(lint/style/useImportType)
apps/web/utils/gmail/label.ts
[error] 1-2: Some named imports are only used as types.
This import is only used as a type.
Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.(lint/style/useImportType)
apps/web/utils/actions/mail.ts
[error] 32-32: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
apps/web/utils/ai/actions.ts
[error] 234-234: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
Additional comments not posted (23)
apps/web/utils/actions/helpers.ts (3)
Line range hint
6-6: LGTM!The function is correctly implemented.
The code changes are approved.
Line range hint
15-20: LGTM!The function is correctly implemented.
The code changes are approved.
11-13: LGTM! But verify the function usage in the codebase.The function is correctly implemented. However, ensure that all function calls to
getSessionAndGmailClientmatch the new logic.The code changes are approved.
Run the following script to verify the function usage:
Verification successful
Verification Successful: Function Usage Matches New Logic
The function
getSessionAndGmailClientis used consistently across the codebase, with all instances correctly handling theerrorandgmailobject as per the new logic.
- Files with verified usage:
apps/web/utils/actions/mail.tsapps/web/utils/actions/categorize.tsapps/web/utils/actions/ai-rule.tsScripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all function calls to `getSessionAndGmailClient` match the new logic. # Test: Search for the function usage. Expect: Only occurrences of the new logic. rg --type typescript -A 5 $'getSessionAndGmailClient'Length of output: 87
Script:
#!/bin/bash # Description: Verify all function calls to `getSessionAndGmailClient` match the new logic. # Test: Search for the function usage in .ts files. Expect: Only occurrences of the new logic. rg 'getSessionAndGmailClient' --glob '**/*.ts' -A 5Length of output: 3526
apps/web/app/api/user/stats/email-actions/route.ts (2)
11-21: LGTM!The function is correctly implemented.
The code changes are approved.
23-31: LGTM!The function is correctly implemented.
The code changes are approved.
apps/web/app/(app)/stats/EmailActionsAnalytics.tsx (1)
10-42: LGTM!The function is correctly implemented.
The code changes are approved.
Tools
Biome
[error] 14-14: Do not use template literals if interpolation and special-character handling are not needed.
Unsafe fix: Replace with string literal
(lint/style/noUnusedTemplateLiteral)
apps/web/utils/gmail/trash.ts (3)
11-12: LGTM!The function signature correctly includes the new parameters
ownerEmailandactionSource.The code changes are approved.
14-42: LGTM!The function body correctly handles the new parameters and concurrent operations using
Promise.allSettled. The error handling is appropriate.The code changes are approved.
Line range hint
44-54: LGTM!The
trashMessagefunction remains unchanged and is correctly implemented.The code changes are approved.
packages/tinybird/src/publish.ts (5)
39-45: LGTM!The Zod schema
tinybirdEmailActionis correctly defined to validate the structure of email action objects.The code changes are approved.
47-47: LGTM!The
TinybirdEmailActiontype is correctly inferred from thetinybirdEmailActionschema.The code changes are approved.
49-52: LGTM!The
publishEmailActionfunction is correctly created usingtb.buildIngestEndpoint.The code changes are approved.
55-57: LGTM!The
publishArchivefunction correctly publishes archive actions.The code changes are approved.
59-61: LGTM!The
publishDeletefunction correctly publishes delete actions.The code changes are approved.
apps/web/app/(app)/stats/page.tsx (2)
15-15: LGTM!The import statement correctly includes the new component
EmailActionsAnalytics.The code changes are approved.
102-104: LGTM!The
EmailActionsAnalyticscomponent is correctly integrated into theStatsPagecomponent.The code changes are approved.
apps/web/utils/gmail/label.ts (1)
34-67: LGTM! But verify the function usage in the codebase.The changes enhance the functionality and resilience of the
archiveThreadfunction. Ensure that all function calls toarchiveThreadmatch the new signature.The code changes are approved.
Run the following script to verify the function usage:
Verification successful
Function usage verified: All calls to
archiveThreadmatch the new signature.The function
archiveThreadis used consistently across the codebase with the updated signature, ensuring that the changes have been correctly integrated.
- Files verified:
apps/web/providers/QueueProvider.tsxapps/web/utils/ai/actions.tsapps/web/utils/actions/mail.tsapps/web/app/api/google/threads/archive/controller.tsScripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all function calls to `archiveThread` match the new signature. # Test: Search for the function usage. Expect: Only occurrences of the new signature. rg --type typescript -A 5 $'archiveThread'Length of output: 76
Script:
#!/bin/bash # Description: Verify all function calls to `archiveThread` match the new signature. # Test: Search for the function usage. Expect: Only occurrences of the new signature. rg --type ts -A 5 $'archiveThread'Length of output: 3868
apps/web/app/(app)/stats/LargestEmails.tsx (2)
6-6: LGTM!The import statement for the
Titlecomponent from@tremor/reactis correct and necessary for the changes made to the component.The code changes are approved.
57-57: LGTM! But verify the visual styling and behavior.The
CardTitlecomponent has been replaced with theTitlecomponent. Ensure that theTitlecomponent is correctly styled and behaves as expected in the UI.The code changes are approved.
Check the visual styling and behavior of the
Titlecomponent in the UI.apps/web/utils/actions/mail.ts (2)
51-57: LGTM!The changes enhance the functionality by allowing the action to access and utilize the user's email. The implementation is correct.
The code changes are approved.
66-72: LGTM!The changes enhance the functionality by allowing the action to access and utilize the user's email. The implementation is correct.
The code changes are approved.
packages/tinybird/src/query.ts (1)
193-203: LGTM!The function
getEmailActionsByDayis correctly implemented. Ensure that the pipe name "get_email_actions_by_period" is correct.The code changes are approved.
Run the following script to verify the pipe name:
apps/web/utils/ai/actions.ts (1)
234-240: LGTM!The function
archiveis correctly updated to include additional parameters and properties.The code changes are approved.
Tools
Biome
[error] 234-234: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
| NODE get_email_actions | ||
| DESCRIPTION > | ||
| Get the number of email actions by period | ||
|
|
||
| SQL > | ||
| % | ||
| SELECT | ||
| toDate(fromUnixTimestamp64Milli(timestamp)) AS date, | ||
| countIf(action = 'archive') AS archive_count, | ||
| countIf(action = 'delete') AS delete_count | ||
| FROM email_action | ||
| WHERE ownerEmail = {{ String(ownerEmail) }} | ||
| GROUP BY date |
There was a problem hiding this comment.
Add error handling and validation for the ownerEmail parameter.
The SQL query is correct, but it lacks error handling and validation for the ownerEmail parameter. Consider adding validation to ensure the ownerEmail is not null or empty.
Apply this diff to add validation:
WHERE ownerEmail = {{ String(ownerEmail) }}
+ AND ownerEmail IS NOT NULL
+ AND ownerEmail != ''Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| NODE get_email_actions | |
| DESCRIPTION > | |
| Get the number of email actions by period | |
| SQL > | |
| % | |
| SELECT | |
| toDate(fromUnixTimestamp64Milli(timestamp)) AS date, | |
| countIf(action = 'archive') AS archive_count, | |
| countIf(action = 'delete') AS delete_count | |
| FROM email_action | |
| WHERE ownerEmail = {{ String(ownerEmail) }} | |
| GROUP BY date | |
| NODE get_email_actions | |
| DESCRIPTION > | |
| Get the number of email actions by period | |
| SQL > | |
| % | |
| SELECT | |
| toDate(fromUnixTimestamp64Milli(timestamp)) AS date, | |
| countIf(action = 'archive') AS archive_count, | |
| countIf(action = 'delete') AS delete_count | |
| FROM email_action | |
| WHERE ownerEmail = {{ String(ownerEmail) }} | |
| AND ownerEmail IS NOT NULL | |
| AND ownerEmail != '' | |
| GROUP BY date |
| ENGINE "MergeTree" | ||
| ENGINE_SORTING_KEY ownerEmail, action, actionSource, timestamp | ||
| ENGINE_PARTITION_KEY "toYYYYMM(fromUnixTimestamp64Milli(timestamp))" No newline at end of file |
There was a problem hiding this comment.
Add error handling and validation for the sorting and partitioning keys.
The engine definition is correct, but it lacks error handling and validation for the sorting and partitioning keys. Consider adding validation to ensure the keys are not null or empty.
Apply this diff to add validation:
ENGINE_SORTING_KEY ownerEmail, action, actionSource, timestamp
+ CHECK ownerEmail IS NOT NULL AND ownerEmail != ''
+ CHECK action IS NOT NULL AND action != ''
+ CHECK actionSource IS NOT NULL AND actionSource != ''
+ CHECK timestamp IS NOT NULLCommittable suggestion was skipped due to low confidence.
| SCHEMA > | ||
| `ownerEmail` String `json:$.ownerEmail`, | ||
| `threadId` String `json:$.threadId`, | ||
| `action` LowCardinality(String) `json:$.action`, | ||
| `actionSource` LowCardinality(String) `json:$.actionSource`, | ||
| `timestamp` Int64 `json:$.timestamp` |
There was a problem hiding this comment.
Add validation for the ownerEmail field.
The schema is correct, but it lacks validation for the ownerEmail field. Consider adding validation to ensure the ownerEmail is not null or empty.
Apply this diff to add validation:
`ownerEmail` String `json:$.ownerEmail`,
+ CHECK ownerEmail IS NOT NULL AND ownerEmail != ''Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| SCHEMA > | |
| `ownerEmail` String `json:$.ownerEmail`, | |
| `threadId` String `json:$.threadId`, | |
| `action` LowCardinality(String) `json:$.action`, | |
| `actionSource` LowCardinality(String) `json:$.actionSource`, | |
| `timestamp` Int64 `json:$.timestamp` | |
| SCHEMA > | |
| `ownerEmail` String `json:$.ownerEmail`, | |
| CHECK ownerEmail IS NOT NULL AND ownerEmail != '', | |
| `threadId` String `json:$.threadId`, | |
| `action` LowCardinality(String) `json:$.action`, | |
| `actionSource` LowCardinality(String) `json:$.actionSource`, | |
| `timestamp` Int64 `json:$.timestamp` |
| const thread = await archiveThread({ | ||
| gmail, | ||
| threadId: body.id, | ||
| ownerEmail: session.user.email, | ||
| actionSource: "user", | ||
| }); |
There was a problem hiding this comment.
Add error handling and validation for the additional parameters.
The modifications are correct, but it lacks error handling and validation for the additional parameters. Additionally, consider making the actionSource value more flexible.
Apply this diff to add validation:
const thread = await archiveThread({
gmail,
threadId: body.id,
ownerEmail: session.user.email,
- actionSource: "user",
+ actionSource: body.actionSource || "user",
});Committable suggestion was skipped due to low confidence.
| return ( | ||
| <LoadingContent | ||
| loading={isLoading} | ||
| error={error} |
There was a problem hiding this comment.
Improve error handling.
The error handling could be improved by providing more user-friendly messages.
Apply this diff to improve error handling:
- error={error}
+ error={error ? "Failed to load email action statistics. Please try again later." : null}Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| error={error} | |
| error={error ? "Failed to load email action statistics. Please try again later." : null} |
| @@ -1,3 +1,4 @@ | |||
| import { publishDelete, TinybirdEmailAction } from "@inboxzero/tinybird"; | |||
There was a problem hiding this comment.
Optimize type-only imports.
Use import type for TinybirdEmailAction to ensure that they are removed by the transpilers and avoid loading unnecessary modules.
Apply this diff to optimize the import:
-import { publishDelete, TinybirdEmailAction } from "@inboxzero/tinybird";
+import { publishDelete } from "@inboxzero/tinybird";
+import type { TinybirdEmailAction } from "@inboxzero/tinybird";Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import { publishDelete, TinybirdEmailAction } from "@inboxzero/tinybird"; | |
| import { publishDelete } from "@inboxzero/tinybird"; | |
| import type { TinybirdEmailAction } from "@inboxzero/tinybird"; |
Tools
Biome
[error] 1-1: Some named imports are only used as types.
This import is only used as a type.
Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.(lint/style/useImportType)
| @@ -1,4 +1,5 @@ | |||
| import type { gmail_v1 } from "googleapis"; | |||
| import { publishArchive, TinybirdEmailAction } from "@inboxzero/tinybird"; | |||
There was a problem hiding this comment.
Use import type for type-only imports.
The TinybirdEmailAction import is only used as a type. Use import type to ensure it is removed by the transpilers and avoid loading unnecessary modules.
Apply this diff to fix the issue:
-import { publishArchive, TinybirdEmailAction } from "@inboxzero/tinybird";
+import { publishArchive } from "@inboxzero/tinybird";
+import type { TinybirdEmailAction } from "@inboxzero/tinybird";Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import { publishArchive, TinybirdEmailAction } from "@inboxzero/tinybird"; | |
| import { publishArchive } from "@inboxzero/tinybird"; | |
| import type { TinybirdEmailAction } from "@inboxzero/tinybird"; |
Tools
Biome
[error] 1-2: Some named imports are only used as types.
This import is only used as a type.
Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.
Safe fix: Use import type.(lint/style/useImportType)
| action: ( | ||
| gmail: gmail_v1.Gmail, | ||
| user: { id: string; email: string }, | ||
| ) => Promise<any>, |
There was a problem hiding this comment.
Avoid using any.
The use of any should be avoided to ensure type safety. Specify a different type for the error parameter.
Apply this diff to fix the issue:
-): Promise<ServerActionResponse<T>> {
+): Promise<ServerActionResponse<T | { error: string }>> {Committable suggestion was skipped due to low confidence.
Tools
Biome
[error] 32-32: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
|
|
||
| const archive: ActionFunction<{}> = async (gmail, email) => { | ||
| await archiveThread({ gmail, threadId: email.threadId }); | ||
| const archive: ActionFunction<{}> = async (gmail, email, _args, userEmail) => { |
There was a problem hiding this comment.
Replace {} with a more specific type.
The use of {} as a type should be replaced with a more specific type to improve type safety.
Apply this diff to replace {} with a more specific type:
-const archive: ActionFunction<{}> = async (gmail, email, _args, userEmail) => {
+const archive: ActionFunction<Record<string, never>> = async (gmail, email, _args, userEmail) => {Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const archive: ActionFunction<{}> = async (gmail, email, _args, userEmail) => { | |
| const archive: ActionFunction<Record<string, never>> = async (gmail, email, _args, userEmail) => { |
Tools
Biome
[error] 234-234: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
Keep track of actions done using inbox zero and display these to the user on the analytics tab
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Chores