Skip to main content
All database queries are defined in lib/db/queries.ts using Drizzle ORM.

User queries

getUser

Retrieve a user by email address.
export async function getUser(email: string): Promise<User[]>
email
string
required
User email address
Returns: Array of matching users (typically 0 or 1) Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:44-53

createUser

Create a new user account.
export async function createUser(email: string, password: string)
email
string
required
User email address
password
string
required
Plain text password (will be hashed)
Returns: Database insert result Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:55-63

createGuestUser

Create a temporary guest user account.
export async function createGuestUser()
Generates:
  • Email: guest-{timestamp}
  • Password: Random UUID (hashed)
Returns: { id: string, email: string } Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:65-80

Chat queries

saveChat

Create a new chat conversation.
export async function saveChat({
  id,
  userId,
  title,
  visibility,
}: {
  id: string;
  userId: string;
  title: string;
  visibility: VisibilityType;
})
id
string
required
Chat UUID
userId
string
required
Owner user ID
title
string
required
Chat title
visibility
VisibilityType
required
"public" or "private"
Returns: Database insert result Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:82-104

getChatById

Retrieve a chat by ID.
export async function getChatById({ id }: { id: string })
id
string
required
Chat UUID
Returns: Chat object or null if not found Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:232-243

getChatsByUserId

Retrieve paginated chats for a user.
export async function getChatsByUserId({
  id,
  limit,
  startingAfter,
  endingBefore,
}: {
  id: string;
  limit: number;
  startingAfter: string | null;
  endingBefore: string | null;
})
id
string
required
User ID
limit
number
required
Number of chats to return
startingAfter
string | null
required
Chat ID to start after (forward pagination)
endingBefore
string | null
required
Chat ID to end before (backward pagination)
Returns: { chats: Chat[], hasMore: boolean } Throws: ChatbotError("bad_request:database") or ChatbotError("not_found:database") if cursor chat not found From lib/db/queries.ts:156-230

Pagination logic

const extendedLimit = limit + 1;

if (startingAfter) {
  // Get chats created after the specified chat
  filteredChats = await query(gt(chat.createdAt, selectedChat.createdAt));
} else if (endingBefore) {
  // Get chats created before the specified chat
  filteredChats = await query(lt(chat.createdAt, selectedChat.createdAt));
} else {
  // Get first page
  filteredChats = await query();
}

const hasMore = filteredChats.length > limit;
return {
  chats: hasMore ? filteredChats.slice(0, limit) : filteredChats,
  hasMore,
};

deleteChatById

Delete a chat and all associated data.
export async function deleteChatById({ id }: { id: string })
id
string
required
Chat UUID
Returns: Deleted chat object Throws: ChatbotError("bad_request:database") on failure Deletes in order:
  1. All votes for the chat
  2. All messages in the chat
  3. All stream records
  4. The chat itself
From lib/db/queries.ts:106-123

deleteAllChatsByUserId

Delete all chats for a user.
export async function deleteAllChatsByUserId({ userId }: { userId: string })
userId
string
required
User ID
Returns: { deletedCount: number } Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:125-154

updateChatTitleById

Update a chat’s title.
export async function updateChatTitleById({
  chatId,
  title,
}: {
  chatId: string;
  title: string;
})
chatId
string
required
Chat UUID
title
string
required
New title
Returns: Database update result Note: Does not throw on failure, only logs warning From lib/db/queries.ts:518-531

updateChatVisibilityById

Update a chat’s visibility.
export async function updateChatVisibilityById({
  chatId,
  visibility,
}: {
  chatId: string;
  visibility: "private" | "public";
})
chatId
string
required
Chat UUID
visibility
string
required
"public" or "private"
Returns: Database update result Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:501-516

Message queries

saveMessages

Save multiple messages to the database.
export async function saveMessages({ messages }: { messages: DBMessage[] })
messages
DBMessage[]
required
Array of messages to save
Message structure:
{
  id: string;           // UUID
  chatId: string;       // Chat UUID
  role: string;         // "user" | "assistant" | "system"
  parts: any[];         // Array of message parts
  attachments: any[];   // Array of attachments
  createdAt: Date;      // Timestamp
}
Returns: Database insert result Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:245-251

getMessagesByChatId

Retrieve all messages for a chat.
export async function getMessagesByChatId({ id }: { id: string })
id
string
required
Chat UUID
Returns: Array of messages ordered by createdAt (ascending) Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:267-280

getMessageById

Retrieve a specific message by ID.
export async function getMessageById({ id }: { id: string })
id
string
required
Message UUID
Returns: Array of matching messages (typically 0 or 1) Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:450-459

updateMessage

Update a message’s parts.
export async function updateMessage({
  id,
  parts,
}: {
  id: string;
  parts: DBMessage["parts"];
})
id
string
required
Message UUID
parts
array
required
New message parts
Returns: Database update result Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:253-265

deleteMessagesByChatIdAfterTimestamp

