69 lines
2.8 KiB
TypeScript
69 lines
2.8 KiB
TypeScript
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),
|
|
]);
|