import { vi } from "vitest"; export const TEST_USER_ID = "assistant-test-user"; export const TEST_CONVERSATION_ID = "assistant-test-conversation"; export function createApprovalStoreMock() { const records = new Map(); return { assistantApproval: { findFirst: vi.fn(async ({ where, orderBy, }: { where: { id?: string; userId?: string; conversationId?: string; status?: "PENDING" | "APPROVED" | "CANCELLED" | "EXPIRED"; }; orderBy?: { createdAt: "desc" | "asc" }; }) => { const matches = [...records.values()] .filter((record) => ( (!where.id || record.id === where.id) && (!where.userId || record.userId === where.userId) && (!where.conversationId || record.conversationId === where.conversationId) && (!where.status || record.status === where.status) )) .sort((a, b) => ( orderBy?.createdAt === "asc" ? a.createdAt.getTime() - b.createdAt.getTime() : b.createdAt.getTime() - a.createdAt.getTime() )); return matches[0] ?? null; }), findMany: vi.fn(async ({ where, orderBy, }: { where: { userId?: string; conversationId?: string; status?: "PENDING" | "APPROVED" | "CANCELLED" | "EXPIRED"; expiresAt?: { lte?: Date; gt?: Date }; }; orderBy?: { createdAt: "desc" | "asc" }; }) => ( [...records.values()] .filter((record) => ( (!where.userId || record.userId === where.userId) && (!where.conversationId || record.conversationId === where.conversationId) && (!where.status || record.status === where.status) && (!where.expiresAt?.lte || record.expiresAt <= where.expiresAt.lte) && (!where.expiresAt?.gt || record.expiresAt > where.expiresAt.gt) )) .sort((a, b) => ( orderBy?.createdAt === "asc" ? a.createdAt.getTime() - b.createdAt.getTime() : b.createdAt.getTime() - a.createdAt.getTime() )) )), create: vi.fn(async ({ data, }: { data: { userId: string; conversationId: string; toolName: string; toolArguments: string; summary: string; createdAt: Date; expiresAt: Date; }; }) => { const record = { id: `approval-${records.size + 1}`, ...data, status: "PENDING" as const, approvedAt: null, cancelledAt: null, updatedAt: data.createdAt, }; records.set(record.id, record); return record; }), updateMany: vi.fn(async ({ where, data, }: { where: { id?: string; userId?: string; conversationId?: string; status?: "PENDING" | "APPROVED" | "CANCELLED" | "EXPIRED"; expiresAt?: { lte?: Date; gt?: Date }; }; data: Partial<{ status: "APPROVED" | "CANCELLED" | "EXPIRED"; cancelledAt: Date; approvedAt: Date; }>; }) => { let count = 0; for (const [id, record] of records.entries()) { if (where.id && record.id !== where.id) continue; if (where.userId && record.userId !== where.userId) continue; if (where.conversationId && record.conversationId !== where.conversationId) continue; if (where.status && record.status !== where.status) continue; if (where.expiresAt?.lte && record.expiresAt > where.expiresAt.lte) continue; if (where.expiresAt?.gt && record.expiresAt <= where.expiresAt.gt) continue; records.set(id, { ...record, ...data, updatedAt: new Date(), }); count += 1; } return { count }; }), update: vi.fn(async ({ where, data, }: { where: { id: string }; data: { status: "APPROVED"; approvedAt: Date; }; }) => { const record = records.get(where.id); if (!record) throw new Error("Record not found"); const next = { ...record, ...data, updatedAt: new Date(), }; records.set(where.id, next); return next; }), }, }; } export function createMissingApprovalTableError() { return Object.assign( new Error("The table `public.assistant_approvals` does not exist in the current database."), { code: "P2021", meta: { table: "public.assistant_approvals" }, }, ); }