mirror of https://github.com/buster-so/buster.git
migrate /chats to use the v2 endpoint from the frontend
This commit is contained in:
parent
41efcbfa54
commit
7bcae1e5d5
|
@ -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';
|
||||||
|
|
|
@ -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]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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'),
|
||||||
|
|
|
@ -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'),
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
// Export pagination types and utilities
|
|
||||||
export * from './pagination.types';
|
|
||||||
export * from './with-pagination';
|
|
|
@ -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;
|
|
||||||
};
|
|
|
@ -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>;
|
||||||
|
|
|
@ -37,3 +37,5 @@ export * from './github';
|
||||||
export * from './search';
|
export * from './search';
|
||||||
|
|
||||||
export * from './chat';
|
export * from './chat';
|
||||||
|
|
||||||
|
export * from './pagination';
|
||||||
|
|
|
@ -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
|
|
@ -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),
|
|
||||||
});
|
|
||||||
|
|
Loading…
Reference in New Issue