import { pgTable, text, timestamp, integer, boolean, date, decimal, pgEnum, index, } from "drizzle-orm/pg-core"; import { relations } from "drizzle-orm"; import { users } from "./users"; import { recipes } from "./recipes"; import { ingredients } from "./recipes"; import { collectionMemberRoleEnum } from "./social"; export const mealTypeEnum = pgEnum("meal_type", ["breakfast", "lunch", "dinner", "snack"]); export const weekdayEnum = pgEnum("weekday", ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]); export const mealPlans = pgTable("meal_plans", { id: text("id").primaryKey(), userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }), weekStart: date("week_start").notNull(), createdAt: timestamp("created_at").notNull().defaultNow(), }); export const mealPlanEntries = pgTable("meal_plan_entries", { id: text("id").primaryKey(), mealPlanId: text("meal_plan_id").notNull().references(() => mealPlans.id, { onDelete: "cascade" }), day: weekdayEnum("day").notNull(), mealType: mealTypeEnum("meal_type").notNull(), recipeId: text("recipe_id").references(() => recipes.id, { onDelete: "set null" }), servings: integer("servings").notNull().default(2), note: text("note"), }); export const pantryItems = pgTable("pantry_items", { id: text("id").primaryKey(), userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }), ingredientId: text("ingredient_id").references(() => ingredients.id, { onDelete: "set null" }), rawName: text("raw_name").notNull(), quantity: decimal("quantity", { precision: 10, scale: 4 }), unit: text("unit"), expiresAt: timestamp("expires_at"), createdAt: timestamp("created_at").notNull().defaultNow(), }); export const shoppingLists = pgTable("shopping_lists", { id: text("id").primaryKey(), userId: text("user_id").references(() => users.id, { onDelete: "cascade" }), name: text("name").notNull(), generatedAt: timestamp("generated_at"), createdAt: timestamp("created_at").notNull().defaultNow(), }); export const shoppingListItems = pgTable("shopping_list_items", { id: text("id").primaryKey(), listId: text("list_id").notNull().references(() => shoppingLists.id, { onDelete: "cascade" }), ingredientId: text("ingredient_id").references(() => ingredients.id, { onDelete: "set null" }), rawName: text("raw_name").notNull(), quantity: decimal("quantity", { precision: 10, scale: 4 }), unit: text("unit"), aisle: text("aisle"), checked: boolean("checked").notNull().default(false), }); export const shoppingListMembers = pgTable("shopping_list_members", { id: text("id").primaryKey(), listId: text("list_id").notNull().references(() => shoppingLists.id, { onDelete: "cascade" }), userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }), role: collectionMemberRoleEnum("role").notNull().default("viewer"), createdAt: timestamp("created_at").notNull().defaultNow(), }, (t) => [ index("shopping_list_members_list_idx").on(t.listId), index("shopping_list_members_user_idx").on(t.userId), ]); export const mealPlanMembers = pgTable("meal_plan_members", { id: text("id").primaryKey(), mealPlanId: text("meal_plan_id").notNull().references(() => mealPlans.id, { onDelete: "cascade" }), userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }), role: collectionMemberRoleEnum("role").notNull().default("viewer"), createdAt: timestamp("created_at").notNull().defaultNow(), }, (t) => [ index("meal_plan_members_plan_idx").on(t.mealPlanId), index("meal_plan_members_user_idx").on(t.userId), ]); export const mealPlansRelations = relations(mealPlans, ({ one, many }) => ({ user: one(users, { fields: [mealPlans.userId], references: [users.id] }), entries: many(mealPlanEntries), members: many(mealPlanMembers), })); export const mealPlanEntriesRelations = relations(mealPlanEntries, ({ one }) => ({ mealPlan: one(mealPlans, { fields: [mealPlanEntries.mealPlanId], references: [mealPlans.id] }), recipe: one(recipes, { fields: [mealPlanEntries.recipeId], references: [recipes.id] }), })); export const mealPlanMembersRelations = relations(mealPlanMembers, ({ one }) => ({ mealPlan: one(mealPlans, { fields: [mealPlanMembers.mealPlanId], references: [mealPlans.id] }), user: one(users, { fields: [mealPlanMembers.userId], references: [users.id] }), })); export const shoppingListsRelations = relations(shoppingLists, ({ one, many }) => ({ user: one(users, { fields: [shoppingLists.userId], references: [users.id] }), items: many(shoppingListItems), members: many(shoppingListMembers), })); export const shoppingListItemsRelations = relations(shoppingListItems, ({ one }) => ({ list: one(shoppingLists, { fields: [shoppingListItems.listId], references: [shoppingLists.id] }), })); export const shoppingListMembersRelations = relations(shoppingListMembers, ({ one }) => ({ list: one(shoppingLists, { fields: [shoppingListMembers.listId], references: [shoppingLists.id] }), user: one(users, { fields: [shoppingListMembers.userId], references: [users.id] }), }));