Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThe changes introduce persistent chat functionality with chat history, message storage, and retrieval. New Prisma models and migrations add Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ChatUI
participant useChatMessages / useChats
participant API
participant DB
User->>ChatUI: Opens Assistant page
ChatUI->>useChats: Optionally fetch chat list
useChats->>API: GET /api/chats
API->>DB: Query chats by emailAccountId
DB-->>API: Return chat list
API-->>useChats: Respond with chats
useChats-->>ChatUI: Provide chat list
User->>ChatUI: Selects a chat from history
ChatUI->>useChatMessages: Fetch messages for chatId
useChatMessages->>API: GET /api/chats/{chatId}
API->>DB: Query chat and messages
DB-->>API: Return chat with messages
API-->>useChatMessages: Respond with chat data
useChatMessages-->>ChatUI: Provide messages
User->>ChatUI: Sends new message
ChatUI->>API: POST /api/chat (chatId + message)
API->>DB: Fetch or create chat, save user message
API->>AI: Process chat with messages
AI-->>API: Return assistant response
API->>DB: Save assistant message
API-->>ChatUI: Stream assistant response
Possibly related PRs
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
apps/web/app/(app)/[emailAccountId]/assistant/page.tsxOops! Something went wrong! :( ESLint: 9.24.0 ESLint couldn't find an eslint.config.(js|mjs|cjs) file. From ESLint v9.0.0, the default configuration file is now eslint.config.js. https://eslint.org/docs/latest/use/configure/migration-guide If you still have problems after following the migration guide, please stop by apps/web/app/(app)/[emailAccountId]/automation/AssistantTabs.tsxOops! Something went wrong! :( ESLint: 9.24.0 ESLint couldn't find an eslint.config.(js|mjs|cjs) file. From ESLint v9.0.0, the default configuration file is now eslint.config.js. https://eslint.org/docs/latest/use/configure/migration-guide If you still have problems after following the migration guide, please stop by apps/web/app/api/rules/pending/route.tsOops! Something went wrong! :( ESLint: 9.24.0 ESLint couldn't find an eslint.config.(js|mjs|cjs) file. From ESLint v9.0.0, the default configuration file is now eslint.config.js. https://eslint.org/docs/latest/use/configure/migration-guide If you still have problems after following the migration guide, please stop by Note ⚡️ AI Code Reviews for VS Code, Cursor, WindsurfCodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback. Note ⚡️ Faster reviews with cachingCodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 30th. To opt out, configure ✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (7)
apps/web/app/api/chats/route.ts (1)
13-20: Consider adding pagination for chat listingThe implementation for fetching chats is clean and follows good practices, ordering by most recent first. However, as users accumulate more chats over time, this endpoint might return a large payload.
Consider adding pagination to handle potentially large numbers of chat sessions:
- async function getChats({ emailAccountId }: { emailAccountId: string }) { + async function getChats({ emailAccountId, page = 1, limit = 20 }: { emailAccountId: string, page?: number, limit?: number }) { const chats = await prisma.chat.findMany({ where: { emailAccountId }, orderBy: { updatedAt: "desc" }, + skip: (page - 1) * limit, + take: limit, }); - return { chats }; + return { chats, page, limit }; }apps/web/components/assistant-chat/chat.tsx (2)
169-223: Well-implemented chat history dropdown with good UX patterns.The ChatHistoryDropdown component is well-structured and follows good practices:
- Lazy loading of chats only when the user interacts with the dropdown
- Proper handling of loading and error states
- Clean implementation of chat selection via URL query parameters
Consider adding a refresh mechanism for when new chats are created:
function ChatHistoryDropdown() { const [_chatId, setChatId] = useQueryState("chatId"); const [shouldLoadChats, setShouldLoadChats] = useState(false); - const { data, error, isLoading } = useChats(shouldLoadChats); + const { data, error, isLoading, mutate } = useChats(shouldLoadChats); return ( <DropdownMenu> <DropdownMenuTrigger asChild> <Button variant="ghost" size="icon" - onMouseEnter={() => setShouldLoadChats(true)} + onMouseEnter={() => { + setShouldLoadChats(true); + mutate(); // Refresh chat list when dropdown is opened + }} >
204-214: Enhance date formatting for better readability.The current date formatting uses the browser's default locale settings, which may not be consistent across all users.
Consider using a more structured date format or a relative time format for better readability:
{data.chats.map((chatItem) => ( <DropdownMenuItem key={chatItem.id} onSelect={() => { setChatId(chatItem.id); }} > - {`Chat from ${new Date(chatItem.createdAt).toLocaleString()}`} + {`Chat from ${new Date(chatItem.createdAt).toLocaleDateString()} at ${new Date(chatItem.createdAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`} </DropdownMenuItem> ))}Or consider using a relative time format like "2 hours ago" for better user experience.
apps/web/app/api/chats/[chatId]/route.ts (1)
29-51: Well-implemented database query with security constraints.The
getChatfunction:
- Properly restricts access by checking both chatId and emailAccountId
- Orders messages chronologically
- Uses appropriate Prisma query structure
Consider adding pagination for messages to handle potentially large chat histories:
async function getChat({ chatId, emailAccountId, + limit = 100, + offset = 0, }: { chatId: string; emailAccountId: string; + limit?: number; + offset?: number; }) { const chat = await prisma.chat.findUnique({ where: { id: chatId, emailAccountId, }, include: { messages: { orderBy: { createdAt: "asc", }, + take: limit, + skip: offset, }, }, }); return chat; }apps/web/prisma/schema.prisma (1)
581-595: ChatMessage model with proper structure and indexing.The ChatMessage model is well-structured but could benefit from some enhancements:
Consider using an enum for the role field to restrict it to valid values:
+enum ChatMessageRole { + USER + ASSISTANT + SYSTEM +} model ChatMessage { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - role String + role ChatMessageRole content String // attachments Json? // For storing message attachments if any // metadata Json? // For any additional metadata, like tool calls chatId String chat Chat @relation(fields: [chatId], references: [id], onDelete: Cascade) @@index([chatId]) }apps/web/app/api/chat/route.ts (2)
98-110: Order loaded messages to preserve chronology
findUnique({ include: { messages: true } })returns messages in unspecified order.
Sorting prevents inconsistent conversation state:include: { - messages: true + messages: { orderBy: { createdAt: "asc" } } },
174-180:convertDbRoleToSdkRolelacks a mapping for"tool"
saveChatMessagesmay persist"tool"roles, but the converter defaults them to"assistant".
Add explicit handling or filter such messages out.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
📒 Files selected for processing (11)
apps/web/app/(app)/[emailAccountId]/automation/AssistantTabs.tsx(1 hunks)apps/web/app/api/chat/route.ts(2 hunks)apps/web/app/api/chats/[chatId]/route.ts(1 hunks)apps/web/app/api/chats/route.ts(1 hunks)apps/web/components/assistant-chat/chat.tsx(4 hunks)apps/web/hooks/useChat.ts(1 hunks)apps/web/hooks/useChats.ts(1 hunks)apps/web/prisma/migrations/20250521104911_chat/migration.sql(1 hunks)apps/web/prisma/schema.prisma(3 hunks)apps/web/utils/ai/assistant/chat.ts(3 hunks)apps/web/utils/llms/index.ts(4 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (5)
apps/web/hooks/useChats.ts (1)
apps/web/app/api/chats/route.ts (1)
GetChatsResponse(5-5)
apps/web/hooks/useChat.ts (1)
apps/web/app/api/chats/[chatId]/route.ts (1)
GetChatResponse(5-5)
apps/web/components/assistant-chat/chat.tsx (1)
apps/web/hooks/useChats.ts (1)
useChats(4-6)
apps/web/app/api/chats/route.ts (2)
apps/web/app/api/chats/[chatId]/route.ts (1)
GET(7-27)apps/web/utils/middleware.ts (1)
withEmailAccount(190-194)
apps/web/app/api/chats/[chatId]/route.ts (2)
apps/web/app/api/chats/route.ts (1)
GET(7-11)apps/web/utils/middleware.ts (1)
withEmailAccount(190-194)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Static Code Analysis Js
- GitHub Check: Jit Security
🔇 Additional comments (14)
apps/web/app/(app)/[emailAccountId]/automation/AssistantTabs.tsx (1)
60-62: Clean text improvement in UI messagingThe removal of the possessive pronoun "your" from the instructional text makes the message more generic and consistent with the application's overall tone.
apps/web/hooks/useChats.ts (1)
1-6: Well-structured hook for fetching chatsNice implementation of a custom hook that follows React best practices with SWR. The conditional fetching pattern with the
shouldFetchparameter gives components control over when to load data.apps/web/hooks/useChat.ts (1)
1-6: Clean implementation of single chat fetching hookThis hook follows the same good patterns as
useChats, providing a consistent API for fetching a single chat by ID. The conditional fetch whenchatIdis undefined is handled properly.apps/web/app/api/chats/route.ts (1)
1-11: Secure API route with proper authenticationThe route handler is correctly wrapped with
withEmailAccountmiddleware to ensure proper authentication and authorization. The implementation extracts the email account ID from the request auth context and uses it to fetch only the chats that belong to the authenticated user.apps/web/utils/llms/index.ts (4)
12-13: Import additions for enhanced streaming capabilities.The addition of
smoothStreamand updatedMessagetype imports support the new word-level chunking feature and updated message handling.
174-175: Enhanced callback interface with additional result data.The
onFinishcallback signature now includes the full result object, providing more context to callback handlers.
204-205: Updated callback invocation with result parameter.The onFinish callback now receives both the completed text and the full result object.
169-170:Details
❓ Verification inconclusive
Updated message type from CoreMessage to Message.
Changing the parameter type from
CoreMessage[]toMessage[]aligns with the updated requirements for chat message handling.Verify that all places using this function have been updated to work with the new
Messagetype:
🏁 Script executed:
#!/bin/bash # Find all usages of chatCompletionStream function to check type compatibility rg --type=typescript "chatCompletionStream" -A 5 -B 5Length of output: 88
Let's broaden the search to all TypeScript files and drop the unrecognized type filter:
🏁 Script executed:
#!/bin/bash # Find all usages of chatCompletionStream across .ts/.tsx files rg "chatCompletionStream" -A 5 -B 5 --glob "*.ts" --glob "*.tsx"Length of output: 5218
Please verify all
chatCompletionStreamcall sites for the newMessage[]typeThe parameter has been updated from
CoreMessage[]toMessage[]in
apps/web/utils/llms/index.ts. Ensure each usage is still type-safe:• apps/web/utils/ai/assistant/chat.ts
– passesmessages; confirm that the localmessagesvariable is declared asMessage[](notCoreMessage[]).
• apps/web/app/api/ai/summarise/controller.ts
– usespromptonly (nomessages, which is optional).
• apps/web/app/api/ai/compose-autocomplete/route.ts
– usespromptonly (nomessages, which is optional).apps/web/app/api/chats/[chatId]/route.ts (1)
1-27: Well-structured API route with proper authentication and error handling.The GET handler is implemented with good practices:
- Uses authentication middleware to ensure the request is authorized
- Validates required parameters
- Returns appropriate error responses
- Uses clean response formatting
apps/web/prisma/schema.prisma (3)
569-579: Well-designed Chat model with appropriate relationships.The Chat model follows good database design principles:
- Contains standard fields (id, timestamps)
- Establishes proper relationship with EmailAccount
- Includes cascade delete for proper cleanup
- Has appropriate indexing for performance
587-590: Commented fields suggest planned future enhancements.The commented out fields for attachments and metadata indicate preparation for future features.
It might be worth tracking these as future tasks. Do you have a roadmap or ticket for implementing these features?
124-124: Added Chat relation to EmailAccount model.The relationship between EmailAccount and Chat is properly established.
apps/web/app/api/chat/route.ts (2)
84-92: Await message-saving to ensure durabilityThe HTTP response is returned immediately; if
saveChatMessagesfails, the client receives a 200 anyway.-onFinish: (messages: any) => { - saveChatMessages({ … }); -}, +onFinish: async (messages) => { + const ok = await saveChatMessages({ … }); + if (!ok) logger.error("Message persistence failed", { chatId: chat.id }); +},
47-55:⚠️ Potential issueUse
successflag fromsafeParsefor reliable validation
safeParsereturns{ success, data, error }. If parsing fails,dataisundefined; accessing it later will throw.-const { data, error } = assistantInputSchema.safeParse(json); -if (error) +const parse = assistantInputSchema.safeParse(json); +if (!parse.success) return NextResponse.json({ error: error.message }, { status: 400 }); -const { data } = parse; // guaranteed to existLikely an incorrect or invalid review comment.
| CREATE TABLE "ChatMessage" ( | ||
| "id" TEXT NOT NULL, | ||
| "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
| "updatedAt" TIMESTAMP(3) NOT NULL, | ||
| "role" TEXT NOT NULL, | ||
| "content" TEXT NOT NULL, | ||
| "chatId" TEXT NOT NULL, | ||
|
|
||
| CONSTRAINT "ChatMessage_pkey" PRIMARY KEY ("id") | ||
| ); |
There was a problem hiding this comment.
Schema is missing attachments / metadata columns used by the code
saveChatMessages() inserts attachments and metadata, but the table definition lacks them, causing runtime failures (Unknown arg attachments …).
"content" TEXT NOT NULL,
"chatId" TEXT NOT NULL,
+ "attachments" JSONB,
+ "metadata" JSONB,Add the columns (or drop the fields in the write-path) and create matching Prisma model attributes.
📝 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.
| CREATE TABLE "ChatMessage" ( | |
| "id" TEXT NOT NULL, | |
| "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| "updatedAt" TIMESTAMP(3) NOT NULL, | |
| "role" TEXT NOT NULL, | |
| "content" TEXT NOT NULL, | |
| "chatId" TEXT NOT NULL, | |
| CONSTRAINT "ChatMessage_pkey" PRIMARY KEY ("id") | |
| ); | |
| CREATE TABLE "ChatMessage" ( | |
| "id" TEXT NOT NULL, | |
| "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| "updatedAt" TIMESTAMP(3) NOT NULL, | |
| "role" TEXT NOT NULL, | |
| "content" TEXT NOT NULL, | |
| "chatId" TEXT NOT NULL, | |
| "attachments" JSONB, | |
| "metadata" JSONB, | |
| CONSTRAINT "ChatMessage_pkey" PRIMARY KEY ("id") | |
| ); |
🤖 Prompt for AI Agents
In apps/web/prisma/migrations/20250521104911_chat/migration.sql around lines 12
to 21, the ChatMessage table is missing the attachments and metadata columns
that the code expects when calling saveChatMessages(), causing runtime errors.
Add appropriate columns for attachments and metadata to the table schema,
ensuring their data types match the expected structure (e.g., JSON or TEXT).
Also, update the corresponding Prisma model to include these fields so the
schema and code remain consistent.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (5)
apps/web/app/api/chat/route.ts (5)
82-82: Replaceas anytype cast with proper typingUsing
as anybypasses TypeScript's type checking. This could lead to runtime errors if the structure ofdbMsg.partsdoesn't match what's expected.- parts: dbMsg.parts as any, + parts: dbMsg.parts as Prisma.JsonValue,
95-97: Consider handling attachments consistentlyThe code contains commented-out attachment handling. Either implement the feature fully or remove the commented code to avoid confusion.
104-109: Validate array is not empty before usingat(-1)The
getTrailingMessageIdfunction checks if the trailing message exists but the current code assumes there's at least one assistant message in the filtered array. Consider adding a check.- const assistantId = getTrailingMessageId({ - messages: response.messages.filter( - (message: { role: string }) => message.role === "assistant", - ), - }); + const assistantMessages = response.messages.filter( + (message: { role: string }) => message.role === "assistant", + ); + + if (assistantMessages.length === 0) { + throw new Error("No assistant messages found in response!"); + } + + const assistantId = getTrailingMessageId({ + messages: assistantMessages, + });
123-126: Simplify nullable JSON handlingThe conditional check and explicit use of
Prisma.JsonNullappears unnecessarily complex for handling message parts.- parts: assistantMessage.parts - ? (assistantMessage.parts as Prisma.InputJsonValue) - : Prisma.JsonNull, + parts: assistantMessage.parts || [],
135-147: Enhance error handling in createNewChatThe function currently logs the error but doesn't provide specific details about what went wrong. Consider adding more specific error handling.
async function createNewChat(emailAccountId: string) { try { const newChat = await prisma.chat.create({ data: { emailAccountId }, include: { messages: true }, }); logger.info("New chat created", { chatId: newChat.id, emailAccountId }); return newChat; } catch (error) { - logger.error("Failed to create new chat", { error, emailAccountId }); + if (error instanceof Prisma.PrismaClientKnownRequestError) { + logger.error("Database error creating chat", { + code: error.code, + meta: error.meta, + emailAccountId + }); + } else { + logger.error("Failed to create new chat", { + error: error instanceof Error ? error.message : String(error), + emailAccountId + }); + } return undefined; } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
📒 Files selected for processing (6)
apps/web/app/api/ai/summarise/controller.ts(1 hunks)apps/web/app/api/chat/route.ts(2 hunks)apps/web/prisma/migrations/20250521132820_message_parts/migration.sql(1 hunks)apps/web/prisma/schema.prisma(3 hunks)apps/web/utils/ai/assistant/chat.ts(3 hunks)apps/web/utils/llms/index.ts(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/web/prisma/schema.prisma
- apps/web/utils/llms/index.ts
- apps/web/utils/ai/assistant/chat.ts
🔇 Additional comments (6)
apps/web/app/api/ai/summarise/controller.ts (1)
27-28: Good adaptation to the new API signature.The change correctly updates the
onFinishcallback to work with the new richer result object structure, extracting just the text content that's needed for the summary storage. This aligns well with the PR's chat history implementation while maintaining the original functionality.apps/web/prisma/migrations/20250521132820_message_parts/migration.sql (1)
1-11: Schema migration removes content column and adds JSON parts fieldThis migration updates the
ChatMessagetable to use a more structured format, replacing the plain textcontentcolumn with a structuredpartsJSON field. The migration explicitly warns about data loss and requirements.A few considerations:
- Ensure you have a data migration strategy if this is applied to a production database with existing chat messages
- Consider adding a default empty JSON array (
'[]') to make the migration more robust when applied to non-empty tablesapps/web/app/api/chat/route.ts (4)
161-176: LGTM: Role conversion function is well-implementedThe
convertDbRoleToSdkRolefunction correctly handles role mapping without case conversion issues, addressing a previous concern with role conversion.
20-43: Schema validation is thoroughThe input validation schema is well-defined with proper constraints on text length and structure. Good job implementing proper validation.
58-74: Strong security with chat ownership verificationExcellent implementation of authorization checks to ensure users can only access their own chats.
103-129: Well-structured callback for saving assistant messagesThe
onFinishcallback effectively handles saving assistant messages after processing completes, ensuring message persistence.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/web/components/assistant-chat/multimodal-input.tsx (1)
100-100: Consider documenting the history manipulation approach.The commented-out history manipulation code suggests there may be a new approach to URL management for chats. Consider adding a comment explaining the new approach or why this functionality was removed, to help future developers understand the design decision.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
apps/web/app/(app)/[emailAccountId]/assistant/page.tsx(1 hunks)apps/web/app/api/chat/route.ts(2 hunks)apps/web/components/assistant-chat/chat.tsx(8 hunks)apps/web/components/assistant-chat/multimodal-input.tsx(2 hunks)apps/web/hooks/useChats.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- apps/web/app/(app)/[emailAccountId]/assistant/page.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/web/hooks/useChats.ts
- apps/web/components/assistant-chat/chat.tsx
- apps/web/app/api/chat/route.ts
🔇 Additional comments (2)
apps/web/components/assistant-chat/multimodal-input.tsx (2)
36-36: Good change makingchatIdoptional.Making the
chatIdprop optional is a good decision that aligns with the broader application changes for persistent chat support. This change allows the component to function properly whether or not a chat is currently selected, supporting the dynamic chat loading and selection functionality introduced in this PR.
110-110: Correctly updated dependency array.The dependency array update is consistent with making
chatIdoptional. RemovingchatIdfrom the dependencies prevents unnecessary re-renders when the chat ID changes and properly reflects that the callback no longer uses this value internally.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/web/hooks/useChatMessages.ts (1)
4-6: Consider adding revalidation options for improved user experience.While the current implementation is solid, you might want to consider adding revalidation options to control refetching behavior:
export function useChatMessages(chatId?: string) { - return useSWR<GetChatResponse>(chatId ? `/api/chats/${chatId}` : null); + return useSWR<GetChatResponse>( + chatId ? `/api/chats/${chatId}` : null, + { + revalidateOnFocus: false, // Prevent refetching when tab regains focus + dedupingInterval: 10000, // Reduce duplicate requests + } + ); }This would improve performance by reducing unnecessary refetches, especially important for chat applications where constant refetching might not be desired.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/web/app/(app)/[emailAccountId]/assistant/page.tsx(2 hunks)apps/web/app/(app)/[emailAccountId]/automation/AssistantTabs.tsx(1 hunks)apps/web/components/assistant-chat/chat.tsx(8 hunks)apps/web/hooks/useChatMessages.ts(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- apps/web/app/(app)/[emailAccountId]/assistant/page.tsx
- apps/web/app/(app)/[emailAccountId]/automation/AssistantTabs.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/web/components/assistant-chat/chat.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/web/hooks/useChatMessages.ts (1)
apps/web/app/api/chats/[chatId]/route.ts (1)
GetChatResponse(5-5)
🔇 Additional comments (1)
apps/web/hooks/useChatMessages.ts (1)
1-6: Well-implemented hook for chat message retrieval.This hook is clean, focused, and follows SWR patterns correctly. It conditionally fetches chat data only when a valid chatId is provided, which prevents unnecessary API calls. The explicit typing with
GetChatResponseensures type safety throughout the application.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/web/app/api/rules/pending/route.ts (1)
16-22: Consider adding an index to optimize this query.The database query is well-structured, using
findFirstwith minimal field selection for better performance. For frequently accessed routes, consider adding a database index onemailAccountIdandautomatefields if not already present.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
.cursor/rules/get-api-route.mdc(2 hunks).cursor/rules/memory.mdc(0 hunks)apps/web/app/(app)/[emailAccountId]/assistant/page.tsx(1 hunks)apps/web/app/(app)/[emailAccountId]/automation/AssistantTabs.tsx(5 hunks)apps/web/app/(app)/[emailAccountId]/automation/page.tsx(0 hunks)apps/web/app/api/rules/pending/route.ts(1 hunks)
💤 Files with no reviewable changes (2)
- apps/web/app/(app)/[emailAccountId]/automation/page.tsx
- .cursor/rules/memory.mdc
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/web/app/(app)/[emailAccountId]/assistant/page.tsx
- apps/web/app/(app)/[emailAccountId]/automation/AssistantTabs.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/web/app/api/rules/pending/route.ts (1)
apps/web/utils/middleware.ts (2)
withEmailAccount(190-194)RequestWithEmailAccount(28-34)
🔇 Additional comments (3)
apps/web/app/api/rules/pending/route.ts (1)
10-14: LGTM! Proper use of authentication middleware.The API route correctly uses the
withEmailAccountmiddleware to ensure authenticated access and extract the current email account ID. This approach aligns with the updated guidelines in.cursor/rules/get-api-route.mdc..cursor/rules/get-api-route.mdc (2)
21-21: LGTM! Updated example with appropriate middleware.The example code now correctly demonstrates the use of
withEmailAccountinstead ofwithAuth, which is consistent with the new API routes being implemented in the codebase.
41-44: LGTM! Clear explanation of middleware options.The updated guidelines provide a clear distinction between
withAuthandwithEmailAccount, helping developers choose the appropriate middleware based on whether they need user-level or email account-level context. This aligns well with the implementation inapps/web/app/api/rules/pending/route.ts.
Summary by CodeRabbit
New Features
Improvements
Chores