import { boolean, date, index, integer, jsonb, numeric, pgTable, primaryKey, text, timestamp, uniqueIndex, } from "drizzle-orm/pg-core"; import { user } from "./auth"; import { activityLevelEnum, coachPriorityEnum, dietStyleEnum, healthGoalEnum, reminderKindEnum, } from "./enums"; export const healthProfiles = pgTable("health_profiles", { userId: text("userId").primaryKey().references(() => user.id, { onDelete: "cascade" }), goal: healthGoalEnum("goal").notNull().default("healthier"), age: integer("age"), heightCm: numeric("heightCm", { precision: 6, scale: 2 }), currentWeightKg: numeric("currentWeightKg", { precision: 6, scale: 2 }), targetWeightKg: numeric("targetWeightKg", { precision: 6, scale: 2 }), activityLevel: activityLevelEnum("activityLevel").notNull().default("moderate"), dietStyle: dietStyleEnum("dietStyle").notNull().default("flexible"), dietPreferences: jsonb("dietPreferences").$type().notNull().default(["vegetarian", "vegan", "meat", "fish"]), mealsPerDay: integer("mealsPerDay").notNull().default(3), cooksPerDay: integer("cooksPerDay").notNull().default(1), preferredMealPrepDays: integer("preferredMealPrepDays").notNull().default(0), meatFishFrequency: text("meatFishFrequency").notNull().default("flexible"), cookingTime: text("cookingTime").notNull().default("medium"), budgetFocus: boolean("budgetFocus").notNull().default(false), excludedFoods: text("excludedFoods"), biggestChallenge: text("biggestChallenge"), medicalNote: boolean("medicalNote").notNull().default(false), completedAt: timestamp("completedAt"), createdAt: timestamp("createdAt").notNull().defaultNow(), updatedAt: timestamp("updatedAt").notNull().defaultNow(), }); export const healthGoals = pgTable("health_goals", { userId: text("userId").primaryKey().references(() => user.id, { onDelete: "cascade" }), drinkMl: integer("drinkMl").notNull().default(2500), calories: integer("calories").notNull().default(2000), carbsG: integer("carbsG").notNull().default(200), fatG: integer("fatG").notNull().default(67), proteinG: integer("proteinG").notNull().default(150), weightKg: numeric("weightKg", { precision: 6, scale: 2 }), fastingHours: integer("fastingHours").notNull().default(12), weeklyCalories: integer("weeklyCalories"), sportAddsCalories: boolean("sportAddsCalories").notNull().default(true), updatedAt: timestamp("updatedAt").notNull().defaultNow(), }); export const weeklyCaloriePlans = pgTable( "weekly_calorie_plans", { userId: text("userId").notNull().references(() => user.id, { onDelete: "cascade" }), date: date("date").notNull(), plannedCalories: integer("plannedCalories").notNull(), note: text("note"), updatedAt: timestamp("updatedAt").notNull().defaultNow(), }, (table) => ({ pk: primaryKey({ columns: [table.userId, table.date] }), }), ); export const reminderRules = pgTable( "reminder_rules", { id: text("id").primaryKey(), userId: text("userId").notNull().references(() => user.id, { onDelete: "cascade" }), kind: reminderKindEnum("kind").notNull(), enabled: boolean("enabled").notNull().default(true), intervalMinutes: integer("intervalMinutes").notNull().default(90), startTime: text("startTime").notNull().default("08:00"), endTime: text("endTime").notNull().default("20:00"), message: text("message").notNull(), quietDays: jsonb("quietDays").$type().notNull().default([]), updatedAt: timestamp("updatedAt").notNull().defaultNow(), }, (table) => ({ uniqueKind: uniqueIndex("reminder_rules_user_kind_unique").on(table.userId, table.kind), }), ); export const coachPrinciples = pgTable("coach_principles", { id: text("id").primaryKey(), title: text("title").notNull(), body: text("body").notNull(), category: text("category").notNull().default("general"), isActive: boolean("isActive").notNull().default(true), sortOrder: integer("sortOrder").notNull().default(0), createdAt: timestamp("createdAt").notNull().defaultNow(), updatedAt: timestamp("updatedAt").notNull().defaultNow(), }); export const coachRecommendations = pgTable( "coach_recommendations", { id: text("id").primaryKey(), userId: text("userId").notNull().references(() => user.id, { onDelete: "cascade" }), title: text("title").notNull(), body: text("body").notNull(), priority: coachPriorityEnum("priority").notNull().default("medium"), category: text("category").notNull().default("daily"), source: text("source").notNull().default("rule"), validFrom: date("validFrom"), validTo: date("validTo"), dismissedAt: timestamp("dismissedAt"), createdAt: timestamp("createdAt").notNull().defaultNow(), }, (table) => ({ userIdx: index("coach_recommendations_user_idx").on(table.userId), }), ); export type HealthProfile = typeof healthProfiles.$inferSelect; export type NewHealthProfile = typeof healthProfiles.$inferInsert; export type HealthGoal = typeof healthGoals.$inferSelect; export type NewHealthGoal = typeof healthGoals.$inferInsert;