import { pgTable, text, timestamp, integer, boolean, index, unique, pgEnum, } from "drizzle-orm/pg-core"; import { relations } from "drizzle-orm"; import { users, tierEnum, userRoleEnum } from "./users"; export const tierDefinitions = pgTable("tier_definitions", { tier: tierEnum("tier").primaryKey(), maxRecipes: integer("max_recipes").notNull(), aiCallsPerMonth: integer("ai_calls_per_month").notNull(), storageMb: integer("storage_mb").notNull(), maxPublicRecipes: integer("max_public_recipes").notNull(), }); export const userUsage = pgTable("user_usage", { id: text("id").primaryKey(), userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }), month: text("month").notNull(), aiCallsUsed: integer("ai_calls_used").notNull().default(0), recipeCount: integer("recipe_count").notNull().default(0), storageUsedMb: integer("storage_used_mb").notNull().default(0), }, (t) => [ index("user_usage_user_month_idx").on(t.userId, t.month), unique("user_usage_user_month_uniq").on(t.userId, t.month), ]); export const auditLogs = pgTable("audit_logs", { id: text("id").primaryKey(), userId: text("user_id").references(() => users.id, { onDelete: "set null" }), action: text("action").notNull(), targetType: text("target_type"), targetId: text("target_id"), metadata: text("metadata"), createdAt: timestamp("created_at").notNull().defaultNow(), }, (t) => [ index("audit_logs_created_idx").on(t.createdAt), ]); export const siteSettings = pgTable("site_settings", { key: text("key").primaryKey(), value: text("value"), isSecret: boolean("is_secret").notNull().default(false), updatedAt: timestamp("updated_at").notNull().defaultNow(), updatedById: text("updated_by_id").references(() => users.id, { onDelete: "set null" }), }); export const invites = pgTable("invites", { id: text("id").primaryKey(), token: text("token").notNull(), email: text("email"), role: userRoleEnum("role").notNull().default("user"), tier: tierEnum("tier").notNull().default("free"), createdById: text("created_by_id").notNull().references(() => users.id, { onDelete: "cascade" }), createdAt: timestamp("created_at").notNull().defaultNow(), expiresAt: timestamp("expires_at"), usedAt: timestamp("used_at"), usedById: text("used_by_id").references(() => users.id, { onDelete: "set null" }), }, (t) => [ unique("invites_token_uniq").on(t.token), ]); export const userUsageRelations = relations(userUsage, ({ one }) => ({ user: one(users, { fields: [userUsage.userId], references: [users.id] }), })); export const invitesRelations = relations(invites, ({ one }) => ({ createdBy: one(users, { fields: [invites.createdById], references: [users.id] }), usedBy: one(users, { fields: [invites.usedById], references: [users.id] }), })); export const reportTargetTypeEnum = pgEnum("report_target_type", ["recipe", "comment", "user"]); export const reportStatusEnum = pgEnum("report_status", ["pending", "reviewed", "dismissed"]); export const reports = pgTable("reports", { id: text("id").primaryKey(), reporterId: text("reporter_id").notNull().references(() => users.id, { onDelete: "cascade" }), targetType: reportTargetTypeEnum("target_type").notNull(), targetId: text("target_id").notNull(), reason: text("reason").notNull(), status: reportStatusEnum("status").notNull().default("pending"), createdAt: timestamp("created_at").notNull().defaultNow(), reviewedById: text("reviewed_by_id").references(() => users.id, { onDelete: "set null" }), reviewedAt: timestamp("reviewed_at"), }, (t) => [ index("reports_status_idx").on(t.status, t.createdAt), ]); export const reportsRelations = relations(reports, ({ one }) => ({ reporter: one(users, { fields: [reports.reporterId], references: [users.id] }), reviewedBy: one(users, { fields: [reports.reviewedById], references: [users.id] }), }));