diff --git a/apps/web/src/api/buster_rest/chats/index.ts b/apps/web/src/api/buster_rest/chats/index.ts index ba46f1efc..8fae0b36f 100644 --- a/apps/web/src/api/buster_rest/chats/index.ts +++ b/apps/web/src/api/buster_rest/chats/index.ts @@ -1,3 +1,4 @@ export * from './queryRequests'; export * from './queryRequestsV2'; export * from './requests'; +export * from './requestsV2'; diff --git a/apps/web/src/api/buster_rest/chats/queryRequests.ts b/apps/web/src/api/buster_rest/chats/queryRequests.ts index 9b19e8949..1d2663abe 100644 --- a/apps/web/src/api/buster_rest/chats/queryRequests.ts +++ b/apps/web/src/api/buster_rest/chats/queryRequests.ts @@ -26,7 +26,6 @@ import { deleteChat, duplicateChat, getChat, - getListChats, getListLogs, shareChat, unshareChat, @@ -34,12 +33,13 @@ import { updateChatMessageFeedback, updateChatShare, } from './requests'; +import { getListChats } from './requestsV2'; export const useGetListChats = ( - filters?: Omit[0], 'page_token' | 'page_size'> + filters?: Omit[0], 'page' | 'page_size'> ) => { const filtersCompiled: Parameters[0] = useMemo( - () => ({ admin_view: false, page_token: 0, page_size: 5000, ...filters }), + () => ({ admin_view: false, page: 1, page_size: 5000, ...filters }), [filters] ); diff --git a/apps/web/src/api/buster_rest/chats/requests.test.ts b/apps/web/src/api/buster_rest/chats/requests.test.ts index 4cc7caac8..7612661bf 100644 --- a/apps/web/src/api/buster_rest/chats/requests.test.ts +++ b/apps/web/src/api/buster_rest/chats/requests.test.ts @@ -1,12 +1,17 @@ import type { ChatListItem } from '@buster/server-shared/chats'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { mainApi } from '../instances'; +import { mainApiV2 } from '../instances'; -// Mock the mainApi +// Mock the mainApi and mainApiV2 vi.mock('../instances', () => ({ mainApi: { get: vi.fn(), }, + mainApiV2: { + get: vi.fn(), + post: vi.fn(), + delete: vi.fn(), + }, })); describe('Chat API Requests', () => { @@ -36,17 +41,19 @@ describe('Chat API Requests', () => { ]; // Setup mock response - (mainApi.get as any).mockResolvedValueOnce({ data: mockChats }); + (mainApiV2.get as any).mockResolvedValueOnce({ + data: { data: mockChats } + }); // Import the function we want to test - const { getListChats } = await import('./requests'); + const { getListChats } = await import('./requestsV2'); // Execute the function const result = await getListChats(); // Verify the API was called with correct parameters - expect(mainApi.get).toHaveBeenCalledWith('/chats', { - params: { page_token: 0, page_size: 3500 }, + expect(mainApiV2.get).toHaveBeenCalledWith('/chats', { + params: { page: 1, page_size: 3500 }, }); // Verify the result matches the mock data diff --git a/apps/web/src/api/buster_rest/chats/requests.ts b/apps/web/src/api/buster_rest/chats/requests.ts index f8196b9cb..2c895743a 100644 --- a/apps/web/src/api/buster_rest/chats/requests.ts +++ b/apps/web/src/api/buster_rest/chats/requests.ts @@ -4,8 +4,6 @@ import type { DuplicateChatResponse, GetChatRequest, GetChatResponse, - GetChatsListRequest, - GetChatsListResponse, GetLogsListRequest, GetLogsListResponse, ShareChatResponse, @@ -23,16 +21,6 @@ import { mainApi, mainApiV2 } from '../instances'; const CHATS_BASE = '/chats'; -// Client-side fetch version -export const getListChats = async (params?: GetChatsListRequest): Promise => { - const { page_token = 0, page_size = 3500 } = params || {}; - return mainApi - .get(`${CHATS_BASE}`, { - params: { page_token, page_size }, - }) - .then((res) => res.data); -}; - export const getListLogs = async (params?: GetLogsListRequest): Promise => { const { page_token = 0, page_size = 3500 } = params || {}; return mainApi diff --git a/apps/web/src/api/buster_rest/chats/requestsV2.ts b/apps/web/src/api/buster_rest/chats/requestsV2.ts index 85fefeb2b..476280d4e 100644 --- a/apps/web/src/api/buster_rest/chats/requestsV2.ts +++ b/apps/web/src/api/buster_rest/chats/requestsV2.ts @@ -1,6 +1,22 @@ -import type { ChatCreateRequest, ChatWithMessages } from '@buster/server-shared/chats'; +import type { + ChatCreateRequest, + ChatWithMessages, + GetChatsListResponseV2, + GetChatsRequestV2, +} from '@buster/server-shared/chats'; import mainApi, { mainApiV2 } from '../instances'; +export const getListChats = async ( + params?: GetChatsRequestV2 +): Promise => { + const { page = 1, page_size = 3500 } = params || {}; + return mainApiV2 + .get(`/chats`, { + params: { page, page_size }, + }) + .then((res) => res.data.data); +}; + export const createNewChat = async (props: ChatCreateRequest) => { return mainApiV2.post('/chats', props).then((res) => res.data); }; diff --git a/apps/web/src/api/query_keys/chat.ts b/apps/web/src/api/query_keys/chat.ts index da70c910b..3986dd5df 100644 --- a/apps/web/src/api/query_keys/chat.ts +++ b/apps/web/src/api/query_keys/chat.ts @@ -2,7 +2,8 @@ import type { ChatListItem } from '@buster/server-shared/chats'; import { queryOptions } from '@tanstack/react-query'; import type { BusterChatMessage, IBusterChat } from '@/api/asset_interfaces/chat'; import type { BusterMetricData } from '@/api/asset_interfaces/metric/metricDataInterfaces'; -import type { getListChats, getListLogs } from '@/api/buster_rest/chats/requests'; +import type { getListLogs } from '@/api/buster_rest/chats/requests'; +import type { getListChats } from '@/api/buster_rest/chats/requestsV2'; const chatsGetChat = (chatId: string) => queryOptions({ @@ -25,9 +26,7 @@ const chatsMessagesFetchingData = (messageId: string) => enabled: !!messageId, }); -const chatsGetList = ( - filters?: Omit[0], 'page_token' | 'page_size'> -) => +const chatsGetList = (filters?: Omit[0], 'page' | 'page_size'>) => queryOptions({ queryKey: [ 'chats', diff --git a/packages/database/src/queries/chats/list-chats.ts b/packages/database/src/queries/chats/list-chats.ts index 4c52b8dc1..a0495018a 100644 --- a/packages/database/src/queries/chats/list-chats.ts +++ b/packages/database/src/queries/chats/list-chats.ts @@ -9,12 +9,8 @@ import { users, usersToOrganizations, } from '../../schema'; -import type { ChatListItem } from '../../schema-types'; -import { - type PaginatedResponse, - PaginationInputSchema, - createPaginatedResponse, -} from '../shared-types'; +import type { ChatListItem, PaginatedResponse } from '../../schema-types'; +import { PaginationInputSchema, createPaginatedResponse } from '../../schema-types'; export const ListChatsRequestSchema = z .object({ diff --git a/packages/database/src/queries/reports/get-reports-list.ts b/packages/database/src/queries/reports/get-reports-list.ts index bd3a3260d..d55093716 100644 --- a/packages/database/src/queries/reports/get-reports-list.ts +++ b/packages/database/src/queries/reports/get-reports-list.ts @@ -2,9 +2,12 @@ import { type InferSelectModel, and, count, desc, eq, gte, isNull, like, lte } f import { z } from 'zod'; import { db } from '../../connection'; import { reportFiles, users } from '../../schema'; +import { + type PaginatedResponse, + createPaginatedResponse, + withPagination, +} from '../../schema-types'; import { getUserOrganizationId } from '../organizations'; -import { type PaginatedResponse, createPaginatedResponse } from '../shared-types'; -import { withPagination } from '../shared-types/with-pagination'; export const GetReportsListInputSchema = z.object({ userId: z.string().uuid('User ID must be a valid UUID'), diff --git a/packages/database/src/queries/reports/get-reports-with-permissions.ts b/packages/database/src/queries/reports/get-reports-with-permissions.ts index f1d72988a..701ef2b54 100644 --- a/packages/database/src/queries/reports/get-reports-with-permissions.ts +++ b/packages/database/src/queries/reports/get-reports-with-permissions.ts @@ -2,9 +2,12 @@ import { type SQL, and, count, desc, eq, exists, isNull, ne, or, sql } from 'dri import { z } from 'zod'; import { db } from '../../connection'; import { assetPermissions, reportFiles, teamsToUsers, users } from '../../schema'; +import { + type PaginatedResponse, + createPaginatedResponse, + withPagination, +} from '../../schema-types'; import { getUserOrganizationId } from '../organizations'; -import { type PaginatedResponse, createPaginatedResponse } from '../shared-types'; -import { withPagination } from '../shared-types/with-pagination'; export const GetReportsWithPermissionsInputSchema = z.object({ userId: z.string().uuid('User ID must be a valid UUID'), diff --git a/packages/database/src/queries/search/search-queries.ts b/packages/database/src/queries/search/search-queries.ts index 24436f5af..8c4b78cde 100644 --- a/packages/database/src/queries/search/search-queries.ts +++ b/packages/database/src/queries/search/search-queries.ts @@ -6,7 +6,7 @@ import { type PaginatedResponse, PaginationInputSchema, createPaginatedResponse, -} from '../shared-types'; +} from '../../schema-types'; import { createPermissionedAssetsSubquery } from './access-control-helpers'; import { AssetTypeSchema } from '../../schema-types/asset'; diff --git a/packages/database/src/queries/shared-types/index.ts b/packages/database/src/queries/shared-types/index.ts deleted file mode 100644 index 272b779db..000000000 --- a/packages/database/src/queries/shared-types/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// Export pagination types and utilities -export * from './pagination.types'; -export * from './with-pagination'; diff --git a/packages/database/src/queries/shared-types/pagination.types.ts b/packages/database/src/queries/shared-types/pagination.types.ts deleted file mode 100644 index 564c67180..000000000 --- a/packages/database/src/queries/shared-types/pagination.types.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { z } from 'zod'; - -// Pagination input schema for validation -export const PaginationInputSchema = z.object({ - page: z.number().min(1).optional().default(1), - page_size: z.number().min(1).max(1000).optional().default(250), -}); - -export type PaginationInput = z.infer; - -// Pagination metadata that's returned with results -export interface PaginationMetadata { - page: number; - page_size: number; - total: number; - total_pages: number; -} - -// Generic paginated response type -export interface PaginatedResponse { - data: T[]; - pagination: PaginationMetadata; -} - -// Type helper for creating paginated API responses -export type WithPagination = { - [K in keyof T]: T[K]; -} & { - pagination: PaginationMetadata; -}; diff --git a/packages/database/src/queries/users/users-to-organizations.ts b/packages/database/src/queries/users/users-to-organizations.ts index 9e2f83ac0..ac4b7a994 100644 --- a/packages/database/src/queries/users/users-to-organizations.ts +++ b/packages/database/src/queries/users/users-to-organizations.ts @@ -8,9 +8,12 @@ import { usersToOrganizations, } from '../../schema'; import { UserOrganizationRoleSchema, UserOrganizationStatusSchema } from '../../schema-types'; +import { + type PaginatedResponse, + createPaginatedResponse, + withPagination, +} from '../../schema-types'; import { getUserOrganizationId } from '../organizations/organizations'; -import { type PaginatedResponse, createPaginatedResponse } from '../shared-types'; -import { withPagination } from '../shared-types/with-pagination'; // Type-safe schema types type User = InferSelectModel; diff --git a/packages/database/src/schema-types/index.ts b/packages/database/src/schema-types/index.ts index 84bf694a7..e7ceb7684 100644 --- a/packages/database/src/schema-types/index.ts +++ b/packages/database/src/schema-types/index.ts @@ -37,3 +37,5 @@ export * from './github'; export * from './search'; export * from './chat'; + +export * from './pagination'; diff --git a/packages/database/src/queries/shared-types/with-pagination.ts b/packages/database/src/schema-types/pagination.ts similarity index 74% rename from packages/database/src/queries/shared-types/with-pagination.ts rename to packages/database/src/schema-types/pagination.ts index 899943b64..14b3bcacf 100644 --- a/packages/database/src/queries/shared-types/with-pagination.ts +++ b/packages/database/src/schema-types/pagination.ts @@ -1,6 +1,36 @@ import type { SQL } from 'drizzle-orm'; import type { PgColumn, PgSelect } from 'drizzle-orm/pg-core'; -import type { PaginatedResponse, PaginationMetadata } from './pagination.types'; +import { z } from 'zod'; + +// Pagination input schema for validation +export const PaginationInputSchema = z.object({ + page: z.coerce.number().min(1).optional().default(1), + page_size: z.coerce.number().min(1).max(5000).optional().default(250), +}); + +export type PaginationInput = z.infer; + +export const PaginationSchema = z.object({ + page: z.number(), + page_size: z.number(), + total: z.number(), + total_pages: z.number(), +}); + +export type PaginationMetadata = z.infer; + +// Generic paginated response type +export interface PaginatedResponse { + data: T[]; + pagination: PaginationMetadata; +} + +// Type helper for creating paginated API responses +export type WithPagination = { + [K in keyof T]: T[K]; +} & { + pagination: PaginationMetadata; +}; /** * Adds pagination to a Drizzle query using the dynamic query builder pattern diff --git a/packages/server-shared/src/type-utilities/pagination.ts b/packages/server-shared/src/type-utilities/pagination.ts index 806fecfa1..edbdad1f1 100644 --- a/packages/server-shared/src/type-utilities/pagination.ts +++ b/packages/server-shared/src/type-utilities/pagination.ts @@ -1,13 +1,13 @@ +import { + PaginationInputSchema, + type PaginationMetadata, + PaginationSchema, +} from '@buster/database/schema-types'; import { z } from 'zod'; -export const PaginationSchema = z.object({ - page: z.number(), - page_size: z.number(), - total: z.number(), - total_pages: z.number(), -}); +export { PaginationSchema, type PaginationMetadata } from '@buster/database/schema-types'; -export type Pagination = z.infer; +export type Pagination = PaginationMetadata; export const PaginatedResponseSchema = (schema: z.ZodType) => z.object({ @@ -17,7 +17,4 @@ export const PaginatedResponseSchema = (schema: z.ZodType) => export type PaginatedResponse = z.infer>>; -export const PaginatedRequestSchema = z.object({ - page: z.coerce.number().min(1).optional().default(1), - page_size: z.coerce.number().min(1).max(5000).default(250), -}); +export const PaginatedRequestSchema = PaginationInputSchema;