feat: paginate chat history (#903)

This commit is contained in:
Jeremy 2025-04-03 00:28:36 -07:00 committed by GitHub
parent 235b0edb91
commit a07a3aad5b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 346 additions and 212 deletions

View file

@ -1,7 +1,7 @@
import 'server-only';
import { genSaltSync, hashSync } from 'bcrypt-ts';
import { and, asc, desc, eq, gt, gte, inArray } from 'drizzle-orm';
import { and, asc, desc, eq, gt, gte, inArray, lt, SQL } from 'drizzle-orm';
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
@ -15,6 +15,7 @@ import {
message,
vote,
type DBMessage,
Chat,
} from './schema';
import { ArtifactKind } from '@/components/artifact';
@ -81,13 +82,68 @@ export async function deleteChatById({ id }: { id: string }) {
}
}
export async function getChatsByUserId({ id }: { id: string }) {
export async function getChatsByUserId({
id,
limit,
startingAfter,
endingBefore,
}: {
id: string;
limit: number;
startingAfter: string | null;
endingBefore: string | null;
}) {
try {
return await db
.select()
.from(chat)
.where(eq(chat.userId, id))
.orderBy(desc(chat.createdAt));
const extendedLimit = limit + 1;
const query = (whereCondition?: SQL<any>) =>
db
.select()
.from(chat)
.where(
whereCondition
? and(whereCondition, eq(chat.userId, id))
: eq(chat.userId, id),
)
.orderBy(desc(chat.createdAt))
.limit(extendedLimit);
let filteredChats: Array<Chat> = [];
if (startingAfter) {
const [selectedChat] = await db
.select()
.from(chat)
.where(eq(chat.id, startingAfter))
.limit(1);
if (!selectedChat) {
throw new Error(`Chat with id ${startingAfter} not found`);
}
filteredChats = await query(gt(chat.createdAt, selectedChat.createdAt));
} else if (endingBefore) {
const [selectedChat] = await db
.select()
.from(chat)
.where(eq(chat.id, endingBefore))
.limit(1);
if (!selectedChat) {
throw new Error(`Chat with id ${endingBefore} not found`);
}
filteredChats = await query(lt(chat.createdAt, selectedChat.createdAt));
} else {
filteredChats = await query();
}
const hasMore = filteredChats.length > limit;
return {
chats: hasMore ? filteredChats.slice(0, limit) : filteredChats,
hasMore,
};
} catch (error) {
console.error('Failed to get chats by user from database');
throw error;