Delete messages created after a specific time.
export async function deleteMessagesByChatIdAfterTimestamp({
  chatId,
  timestamp,
}: {
  chatId: string;
  timestamp: Date;
})
chatId
string
required
Chat UUID
timestamp
Date
required
Delete messages created on or after this time
Returns: Database delete result Throws: ChatbotError("bad_request:database") on failure Also deletes associated votes for those messages. From lib/db/queries.ts:461-499

getMessageCountByUserId

Get count of user messages within a time window.
export async function getMessageCountByUserId({
  id,
  differenceInHours,
}: {
  id: string;
  differenceInHours: number;
})
id
string
required
User ID
differenceInHours
number
required
Time window in hours (e.g., 24 for last 24 hours)
Returns: Number of user messages in time window Throws: ChatbotError("bad_request:database") on failure Used for rate limiting. From lib/db/queries.ts:533-565

Vote queries

voteMessage

Create or update a vote on a message.
export async function voteMessage({
  chatId,
  messageId,
  type,
}: {
  chatId: string;
  messageId: string;
  type: "up" | "down";
})
chatId
string
required
Chat UUID
messageId
string
required
Message UUID
type
string
required
"up" or "down"
Returns: Database insert or update result Throws: ChatbotError("bad_request:database") on failure Logic:
  • If vote exists: Update isUpvoted field
  • If vote doesn’t exist: Insert new vote
From lib/db/queries.ts:282-311

getVotesByChatId

Retrieve all votes for a chat.
export async function getVotesByChatId({ id }: { id: string })
id
string
required
Chat UUID
Returns: Array of vote objects Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:313-322

Document queries

saveDocument

Save a new document version.
export async function saveDocument({
  id,
  title,
  kind,
  content,
  userId,
}: {
  id: string;
  title: string;
  kind: ArtifactKind;
  content: string;
  userId: string;
})
id
string
required
Document UUID
title
string
required
Document title
kind
ArtifactKind
required
"text" | "code" | "image" | "sheet"
content
string
required
Document content
userId
string
required
Owner user ID
Returns: Array with created document Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:324-352

getDocumentsById

Retrieve all versions of a document.
export async function getDocumentsById({ id }: { id: string })
id
string
required
Document UUID
Returns: Array of document versions ordered by createdAt (ascending) Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:354-369

getDocumentById

Retrieve the latest version of a document.
export async function getDocumentById({ id }: { id: string })
id
string
required
Document UUID
Returns: Latest document version or undefined Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:371-386

deleteDocumentsByIdAfterTimestamp

Delete document versions created after a timestamp.
export async function deleteDocumentsByIdAfterTimestamp({
  id,
  timestamp,
}: {
  id: string;
  timestamp: Date;
})
id
string
required
Document UUID
timestamp
Date
required
Delete versions created after this time
Returns: Array of deleted documents Throws: ChatbotError("bad_request:database") on failure Also deletes associated suggestions. From lib/db/queries.ts:388-415

Suggestion queries

saveSuggestions

Save multiple suggestions.
export async function saveSuggestions({
  suggestions,
}: {
  suggestions: Suggestion[];
})
suggestions
Suggestion[]
required
Array of suggestions to save
Suggestion structure:
{
  id: string;                    // UUID
  documentId: string;            // Document UUID
  documentCreatedAt: Date;       // Document version timestamp
  originalText: string;          // Text to replace
  suggestedText: string;         // Replacement text
  description: string | null;    // Optional description
  isResolved: boolean;           // Resolution status
  userId: string;                // Owner user ID
  createdAt: Date;               // Creation timestamp
}
Returns: Database insert result Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:417-429

getSuggestionsByDocumentId

Retrieve all suggestions for a document.
export async function getSuggestionsByDocumentId({
  documentId,
}: {
  documentId: string;
})
documentId
string
required
Document UUID
Returns: Array of suggestions for all versions of the document Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:432-448

Stream queries

createStreamId

Create a resumable stream record.
export async function createStreamId({
  streamId,
  chatId,
}: {
  streamId: string;
  chatId: string;
})
streamId
string
required
Stream UUID
chatId
string
required
Associated chat UUID
Returns: Database insert result Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:567-584

getStreamIdsByChatId

Retrieve all stream IDs for a chat.
export async function getStreamIdsByChatId({ chatId }: { chatId: string })
chatId
string
required
Chat UUID
Returns: Array of stream IDs (strings) Throws: ChatbotError("bad_request:database") on failure From lib/db/queries.ts:586-602

Error handling

All query functions use consistent error handling:
try {
  // Database operation
} catch (_error) {
  throw new ChatbotError(
    "bad_request:database",
    "Failed to {operation description}"
  );
}
Exceptions:
  • updateChatTitleById: Logs warning instead of throwing
  • Pagination queries: May throw ChatbotError("not_found:database") if cursor chat not found

Database connection

From lib/db/queries.ts:41-42:
const client = postgres(process.env.POSTGRES_URL!);
const db = drizzle(client);
Requires POSTGRES_URL environment variable to be set.

Build docs developers (and LLMs) love