import type { InferSelectModel } from "drizzle-orm"; import { boolean, integer, json, pgTable, primaryKey, text, timestamp, uuid, varchar, } from "drizzle-orm/pg-core"; export const user = pgTable("User", { id: uuid("id").primaryKey().notNull().defaultRandom(), email: varchar("email", { length: 64 }).notNull(), password: varchar("password", { length: 64 }), name: text("name"), emailVerified: boolean("emailVerified").notNull().default(false), image: text("image"), isAnonymous: boolean("isAnonymous").notNull().default(false), createdAt: timestamp("createdAt").notNull().defaultNow(), updatedAt: timestamp("updatedAt").notNull().defaultNow(), }); export type User = InferSelectModel; export const chat = pgTable("Chat", { id: uuid("id").primaryKey().notNull().defaultRandom(), createdAt: timestamp("createdAt").notNull(), title: text("title").notNull(), userId: uuid("userId") .notNull() .references(() => user.id), visibility: varchar("visibility", { enum: ["public", "private"] }) .notNull() .default("private"), }); export type Chat = InferSelectModel; export const message = pgTable("Message_v2", { id: uuid("id").primaryKey().notNull().defaultRandom(), chatId: uuid("chatId") .notNull() .references(() => chat.id), role: varchar("role").notNull(), parts: json("parts").notNull(), attachments: json("attachments").notNull(), createdAt: timestamp("createdAt").notNull(), }); export type DBMessage = InferSelectModel; export const vote = pgTable( "Vote_v2", { chatId: uuid("chatId") .notNull() .references(() => chat.id), messageId: uuid("messageId") .notNull() .references(() => message.id), isUpvoted: boolean("isUpvoted").notNull(), }, (table) => ({ pk: primaryKey({ columns: [table.chatId, table.messageId] }), }) ); export type Vote = InferSelectModel; export const subscription = pgTable("Subscription", { userId: uuid("userId") .primaryKey() .notNull() .references(() => user.id), tier: varchar("tier", { enum: ["free", "pro"] }) .notNull() .default("free"), status: varchar("status", { enum: ["active", "canceled", "past_due"] }) .notNull() .default("active"), stripeCustomerId: text("stripeCustomerId"), stripeSubscriptionId: text("stripeSubscriptionId"), currentPeriodEnd: timestamp("currentPeriodEnd"), createdAt: timestamp("createdAt").notNull().defaultNow(), updatedAt: timestamp("updatedAt").notNull().defaultNow(), }); export type Subscription = InferSelectModel; export const usage = pgTable( "Usage", { userId: uuid("userId") .notNull() .references(() => user.id), periodKey: varchar("periodKey", { length: 10 }).notNull(), messageCount: integer("messageCount").notNull().default(0), toolCallCount: integer("toolCallCount").notNull().default(0), updatedAt: timestamp("updatedAt").notNull().defaultNow(), }, (table) => ({ pk: primaryKey({ columns: [table.userId, table.periodKey] }), }) ); export type Usage = InferSelectModel; export const webhookEvent = pgTable("WebhookEvent", { id: text("id").primaryKey().notNull(), type: text("type").notNull(), receivedAt: timestamp("receivedAt").notNull().defaultNow(), }); export type WebhookEvent = InferSelectModel;