migrate /chats to use the v2 endpoint from the frontend

This commit is contained in:
Wells Bunker 2025-09-25 11:44:35 -06:00
parent 41efcbfa54
commit 7bcae1e5d5
No known key found for this signature in database
GPG Key ID: DB16D6F2679B78FC
16 changed files with 96 additions and 84 deletions

View File

@ -1,3 +1,4 @@
export * from './queryRequests'; export * from './queryRequests';
export * from './queryRequestsV2'; export * from './queryRequestsV2';
export * from './requests'; export * from './requests';
export * from './requestsV2';

View File

@ -26,7 +26,6 @@ import {
deleteChat, deleteChat,
duplicateChat, duplicateChat,
getChat, getChat,
getListChats,
getListLogs, getListLogs,
shareChat, shareChat,
unshareChat, unshareChat,
@ -34,12 +33,13 @@ import {
updateChatMessageFeedback, updateChatMessageFeedback,
updateChatShare, updateChatShare,
} from './requests'; } from './requests';
import { getListChats } from './requestsV2';
export const useGetListChats = ( export const useGetListChats = (
filters?: Omit<Parameters<typeof getListChats>[0], 'page_token' | 'page_size'> filters?: Omit<Parameters<typeof getListChats>[0], 'page' | 'page_size'>
) => { ) => {
const filtersCompiled: Parameters<typeof getListChats>[0] = useMemo( const filtersCompiled: Parameters<typeof getListChats>[0] = useMemo(
() => ({ admin_view: false, page_token: 0, page_size: 5000, ...filters }), () => ({ admin_view: false, page: 1, page_size: 5000, ...filters }),
[filters] [filters]
); );

View File

@ -1,12 +1,17 @@
import type { ChatListItem } from '@buster/server-shared/chats'; import type { ChatListItem } from '@buster/server-shared/chats';
import { beforeEach, describe, expect, it, vi } from 'vitest'; 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', () => ({ vi.mock('../instances', () => ({
mainApi: { mainApi: {
get: vi.fn(), get: vi.fn(),
}, },
mainApiV2: {
get: vi.fn(),
post: vi.fn(),
delete: vi.fn(),
},
})); }));
describe('Chat API Requests', () => { describe('Chat API Requests', () => {
@ -36,17 +41,19 @@ describe('Chat API Requests', () => {
]; ];
// Setup mock response // 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 // Import the function we want to test
const { getListChats } = await import('./requests'); const { getListChats } = await import('./requestsV2');
// Execute the function // Execute the function
const result = await getListChats(); const result = await getListChats();
// Verify the API was called with correct parameters // Verify the API was called with correct parameters
expect(mainApi.get).toHaveBeenCalledWith('/chats', { expect(mainApiV2.get).toHaveBeenCalledWith('/chats', {
params: { page_token: 0, page_size: 3500 }, params: { page: 1, page_size: 3500 },
}); });
// Verify the result matches the mock data // Verify the result matches the mock data

View File

@ -4,8 +4,6 @@ import type {
DuplicateChatResponse, DuplicateChatResponse,
GetChatRequest, GetChatRequest,
GetChatResponse, GetChatResponse,
GetChatsListRequest,
GetChatsListResponse,
GetLogsListRequest, GetLogsListRequest,
GetLogsListResponse, GetLogsListResponse,
ShareChatResponse, ShareChatResponse,
@ -23,16 +21,6 @@ import { mainApi, mainApiV2 } from '../instances';
const CHATS_BASE = '/chats'; const CHATS_BASE = '/chats';
// Client-side fetch version
export const getListChats = async (params?: GetChatsListRequest): Promise<GetChatsListResponse> => {
const { page_token = 0, page_size = 3500 } = params || {};
return mainApi
.get<GetChatsListResponse>(`${CHATS_BASE}`, {
params: { page_token, page_size },
})
.then((res) => res.data);
};
export const getListLogs = async (params?: GetLogsListRequest): Promise<GetLogsListResponse> => { export const getListLogs = async (params?: GetLogsListRequest): Promise<GetLogsListResponse> => {
const { page_token = 0, page_size = 3500 } = params || {}; const { page_token = 0, page_size = 3500 } = params || {};
return mainApi return mainApi

View File

@ -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'; import mainApi, { mainApiV2 } from '../instances';
export const getListChats = async (
params?: GetChatsRequestV2
): Promise<GetChatsListResponseV2['data']> => {
const { page = 1, page_size = 3500 } = params || {};
return mainApiV2
.get<GetChatsListResponseV2>(`/chats`, {
params: { page, page_size },
})
.then((res) => res.data.data);
};
export const createNewChat = async (props: ChatCreateRequest) => { export const createNewChat = async (props: ChatCreateRequest) => {
return mainApiV2.post<ChatWithMessages>('/chats', props).then((res) => res.data); return mainApiV2.post<ChatWithMessages>('/chats', props).then((res) => res.data);
}; };

View File

@ -2,7 +2,8 @@ import type { ChatListItem } from '@buster/server-shared/chats';
import { queryOptions } from '@tanstack/react-query'; import { queryOptions } from '@tanstack/react-query';
import type { BusterChatMessage, IBusterChat } from '@/api/asset_interfaces/chat'; import type { BusterChatMessage, IBusterChat } from '@/api/asset_interfaces/chat';
import type { BusterMetricData } from '@/api/asset_interfaces/metric/metricDataInterfaces'; 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) => const chatsGetChat = (chatId: string) =>
queryOptions<IBusterChat>({ queryOptions<IBusterChat>({
@ -25,9 +26,7 @@ const chatsMessagesFetchingData = (messageId: string) =>
enabled: !!messageId, enabled: !!messageId,
}); });
const chatsGetList = ( const chatsGetList = (filters?: Omit<Parameters<typeof getListChats>[0], 'page' | 'page_size'>) =>
filters?: Omit<Parameters<typeof getListChats>[0], 'page_token' | 'page_size'>
) =>
queryOptions<ChatListItem[]>({ queryOptions<ChatListItem[]>({
queryKey: [ queryKey: [
'chats', 'chats',

View File

@ -9,12 +9,8 @@ import {
users, users,
usersToOrganizations, usersToOrganizations,
} from '../../schema'; } from '../../schema';
import type { ChatListItem } from '../../schema-types'; import type { ChatListItem, PaginatedResponse } from '../../schema-types';
import { import { PaginationInputSchema, createPaginatedResponse } from '../../schema-types';
type PaginatedResponse,
PaginationInputSchema,
createPaginatedResponse,
} from '../shared-types';
export const ListChatsRequestSchema = z export const ListChatsRequestSchema = z
.object({ .object({

View File

@ -2,9 +2,12 @@ import { type InferSelectModel, and, count, desc, eq, gte, isNull, like, lte } f
import { z } from 'zod'; import { z } from 'zod';
import { db } from '../../connection'; import { db } from '../../connection';
import { reportFiles, users } from '../../schema'; import { reportFiles, users } from '../../schema';
import {
type PaginatedResponse,
createPaginatedResponse,
withPagination,
} from '../../schema-types';
import { getUserOrganizationId } from '../organizations'; import { getUserOrganizationId } from '../organizations';
import { type PaginatedResponse, createPaginatedResponse } from '../shared-types';
import { withPagination } from '../shared-types/with-pagination';
export const GetReportsListInputSchema = z.object({ export const GetReportsListInputSchema = z.object({
userId: z.string().uuid('User ID must be a valid UUID'), userId: z.string().uuid('User ID must be a valid UUID'),

View File

@ -2,9 +2,12 @@ import { type SQL, and, count, desc, eq, exists, isNull, ne, or, sql } from 'dri
import { z } from 'zod'; import { z } from 'zod';
import { db } from '../../connection'; import { db } from '../../connection';
import { assetPermissions, reportFiles, teamsToUsers, users } from '../../schema'; import { assetPermissions, reportFiles, teamsToUsers, users } from '../../schema';
import {
type PaginatedResponse,
createPaginatedResponse,
withPagination,
} from '../../schema-types';
import { getUserOrganizationId } from '../organizations'; import { getUserOrganizationId } from '../organizations';
import { type PaginatedResponse, createPaginatedResponse } from '../shared-types';
import { withPagination } from '../shared-types/with-pagination';
export const GetReportsWithPermissionsInputSchema = z.object({ export const GetReportsWithPermissionsInputSchema = z.object({
userId: z.string().uuid('User ID must be a valid UUID'), userId: z.string().uuid('User ID must be a valid UUID'),

View File

@ -6,7 +6,7 @@ import {
type PaginatedResponse, type PaginatedResponse,
PaginationInputSchema, PaginationInputSchema,
createPaginatedResponse, createPaginatedResponse,
} from '../shared-types'; } from '../../schema-types';
import { createPermissionedAssetsSubquery } from './access-control-helpers'; import { createPermissionedAssetsSubquery } from './access-control-helpers';
import { AssetTypeSchema } from '../../schema-types/asset'; import { AssetTypeSchema } from '../../schema-types/asset';

View File

@ -1,3 +0,0 @@
// Export pagination types and utilities
export * from './pagination.types';
export * from './with-pagination';

View File

@ -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<typeof PaginationInputSchema>;
// 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<T> {
data: T[];
pagination: PaginationMetadata;
}
// Type helper for creating paginated API responses
export type WithPagination<T> = {
[K in keyof T]: T[K];
} & {
pagination: PaginationMetadata;
};

View File

@ -8,9 +8,12 @@ import {
usersToOrganizations, usersToOrganizations,
} from '../../schema'; } from '../../schema';
import { UserOrganizationRoleSchema, UserOrganizationStatusSchema } from '../../schema-types'; import { UserOrganizationRoleSchema, UserOrganizationStatusSchema } from '../../schema-types';
import {
type PaginatedResponse,
createPaginatedResponse,
withPagination,
} from '../../schema-types';
import { getUserOrganizationId } from '../organizations/organizations'; import { getUserOrganizationId } from '../organizations/organizations';
import { type PaginatedResponse, createPaginatedResponse } from '../shared-types';
import { withPagination } from '../shared-types/with-pagination';
// Type-safe schema types // Type-safe schema types
type User = InferSelectModel<typeof users>; type User = InferSelectModel<typeof users>;

View File

@ -37,3 +37,5 @@ export * from './github';
export * from './search'; export * from './search';
export * from './chat'; export * from './chat';
export * from './pagination';

View File

@ -1,6 +1,36 @@
import type { SQL } from 'drizzle-orm'; import type { SQL } from 'drizzle-orm';
import type { PgColumn, PgSelect } from 'drizzle-orm/pg-core'; 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<typeof PaginationInputSchema>;
export const PaginationSchema = z.object({
page: z.number(),
page_size: z.number(),
total: z.number(),
total_pages: z.number(),
});
export type PaginationMetadata = z.infer<typeof PaginationSchema>;
// Generic paginated response type
export interface PaginatedResponse<T> {
data: T[];
pagination: PaginationMetadata;
}
// Type helper for creating paginated API responses
export type WithPagination<T> = {
[K in keyof T]: T[K];
} & {
pagination: PaginationMetadata;
};
/** /**
* Adds pagination to a Drizzle query using the dynamic query builder pattern * Adds pagination to a Drizzle query using the dynamic query builder pattern

View File

@ -1,13 +1,13 @@
import {
PaginationInputSchema,
type PaginationMetadata,
PaginationSchema,
} from '@buster/database/schema-types';
import { z } from 'zod'; import { z } from 'zod';
export const PaginationSchema = z.object({ export { PaginationSchema, type PaginationMetadata } from '@buster/database/schema-types';
page: z.number(),
page_size: z.number(),
total: z.number(),
total_pages: z.number(),
});
export type Pagination = z.infer<typeof PaginationSchema>; export type Pagination = PaginationMetadata;
export const PaginatedResponseSchema = <T>(schema: z.ZodType<T>) => export const PaginatedResponseSchema = <T>(schema: z.ZodType<T>) =>
z.object({ z.object({
@ -17,7 +17,4 @@ export const PaginatedResponseSchema = <T>(schema: z.ZodType<T>) =>
export type PaginatedResponse<T> = z.infer<ReturnType<typeof PaginatedResponseSchema<T>>>; export type PaginatedResponse<T> = z.infer<ReturnType<typeof PaginatedResponseSchema<T>>>;
export const PaginatedRequestSchema = z.object({ export const PaginatedRequestSchema = PaginationInputSchema;
page: z.coerce.number().min(1).optional().default(1),
page_size: z.coerce.number().min(1).max(5000).default(250),
});