import { sqliteTable, text, integer, real, uniqueIndex } from "drizzle-orm/sqlite-core"; export const users = sqliteTable("users", { id: text("id").primaryKey(), nickname: text("nickname").unique().notNull(), passwordHash: text("password_hash").notNull(), isAdmin: integer("is_admin", { mode: "boolean" }).default(false).notNull(), createdAt: text("created_at").notNull(), }); export const sessions = sqliteTable("sessions", { id: text("id").primaryKey(), userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }), expiresAt: text("expires_at").notNull(), createdAt: text("created_at").notNull(), }); export const campaigns = sqliteTable("campaigns", { id: text("id").primaryKey(), name: text("name").notNull(), gridSize: integer("grid_size").notNull().default(5), status: text("status").notNull().default("active"), createdBy: text("created_by").notNull().references(() => users.id), createdAt: text("created_at").notNull(), }); export const bingoItems = sqliteTable("bingo_items", { id: text("id").primaryKey(), campaignId: text("campaign_id").notNull().references(() => campaigns.id, { onDelete: "cascade" }), text: text("text").notNull(), emoji: text("emoji").notNull().default("💀"), soundCategory: text("sound_category").notNull().default("horn"), soundUrl: text("sound_url"), imageUrl: text("image_url"), gridIndex: integer("grid_index").notNull(), createdAt: text("created_at").notNull(), }, (table) => [ uniqueIndex("idx_campaign_item_pos").on(table.campaignId, table.gridIndex), ]); export const sounds = sqliteTable("sounds", { id: text("id").primaryKey(), originalName: text("original_name").notNull(), storedFilename: text("stored_filename").unique().notNull(), duration: real("duration").notNull().default(0), uploadedBy: text("uploaded_by").notNull().references(() => users.id), createdAt: text("created_at").notNull(), }); export const images = sqliteTable("images", { id: text("id").primaryKey(), originalName: text("original_name").notNull(), storedFilename: text("stored_filename").unique().notNull(), mimeType: text("mime_type").notNull().default("image/png"), fileSize: integer("file_size").notNull(), uploadedBy: text("uploaded_by").notNull().references(() => users.id), createdAt: text("created_at").notNull(), }); export const marks = sqliteTable("marks", { id: text("id").primaryKey(), campaignId: text("campaign_id").notNull().references(() => campaigns.id, { onDelete: "cascade" }), itemId: text("item_id").notNull().references(() => bingoItems.id, { onDelete: "cascade" }), userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }), createdAt: text("created_at").notNull(), }, (table) => [ uniqueIndex("idx_unique_mark").on(table.campaignId, table.itemId), ]);