diff --git a/surfsense_web/app/dashboard/[search_space_id]/chats/chats-client.tsx b/surfsense_web/app/dashboard/[search_space_id]/chats/chats-client.tsx index 1cfec056a..822b749e4 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/chats/chats-client.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/chats/chats-client.tsx @@ -55,14 +55,14 @@ import { export interface Chat { created_at: string; id: number; - type: "DOCUMENT" | "CHAT"; + type: "QNA"; title: string; search_space_id: number; state_version: number; } export interface ChatDetails { - type: "DOCUMENT" | "CHAT"; + type: "QNA"; title: string; initial_connectors: string[]; messages: any[]; diff --git a/surfsense_web/atoms/chats/chat-mutation.atoms.ts b/surfsense_web/atoms/chats/chat-mutation.atoms.ts index a6dd1c9dc..fee69f9f7 100644 --- a/surfsense_web/atoms/chats/chat-mutation.atoms.ts +++ b/surfsense_web/atoms/chats/chat-mutation.atoms.ts @@ -2,6 +2,7 @@ import { atomWithMutation } from "jotai-tanstack-query"; import { toast } from "sonner"; import type { Chat } from "@/app/dashboard/[search_space_id]/chats/chats-client"; import { deleteChat } from "@/lib/apis/chats.api"; +import { chatApiService } from "@/lib/apis/chats-api.service"; import { cacheKeys } from "@/lib/query-client/cache-keys"; import { queryClient } from "@/lib/query-client/client"; import { activeSearchSpaceIdAtom } from "../seach-spaces/seach-space-queries.atom"; @@ -14,14 +15,7 @@ export const deleteChatMutationAtom = atomWithMutation((get) => { mutationKey: cacheKeys.activeSearchSpace.chats(searchSpaceId ?? ""), enabled: !!searchSpaceId && !!authToken, mutationFn: async (chatId: number) => { - if (!authToken) { - throw new Error("No authentication token found"); - } - if (!searchSpaceId) { - throw new Error("No search space id found"); - } - - return deleteChat(chatId, authToken); + return chatApiService.deleteChat({ id: chatId }); }, onSuccess: (_, chatId) => { diff --git a/surfsense_web/atoms/chats/chat-querie.atoms.ts b/surfsense_web/atoms/chats/chat-querie.atoms.ts index 3603bf9bb..9ff913432 100644 --- a/surfsense_web/atoms/chats/chat-querie.atoms.ts +++ b/surfsense_web/atoms/chats/chat-querie.atoms.ts @@ -4,6 +4,7 @@ import type { ChatDetails } from "@/app/dashboard/[search_space_id]/chats/chats- import type { PodcastItem } from "@/app/dashboard/[search_space_id]/podcasts/podcasts-client"; import { activeSearchSpaceIdAtom } from "@/atoms/seach-spaces/seach-space-queries.atom"; import { fetchChatDetails, fetchChatsBySearchSpace } from "@/lib/apis/chats.api"; +import { chatApiService } from "@/lib/apis/chats-api.service"; import { getPodcastByChatId } from "@/lib/apis/podcasts.api"; import { cacheKeys } from "@/lib/query-client/cache-keys"; @@ -32,7 +33,7 @@ export const activeChatAtom = atomWithQuery((get) => { const [podcast, chatDetails] = await Promise.all([ getPodcastByChatId(activeChatId, authToken), - fetchChatDetails(activeChatId, authToken), + chatApiService.getChatDetails({ id: Number(activeChatId) }), ]); return { chatId: activeChatId, chatDetails, podcast }; @@ -48,14 +49,7 @@ export const activeSearchSpaceChatsAtom = atomWithQuery((get) => { queryKey: cacheKeys.activeSearchSpace.chats(searchSpaceId ?? ""), enabled: !!searchSpaceId && !!authToken, queryFn: async () => { - if (!authToken) { - throw new Error("No authentication token found"); - } - if (!searchSpaceId) { - throw new Error("No search space id found"); - } - - return fetchChatsBySearchSpace(searchSpaceId, authToken); + return chatApiService.getChatsBySearchSpace({ search_space_id: Number(searchSpaceId) }); }, }; }); diff --git a/surfsense_web/lib/apis/chats-api.service.api.ts b/surfsense_web/lib/apis/chats-api.service.api.ts deleted file mode 100644 index ae7aa9837..000000000 --- a/surfsense_web/lib/apis/chats-api.service.api.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { Message } from "@ai-sdk/react"; -import { z } from "zod"; -import { ResearchMode } from "@/components/chat/types"; -import { - type CreateChatRequest, - chatDetails, - chatSummary, - createChatRequest, - type DeleteChatRequest, - deleteChatRequest, - deleteChatResponse, - type GetChatDetailsRequest, - type GetChatsBySearchSpaceRequest, - getChatDetailsRequest, - getChatsBySearchSpaceRequest, - type UpdateChatRequest, - updateChatRequest, -} from "@/contracts/types/chat.types"; -import { baseApiService } from "./base-api.service"; - -export class ChatApiService { - fetchChatDetails = async (request: GetChatDetailsRequest) => { - // Validate the request - const parsedRequest = getChatDetailsRequest.safeParse(request); - - if (!parsedRequest.success) { - throw new Error(`Invalid request: ${parsedRequest.error.message}`); - } - - return baseApiService.get(`/api/v1/chats/${request.id}`, chatDetails); - }; - - fetchChatsBySearchSpace = async (request: GetChatsBySearchSpaceRequest) => { - // Validate the request - const parsedRequest = getChatsBySearchSpaceRequest.safeParse(request); - - if (!parsedRequest.success) { - throw new Error(`Invalid request: ${parsedRequest.error.message}`); - } - - return baseApiService.get( - `/api/v1/chats?search_space_id=${request.search_space_id}`, - z.array(chatSummary) - ); - }; - - deleteChat = async (request: DeleteChatRequest) => { - // Validate the request - const parsedRequest = deleteChatRequest.safeParse(request); - - if (!parsedRequest.success) { - throw new Error(`Invalid request: ${parsedRequest.error.message}`); - } - - return baseApiService.delete(`/api/v1/chats/${request.id}`, undefined, deleteChatResponse); - }; - - createChat = async (request: CreateChatRequest) => { - // Validate the request - const parsedRequest = createChatRequest.safeParse(request); - - if (!parsedRequest.success) { - throw new Error(`Invalid request: ${parsedRequest.error.message}`); - } - - const { type, title, initial_connectors, messages, search_space_id } = parsedRequest.data; - - return baseApiService.post( - `/api/v1/chats`, - { - type, - title, - initial_connectors, - messages, - search_space_id, - }, - chatSummary - ); - }; - - updateChat = async (request: UpdateChatRequest) => { - // Validate the request - const parsedRequest = updateChatRequest.safeParse(request); - - if (!parsedRequest.success) { - throw new Error(`Invalid request: ${parsedRequest.error.message}`); - } - - const { type, title, initial_connectors, messages, search_space_id, id } = parsedRequest.data; - - return baseApiService.put( - `/api/v1/chats/${id}`, - { - type, - title, - initial_connectors, - messages, - search_space_id, - }, - chatSummary - ); - }; -} diff --git a/surfsense_web/lib/apis/chats-api.service.ts b/surfsense_web/lib/apis/chats-api.service.ts new file mode 100644 index 000000000..69cfab831 --- /dev/null +++ b/surfsense_web/lib/apis/chats-api.service.ts @@ -0,0 +1,130 @@ +import { z } from "zod"; +import { + type CreateChatRequest, + chatDetails, + chatSummary, + createChatRequest, + type DeleteChatRequest, + deleteChatRequest, + deleteChatResponse, + type GetChatDetailsRequest, + type GetChatsBySearchSpaceRequest, + getChatDetailsRequest, + getChatsBySearchSpaceRequest, + type UpdateChatRequest, + updateChatRequest, +} from "@/contracts/types/chat.types"; +import { ValidationError } from "../error"; +import { baseApiService } from "./base-api.service"; + +export class ChatApiService { + getChatDetails = async (request: GetChatDetailsRequest) => { + // Validate the request + const parsedRequest = getChatDetailsRequest.safeParse(request); + + if (!parsedRequest.success) { + console.error("Invalid request:", parsedRequest.error); + + // Format a user frendly error message + const errorMessage = parsedRequest.error.errors.map((err) => err.message).join(", "); + throw new ValidationError(`Invalid request: ${errorMessage}`); + } + + return baseApiService.get(`/api/v1/chats/${request.id}`, chatDetails); + }; + + getChatsBySearchSpace = async (request: GetChatsBySearchSpaceRequest) => { + // Validate the request + const parsedRequest = getChatsBySearchSpaceRequest.safeParse(request); + + if (!parsedRequest.success) { + console.error("Invalid request:", parsedRequest.error); + + // Format a user frendly error message + const errorMessage = parsedRequest.error.errors.map((err) => err.message).join(", "); + throw new ValidationError(`Invalid request: ${errorMessage}`); + } + + return baseApiService.get( + `/api/v1/chats?search_space_id=${request.search_space_id}`, + z.array(chatSummary) + ); + }; + + deleteChat = async (request: DeleteChatRequest) => { + // Validate the request + const parsedRequest = deleteChatRequest.safeParse(request); + + if (!parsedRequest.success) { + console.error("Invalid request:", parsedRequest.error); + + // Format a user frendly error message + const errorMessage = parsedRequest.error.errors.map((err) => err.message).join(", "); + throw new ValidationError(`Invalid request: ${errorMessage}`); + } + + return baseApiService.delete(`/api/v1/chats/${request.id}`, deleteChatResponse); + }; + + createChat = async (request: CreateChatRequest) => { + // Validate the request + const parsedRequest = createChatRequest.safeParse(request); + + if (!parsedRequest.success) { + console.error("Invalid request:", parsedRequest.error); + + // Format a user frendly error message + const errorMessage = parsedRequest.error.errors.map((err) => err.message).join(", "); + throw new ValidationError(`Invalid request: ${errorMessage}`); + } + + const { type, title, initial_connectors, messages, search_space_id } = parsedRequest.data; + + return baseApiService.post( + `/api/v1/chats`, + + chatSummary, + { + body: { + type, + title, + initial_connectors, + messages, + search_space_id, + }, + } + ); + }; + + updateChat = async (request: UpdateChatRequest) => { + // Validate the request + const parsedRequest = updateChatRequest.safeParse(request); + + if (!parsedRequest.success) { + console.error("Invalid request:", parsedRequest.error); + + // Format a user frendly error message + const errorMessage = parsedRequest.error.errors.map((err) => err.message).join(", "); + throw new ValidationError(`Invalid request: ${errorMessage}`); + } + + const { type, title, initial_connectors, messages, search_space_id, id } = parsedRequest.data; + + return baseApiService.put( + `/api/v1/chats/${id}`, + + chatSummary, + { + body: { + type, + title, + initial_connectors, + messages, + search_space_id, + }, + } + ); + }; +} + +export const chatApiService = new ChatApiService();