CREATE TYPE "public"."tier" AS ENUM('free', 'pro');--> statement-breakpoint CREATE TYPE "public"."unit_pref" AS ENUM('metric', 'imperial');--> statement-breakpoint CREATE TYPE "public"."user_role" AS ENUM('user', 'moderator', 'admin');--> statement-breakpoint CREATE TYPE "public"."difficulty" AS ENUM('easy', 'medium', 'hard');--> statement-breakpoint CREATE TYPE "public"."visibility" AS ENUM('private', 'unlisted', 'public');--> statement-breakpoint CREATE TYPE "public"."feed_item_type" AS ENUM('new_recipe', 'new_follow', 'recipe_rated');--> statement-breakpoint CREATE TYPE "public"."meal_type" AS ENUM('breakfast', 'lunch', 'dinner', 'snack');--> statement-breakpoint CREATE TYPE "public"."weekday" AS ENUM('mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun');--> statement-breakpoint CREATE TABLE "accounts" ( "id" text PRIMARY KEY NOT NULL, "account_id" text NOT NULL, "provider_id" text NOT NULL, "user_id" text NOT NULL, "access_token" text, "refresh_token" text, "id_token" text, "access_token_expires_at" timestamp, "refresh_token_expires_at" timestamp, "scope" text, "password" text, "created_at" timestamp DEFAULT now() NOT NULL, "updated_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "api_keys" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "name" text NOT NULL, "key_hash" text NOT NULL, "last_used_at" timestamp, "created_at" timestamp DEFAULT now() NOT NULL, CONSTRAINT "api_keys_key_hash_unique" UNIQUE("key_hash") ); --> statement-breakpoint CREATE TABLE "sessions" ( "id" text PRIMARY KEY NOT NULL, "expires_at" timestamp NOT NULL, "token" text NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL, "updated_at" timestamp DEFAULT now() NOT NULL, "ip_address" text, "user_agent" text, "user_id" text NOT NULL, CONSTRAINT "sessions_token_unique" UNIQUE("token") ); --> statement-breakpoint CREATE TABLE "user_follows" ( "follower_id" text NOT NULL, "following_id" text NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "users" ( "id" text PRIMARY KEY NOT NULL, "email" text NOT NULL, "email_verified" boolean DEFAULT false NOT NULL, "name" text NOT NULL, "avatar_url" text, "bio" text, "username" text, "role" "user_role" DEFAULT 'user' NOT NULL, "tier" "tier" DEFAULT 'free' NOT NULL, "unit_pref" "unit_pref" DEFAULT 'metric' NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL, "updated_at" timestamp DEFAULT now() NOT NULL, CONSTRAINT "users_email_unique" UNIQUE("email"), CONSTRAINT "users_username_unique" UNIQUE("username") ); --> statement-breakpoint CREATE TABLE "verifications" ( "id" text PRIMARY KEY NOT NULL, "identifier" text NOT NULL, "value" text NOT NULL, "expires_at" timestamp NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL, "updated_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "ingredients" ( "id" text PRIMARY KEY NOT NULL, "name" text NOT NULL, "aliases" text[] DEFAULT '{}' NOT NULL, "category" text, "known_allergens" text[] DEFAULT '{}' NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL, CONSTRAINT "ingredients_name_unique" UNIQUE("name") ); --> statement-breakpoint CREATE TABLE "recipe_ingredients" ( "id" text PRIMARY KEY NOT NULL, "recipe_id" text NOT NULL, "ingredient_id" text, "raw_name" text NOT NULL, "quantity" numeric(10, 4), "unit" text, "note" text, "order" integer DEFAULT 0 NOT NULL ); --> statement-breakpoint CREATE TABLE "recipe_notes" ( "id" text PRIMARY KEY NOT NULL, "recipe_id" text NOT NULL, "user_id" text NOT NULL, "content" text NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL, "updated_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "recipe_photos" ( "id" text PRIMARY KEY NOT NULL, "recipe_id" text NOT NULL, "storage_key" text NOT NULL, "order" integer DEFAULT 0 NOT NULL, "is_cover" boolean DEFAULT false NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "recipe_steps" ( "id" text PRIMARY KEY NOT NULL, "recipe_id" text NOT NULL, "order" integer NOT NULL, "instruction" text NOT NULL, "timer_seconds" integer, "photo_url" text ); --> statement-breakpoint CREATE TABLE "recipe_variations" ( "id" text PRIMARY KEY NOT NULL, "parent_recipe_id" text NOT NULL, "child_recipe_id" text NOT NULL, "description" text, "ai_generated" boolean DEFAULT false NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "recipes" ( "id" text PRIMARY KEY NOT NULL, "author_id" text NOT NULL, "title" text NOT NULL, "description" text, "base_servings" integer DEFAULT 4 NOT NULL, "visibility" "visibility" DEFAULT 'private' NOT NULL, "source_url" text, "ai_generated" boolean DEFAULT false NOT NULL, "ai_model" text, "ai_prompt" text, "dietary_tags" jsonb DEFAULT '{}'::jsonb, "dietary_verified" boolean DEFAULT false NOT NULL, "difficulty" "difficulty", "prep_mins" integer, "cook_mins" integer, "created_at" timestamp DEFAULT now() NOT NULL, "updated_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "user_allergens" ( "user_id" text NOT NULL, "allergen_tag" text NOT NULL ); --> statement-breakpoint CREATE TABLE "collection_recipes" ( "collection_id" text NOT NULL, "recipe_id" text NOT NULL, "added_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "collections" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "name" text NOT NULL, "description" text, "is_public" boolean DEFAULT false NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL, "updated_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "comments" ( "id" text PRIMARY KEY NOT NULL, "recipe_id" text NOT NULL, "user_id" text NOT NULL, "parent_id" text, "content" text NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL, "updated_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "cooking_history" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "recipe_id" text NOT NULL, "cooked_at" timestamp DEFAULT now() NOT NULL, "servings" integer, "notes" text ); --> statement-breakpoint CREATE TABLE "favorites" ( "user_id" text NOT NULL, "recipe_id" text NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "feed_items" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "type" "feed_item_type" NOT NULL, "actor_id" text NOT NULL, "subject_id" text NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "ratings" ( "id" text PRIMARY KEY NOT NULL, "recipe_id" text NOT NULL, "user_id" text NOT NULL, "score" integer NOT NULL, "review_text" text, "created_at" timestamp DEFAULT now() NOT NULL, "updated_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "meal_plan_entries" ( "id" text PRIMARY KEY NOT NULL, "meal_plan_id" text NOT NULL, "day" "weekday" NOT NULL, "meal_type" "meal_type" NOT NULL, "recipe_id" text, "servings" integer DEFAULT 2 NOT NULL, "note" text ); --> statement-breakpoint CREATE TABLE "meal_plans" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "week_start" date NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "pantry_items" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "ingredient_id" text, "raw_name" text NOT NULL, "quantity" numeric(10, 4), "unit" text, "expires_at" timestamp, "created_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "shopping_list_items" ( "id" text PRIMARY KEY NOT NULL, "list_id" text NOT NULL, "ingredient_id" text, "raw_name" text NOT NULL, "quantity" numeric(10, 4), "unit" text, "aisle" text, "checked" boolean DEFAULT false NOT NULL ); --> statement-breakpoint CREATE TABLE "shopping_lists" ( "id" text PRIMARY KEY NOT NULL, "user_id" text, "name" text NOT NULL, "generated_at" timestamp, "created_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "audit_logs" ( "id" text PRIMARY KEY NOT NULL, "user_id" text, "action" text NOT NULL, "target_type" text, "target_id" text, "metadata" text, "created_at" timestamp DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "tier_definitions" ( "tier" "tier" PRIMARY KEY NOT NULL, "max_recipes" integer NOT NULL, "ai_calls_per_month" integer NOT NULL, "storage_mb" integer NOT NULL, "max_public_recipes" integer NOT NULL ); --> statement-breakpoint CREATE TABLE "user_usage" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "month" text NOT NULL, "ai_calls_used" integer DEFAULT 0 NOT NULL, "recipe_count" integer DEFAULT 0 NOT NULL, "storage_used_mb" integer DEFAULT 0 NOT NULL ); --> statement-breakpoint ALTER TABLE "accounts" ADD CONSTRAINT "accounts_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "api_keys" ADD CONSTRAINT "api_keys_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "sessions" ADD CONSTRAINT "sessions_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "user_follows" ADD CONSTRAINT "user_follows_follower_id_users_id_fk" FOREIGN KEY ("follower_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "user_follows" ADD CONSTRAINT "user_follows_following_id_users_id_fk" FOREIGN KEY ("following_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "recipe_ingredients" ADD CONSTRAINT "recipe_ingredients_recipe_id_recipes_id_fk" FOREIGN KEY ("recipe_id") REFERENCES "public"."recipes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "recipe_ingredients" ADD CONSTRAINT "recipe_ingredients_ingredient_id_ingredients_id_fk" FOREIGN KEY ("ingredient_id") REFERENCES "public"."ingredients"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "recipe_notes" ADD CONSTRAINT "recipe_notes_recipe_id_recipes_id_fk" FOREIGN KEY ("recipe_id") REFERENCES "public"."recipes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "recipe_notes" ADD CONSTRAINT "recipe_notes_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "recipe_photos" ADD CONSTRAINT "recipe_photos_recipe_id_recipes_id_fk" FOREIGN KEY ("recipe_id") REFERENCES "public"."recipes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "recipe_steps" ADD CONSTRAINT "recipe_steps_recipe_id_recipes_id_fk" FOREIGN KEY ("recipe_id") REFERENCES "public"."recipes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "recipe_variations" ADD CONSTRAINT "recipe_variations_parent_recipe_id_recipes_id_fk" FOREIGN KEY ("parent_recipe_id") REFERENCES "public"."recipes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "recipe_variations" ADD CONSTRAINT "recipe_variations_child_recipe_id_recipes_id_fk" FOREIGN KEY ("child_recipe_id") REFERENCES "public"."recipes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "recipes" ADD CONSTRAINT "recipes_author_id_users_id_fk" FOREIGN KEY ("author_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "user_allergens" ADD CONSTRAINT "user_allergens_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "collection_recipes" ADD CONSTRAINT "collection_recipes_collection_id_collections_id_fk" FOREIGN KEY ("collection_id") REFERENCES "public"."collections"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "collection_recipes" ADD CONSTRAINT "collection_recipes_recipe_id_recipes_id_fk" FOREIGN KEY ("recipe_id") REFERENCES "public"."recipes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "collections" ADD CONSTRAINT "collections_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "comments" ADD CONSTRAINT "comments_recipe_id_recipes_id_fk" FOREIGN KEY ("recipe_id") REFERENCES "public"."recipes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "comments" ADD CONSTRAINT "comments_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "cooking_history" ADD CONSTRAINT "cooking_history_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "cooking_history" ADD CONSTRAINT "cooking_history_recipe_id_recipes_id_fk" FOREIGN KEY ("recipe_id") REFERENCES "public"."recipes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "favorites" ADD CONSTRAINT "favorites_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "favorites" ADD CONSTRAINT "favorites_recipe_id_recipes_id_fk" FOREIGN KEY ("recipe_id") REFERENCES "public"."recipes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "feed_items" ADD CONSTRAINT "feed_items_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "feed_items" ADD CONSTRAINT "feed_items_actor_id_users_id_fk" FOREIGN KEY ("actor_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "ratings" ADD CONSTRAINT "ratings_recipe_id_recipes_id_fk" FOREIGN KEY ("recipe_id") REFERENCES "public"."recipes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "ratings" ADD CONSTRAINT "ratings_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "meal_plan_entries" ADD CONSTRAINT "meal_plan_entries_meal_plan_id_meal_plans_id_fk" FOREIGN KEY ("meal_plan_id") REFERENCES "public"."meal_plans"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "meal_plan_entries" ADD CONSTRAINT "meal_plan_entries_recipe_id_recipes_id_fk" FOREIGN KEY ("recipe_id") REFERENCES "public"."recipes"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "meal_plans" ADD CONSTRAINT "meal_plans_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "pantry_items" ADD CONSTRAINT "pantry_items_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "pantry_items" ADD CONSTRAINT "pantry_items_ingredient_id_ingredients_id_fk" FOREIGN KEY ("ingredient_id") REFERENCES "public"."ingredients"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "shopping_list_items" ADD CONSTRAINT "shopping_list_items_list_id_shopping_lists_id_fk" FOREIGN KEY ("list_id") REFERENCES "public"."shopping_lists"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "shopping_list_items" ADD CONSTRAINT "shopping_list_items_ingredient_id_ingredients_id_fk" FOREIGN KEY ("ingredient_id") REFERENCES "public"."ingredients"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "shopping_lists" ADD CONSTRAINT "shopping_lists_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "user_usage" ADD CONSTRAINT "user_usage_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint CREATE INDEX "recipes_author_idx" ON "recipes" USING btree ("author_id");--> statement-breakpoint CREATE INDEX "recipes_visibility_idx" ON "recipes" USING btree ("visibility");--> statement-breakpoint CREATE INDEX "comments_recipe_idx" ON "comments" USING btree ("recipe_id");--> statement-breakpoint CREATE INDEX "feed_items_user_idx" ON "feed_items" USING btree ("user_id","created_at");--> statement-breakpoint CREATE INDEX "audit_logs_created_idx" ON "audit_logs" USING btree ("created_at");--> statement-breakpoint CREATE INDEX "user_usage_user_month_idx" ON "user_usage" USING btree ("user_id","month");