Initial commit (unpacked platform)

This commit is contained in:
Sven (AAMOS AI)
2026-08-05 19:21:11 +07:00
commit ac5340195a
314 changed files with 57584 additions and 0 deletions
@@ -0,0 +1,1051 @@
CREATE TYPE "public"."activity_level" AS ENUM('sedentary', 'light', 'moderate', 'active', 'very_active');--> statement-breakpoint
CREATE TYPE "public"."allergen" AS ENUM('gluten', 'crustaceans', 'eggs', 'fish', 'peanuts', 'soy', 'milk', 'tree_nuts', 'celery', 'mustard', 'sesame', 'sulphites', 'lupin', 'molluscs');--> statement-breakpoint
CREATE TYPE "public"."consent_kind" AS ENUM('personalization', 'anonymized_improvement', 'image_training', 'health_integration', 'location_weather', 'push_notifications');--> statement-breakpoint
CREATE TYPE "public"."consent_status" AS ENUM('granted', 'denied', 'revoked');--> statement-breakpoint
CREATE TYPE "public"."cooking_method" AS ENUM('stovetop', 'oven', 'grill', 'airfryer', 'wok', 'slow_cooker', 'sous_vide', 'microwave', 'no_cook', 'pressure_cooker', 'deep_fry', 'steam');--> statement-breakpoint
CREATE TYPE "public"."creator_level" AS ENUM('beginner', 'sous_chef', 'chef', 'master_chef', 'legend');--> statement-breakpoint
CREATE TYPE "public"."cuisine" AS ENUM('swedish', 'nordic', 'italian', 'french', 'spanish', 'greek', 'thai', 'chinese', 'japanese', 'korean', 'vietnamese', 'indian', 'mexican', 'american', 'turkish', 'lebanese', 'moroccan', 'middle_eastern', 'international');--> statement-breakpoint
CREATE TYPE "public"."date_kind" AS ENUM('best_before', 'use_by');--> statement-breakpoint
CREATE TYPE "public"."diet_pattern" AS ENUM('omnivore', 'flexitarian', 'pescatarian', 'vegetarian', 'vegan', 'low_carb', 'keto', 'high_protein', 'mediterranean');--> statement-breakpoint
CREATE TYPE "public"."event_type" AS ENUM('PRODUCT_ADDED', 'PRODUCT_UPDATED', 'PRODUCT_CONSUMED', 'PRODUCT_DISCARDED', 'RECIPE_COOKED', 'RECIPE_RATED', 'RECIPE_CREATED', 'RECIPE_FORKED', 'MEAL_LOGGED', 'MEAL_PHOTO_ANALYZED', 'HOUSEHOLD_MEMBER_ADDED', 'SUBSCRIPTION_STARTED', 'SUBSCRIPTION_CHANGED', 'AI_CORRECTED', 'MEMORY_UPDATED', 'SHOPPING_COMPLETED', 'WEEK_PLAN_UPDATED', 'MEAL_BOX_CREATED', 'MEAL_BOX_CONSUMED');--> statement-breakpoint
CREATE TYPE "public"."expiry_status" AS ENUM('fresh', 'use_soon', 'expiring', 'expired', 'unknown');--> statement-breakpoint
CREATE TYPE "public"."goal_type" AS ENUM('lose_weight', 'gain_weight', 'build_muscle', 'maintain_weight', 'more_protein', 'less_fat', 'more_fiber', 'more_variety', 'less_waste', 'lower_cost', 'cook_more');--> statement-breakpoint
CREATE TYPE "public"."household_role" AS ENUM('owner', 'adult', 'member', 'child');--> statement-breakpoint
CREATE TYPE "public"."inventory_source" AS ENUM('fridge_photo', 'freezer_photo', 'pantry_photo', 'ingredient_photo', 'barcode', 'receipt', 'digital_receipt', 'label_photo', 'manual_search', 'free_text', 'voice', 'cooked_recipe', 'connector', 'seed');--> statement-breakpoint
CREATE TYPE "public"."inventory_transaction_type" AS ENUM('purchase', 'consume', 'discard', 'adjust', 'cook_use', 'leftover_created', 'leftover_consumed', 'correction', 'freeze', 'thaw', 'move');--> statement-breakpoint
CREATE TYPE "public"."job_status" AS ENUM('queued', 'running', 'awaiting_confirmation', 'completed', 'failed', 'canceled');--> statement-breakpoint
CREATE TYPE "public"."job_type" AS ENUM('ANALYZE_FRIDGE_IMAGE', 'ANALYZE_PANTRY_IMAGE', 'ANALYZE_MEAL_IMAGE', 'READ_RECEIPT', 'READ_NUTRITION_LABEL', 'READ_EXPIRY_DATE', 'NORMALIZE_PRODUCTS', 'DEDUPLICATE_INVENTORY', 'CALCULATE_NUTRITION', 'GENERATE_RECIPE_OPTIONS', 'RANK_RECIPES', 'UPDATE_USER_MEMORY', 'GENERATE_WEEK_PLAN', 'SEND_EXPIRY_NOTIFICATION', 'VERIFY_SUBSCRIPTION', 'PROCESS_STORE_NOTIFICATION', 'BUILD_TRAINING_SAMPLE', 'RUN_AI_EVALUATION');--> statement-breakpoint
CREATE TYPE "public"."meal_log_source" AS ENUM('cooked_recipe', 'plate_photo', 'barcode', 'product', 'free_text', 'voice', 'previous_meal', 'meal_box', 'manual');--> statement-breakpoint
CREATE TYPE "public"."meal_type" AS ENUM('breakfast', 'lunch', 'dinner', 'snack', 'dessert', 'starter', 'buffet', 'party');--> statement-breakpoint
CREATE TYPE "public"."memory_kind" AS ENUM('structured_fact', 'event', 'semantic', 'profile_summary', 'recipe_memory');--> statement-breakpoint
CREATE TYPE "public"."notification_type" AS ENUM('expiry_warning', 'meal_box_reminder', 'quick_dinner_suggestion', 'holiday_upcoming', 'creator_new_recipe', 'week_plan_change', 'pantry_forecast', 'subscription_status');--> statement-breakpoint
CREATE TYPE "public"."precision_mode" AS ENUM('simple', 'exact');--> statement-breakpoint
CREATE TYPE "public"."profile_visibility" AS ENUM('private', 'friends', 'national', 'global');--> statement-breakpoint
CREATE TYPE "public"."recipe_difficulty" AS ENUM('beginner', 'easy', 'medium', 'advanced', 'expert');--> statement-breakpoint
CREATE TYPE "public"."recipe_similarity_class" AS ENUM('duplicate', 'variant', 'inspired', 'independent');--> statement-breakpoint
CREATE TYPE "public"."recipe_source_type" AS ENUM('own_editorial', 'ai_assisted_reviewed', 'open_license', 'public_domain', 'licensed_database', 'creator_agreement', 'user_generated');--> statement-breakpoint
CREATE TYPE "public"."recipe_status" AS ENUM('draft', 'submitted', 'ai_checked', 'in_moderation', 'published', 'rejected', 'archived');--> statement-breakpoint
CREATE TYPE "public"."recipe_variant_type" AS ENUM('standard', 'high_protein', 'low_calorie', 'low_fat', 'vegetarian', 'vegan', 'gluten_free', 'lactose_free', 'kid_friendly', 'airfryer', 'budget');--> statement-breakpoint
CREATE TYPE "public"."recipe_verification_status" AS ENUM('unverified', 'community', 'verified', 'editorial');--> statement-breakpoint
CREATE TYPE "public"."religious_rule" AS ENUM('none', 'halal', 'kosher', 'hindu_no_beef', 'buddhist_vegetarian');--> statement-breakpoint
CREATE TYPE "public"."scan_type" AS ENUM('fridge', 'freezer', 'pantry', 'ingredients', 'plate', 'receipt', 'barcode', 'expiry_date', 'nutrition_label', 'product_package');--> statement-breakpoint
CREATE TYPE "public"."sex" AS ENUM('female', 'male', 'unspecified');--> statement-breakpoint
CREATE TYPE "public"."signal_origin" AS ENUM('user_stated', 'observed', 'ai_inferred');--> statement-breakpoint
CREATE TYPE "public"."storage_location_type" AS ENUM('fridge', 'freezer', 'pantry', 'garage_freezer', 'wine_fridge', 'cellar', 'meal_box', 'custom');--> statement-breakpoint
CREATE TYPE "public"."subscription_plan" AS ENUM('free', 'household', 'family', 'large_household');--> statement-breakpoint
CREATE TYPE "public"."subscription_provider" AS ENUM('apple', 'google', 'promo', 'none');--> statement-breakpoint
CREATE TYPE "public"."subscription_status" AS ENUM('trial', 'active', 'in_grace', 'on_hold', 'paused', 'canceled', 'expired');--> statement-breakpoint
CREATE TYPE "public"."taste_axis" AS ENUM('spice', 'salt', 'acid', 'creaminess', 'garlic', 'sweetness', 'herbs', 'umami');--> statement-breakpoint
CREATE TYPE "public"."unit" AS ENUM('GRAM', 'KILOGRAM', 'MILLILITER', 'DECILITER', 'LITER', 'TEASPOON', 'TABLESPOON', 'CUP_US', 'FLUID_OUNCE_US', 'OUNCE', 'POUND', 'COUNT', 'PORTION', 'PINCH', 'SLICE', 'CLOVE', 'CAN', 'PACKAGE');--> statement-breakpoint
CREATE TYPE "public"."user_role" AS ENUM('user', 'moderator', 'admin');--> statement-breakpoint
CREATE TYPE "public"."verification_status" AS ENUM('unverified', 'user_verified', 'editorially_verified');--> statement-breakpoint
CREATE TYPE "public"."measurement_system" AS ENUM('METRIC', 'US_CUSTOMARY', 'MIXED');--> statement-breakpoint
CREATE TYPE "public"."temperature_unit" AS ENUM('CELSIUS', 'FAHRENHEIT');--> statement-breakpoint
CREATE TYPE "public"."translation_source" AS ENUM('seed', 'ai', 'human');--> statement-breakpoint
CREATE TYPE "public"."translation_status" AS ENUM('draft_ai', 'in_review', 'published');--> statement-breakpoint
CREATE TABLE "admin_totp" (
"user_id" uuid PRIMARY KEY NOT NULL,
"secret_base32" text NOT NULL,
"enabled_at" timestamp with time zone,
"last_used_step" integer,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "email_verification_tokens" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid NOT NULL,
"token_hash" text NOT NULL,
"expires_at" timestamp with time zone NOT NULL,
"used_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "password_reset_tokens" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid NOT NULL,
"token_hash" text NOT NULL,
"expires_at" timestamp with time zone NOT NULL,
"used_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "refresh_tokens" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid NOT NULL,
"token_hash" text NOT NULL,
"family_id" uuid NOT NULL,
"expires_at" timestamp with time zone NOT NULL,
"revoked_at" timestamp with time zone,
"replaced_by_token_id" uuid,
"user_agent" text,
"ip" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "user_consents" (
"user_id" uuid NOT NULL,
"kind" "consent_kind" NOT NULL,
"status" "consent_status" NOT NULL,
"granted_at" timestamp with time zone,
"revoked_at" timestamp with time zone,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "user_consents_user_id_kind_pk" PRIMARY KEY("user_id","kind")
);
--> statement-breakpoint
CREATE TABLE "user_credentials" (
"user_id" uuid PRIMARY KEY NOT NULL,
"password_hash" text NOT NULL,
"password_updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "user_health_profiles" (
"user_id" uuid PRIMARY KEY NOT NULL,
"birth_year" integer,
"sex" "sex",
"height_cm" double precision,
"weight_kg" double precision,
"target_weight_kg" double precision,
"activity_level" "activity_level" DEFAULT 'moderate' NOT NULL,
"training_sessions_per_week" integer,
"training_types" text[] DEFAULT '{}' NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "user_preferences" (
"user_id" uuid PRIMARY KEY NOT NULL,
"primary_goal" "goal_type",
"goals" "goal_type"[] DEFAULT '{}' NOT NULL,
"diet_pattern" "diet_pattern" DEFAULT 'omnivore' NOT NULL,
"religious_rule" "religious_rule" DEFAULT 'none' NOT NULL,
"allergens" "allergen"[] DEFAULT '{}' NOT NULL,
"intolerances" text[] DEFAULT '{}' NOT NULL,
"avoid_ingredient_ids" text[] DEFAULT '{}' NOT NULL,
"favorite_cuisines" "cuisine"[] DEFAULT '{}' NOT NULL,
"disliked_dishes" text[] DEFAULT '{}' NOT NULL,
"spice_level_max" integer DEFAULT 3 NOT NULL,
"weekly_budget_minor" integer,
"max_cooking_minutes_weekday" integer,
"equipment" text[] DEFAULT '{}' NOT NULL,
"default_portions" integer DEFAULT 2 NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "users" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"email" text NOT NULL,
"email_verified_at" timestamp with time zone,
"display_name" text NOT NULL,
"role" "user_role" DEFAULT 'user' NOT NULL,
"locale" text DEFAULT 'sv-SE' NOT NULL,
"precision_mode" "precision_mode" DEFAULT 'simple' NOT NULL,
"onboarding_completed" boolean DEFAULT false NOT NULL,
"deleted_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "user_locale_preferences" (
"user_id" uuid PRIMARY KEY NOT NULL,
"language_tag" text DEFAULT 'sv-SE' NOT NULL,
"region_code" text DEFAULT 'SE' NOT NULL,
"time_zone" text DEFAULT 'Europe/Stockholm' NOT NULL,
"measurement_system" "measurement_system" DEFAULT 'METRIC' NOT NULL,
"temperature_unit" "temperature_unit" DEFAULT 'CELSIUS' NOT NULL,
"currency_code" text DEFAULT 'SEK' NOT NULL,
"first_day_of_week" integer DEFAULT 1 NOT NULL,
"use_24_hour_time" boolean DEFAULT true NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "household_members" (
"household_id" uuid NOT NULL,
"user_id" uuid NOT NULL,
"role" "household_role" DEFAULT 'member' NOT NULL,
"portion_factor" double precision DEFAULT 1 NOT NULL,
"joined_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "household_members_household_id_user_id_pk" PRIMARY KEY("household_id","user_id")
);
--> statement-breakpoint
CREATE TABLE "households" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"name" text NOT NULL,
"invite_code" text NOT NULL,
"weekly_budget_minor" integer,
"currency_code" varchar(3) DEFAULT 'SEK' NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "storage_locations" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"household_id" uuid NOT NULL,
"type" "storage_location_type" NOT NULL,
"name" text NOT NULL,
"sublocations" text[] DEFAULT '{}' NOT NULL,
"sort_order" integer DEFAULT 0 NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "canonical_ingredients" (
"id" text PRIMARY KEY NOT NULL,
"name_sv" text NOT NULL,
"name_en" text NOT NULL,
"aliases" text[] DEFAULT '{}' NOT NULL,
"category" text NOT NULL,
"default_unit" "unit" NOT NULL,
"density_g_per_ml" double precision,
"grams_per_piece" double precision,
"allergens" "allergen"[] DEFAULT '{}' NOT NULL,
"is_vegan" boolean DEFAULT false NOT NULL,
"is_vegetarian" boolean DEFAULT false NOT NULL,
"contains_gluten" boolean DEFAULT false NOT NULL,
"contains_lactose" boolean DEFAULT false NOT NULL,
"is_pork" boolean DEFAULT false NOT NULL,
"is_beef" boolean DEFAULT false NOT NULL,
"is_alcohol" boolean DEFAULT false NOT NULL,
"nutrition_per_100" jsonb NOT NULL,
"nutrition_provenance" jsonb NOT NULL,
"peak_seasons" text[] DEFAULT '{}' NOT NULL,
"shelf_life_guidance" jsonb,
"default_price_minor_per_kg" integer,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "substitutions" (
"id" text PRIMARY KEY NOT NULL,
"from_ingredient_id" text NOT NULL,
"to_ingredient_id" text NOT NULL,
"ratio" double precision DEFAULT 1 NOT NULL,
"instructions_sv" text,
"best_for" text[] DEFAULT '{}' NOT NULL,
"not_recommended_for" text[] DEFAULT '{}' NOT NULL,
"flavor_impact_sv" text,
"texture_impact_sv" text,
"priority" integer DEFAULT 0 NOT NULL
);
--> statement-breakpoint
CREATE TABLE "products" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"gtin" text,
"name" text NOT NULL,
"brand" text,
"canonical_ingredient_id" text,
"package_size_value" double precision,
"package_size_unit" "unit",
"ingredients_text" text,
"allergens" "allergen"[] DEFAULT '{}' NOT NULL,
"may_contain_allergens" "allergen"[] DEFAULT '{}' NOT NULL,
"nutrition" jsonb,
"image_urls" text[] DEFAULT '{}' NOT NULL,
"language" text DEFAULT 'sv' NOT NULL,
"market" text DEFAULT 'SE' NOT NULL,
"data_source" text NOT NULL,
"verification_status" "verification_status" DEFAULT 'unverified' NOT NULL,
"version" integer DEFAULT 1 NOT NULL,
"valid_from" timestamp with time zone DEFAULT now() NOT NULL,
"valid_to" timestamp with time zone,
"created_by_user_id" uuid,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "inventory_items" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"household_id" uuid NOT NULL,
"canonical_ingredient_id" text,
"product_id" uuid,
"display_name" text NOT NULL,
"brand" text,
"quantity" double precision DEFAULT 0 NOT NULL,
"unit" "unit" NOT NULL,
"storage_location_id" uuid NOT NULL,
"sublocation" text,
"purchased_at" date,
"opened_at" date,
"best_before_date" date,
"use_by_date" date,
"date_kind" date_kind,
"frozen_at" date,
"thawed_at" date,
"price_minor" integer,
"nutrition_per_100" jsonb,
"source" "inventory_source" NOT NULL,
"confidence" double precision DEFAULT 1 NOT NULL,
"verified_by_user" boolean DEFAULT false NOT NULL,
"last_verified_at" timestamp with time zone,
"expiry_status" "expiry_status" DEFAULT 'unknown' NOT NULL,
"depleted_at" timestamp with time zone,
"model_version" text,
"prompt_version" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "inventory_transactions" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"household_id" uuid NOT NULL,
"inventory_item_id" uuid NOT NULL,
"type" "inventory_transaction_type" NOT NULL,
"quantity_delta" double precision NOT NULL,
"unit" "unit" NOT NULL,
"ref_type" text,
"ref_id" uuid,
"actor_user_id" uuid,
"note" text,
"value_minor" integer,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "recipe_cooks" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"recipe_id" uuid NOT NULL,
"user_id" uuid NOT NULL,
"household_id" uuid,
"portions_cooked" integer NOT NULL,
"cooked_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "recipe_favorites" (
"recipe_id" uuid NOT NULL,
"user_id" uuid NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "recipe_favorites_recipe_id_user_id_pk" PRIMARY KEY("recipe_id","user_id")
);
--> statement-breakpoint
CREATE TABLE "recipe_ingredients" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"recipe_id" uuid NOT NULL,
"canonical_ingredient_id" text NOT NULL,
"display_name_sv" text NOT NULL,
"quantity" double precision NOT NULL,
"unit" "unit" NOT NULL,
"note" text,
"optional" boolean DEFAULT false NOT NULL,
"group_name" text,
"sort_order" integer DEFAULT 0 NOT NULL
);
--> statement-breakpoint
CREATE TABLE "recipe_ratings" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"recipe_id" uuid NOT NULL,
"user_id" uuid NOT NULL,
"stars" integer NOT NULL,
"feedback_tags" text[] DEFAULT '{}' NOT NULL,
"comment" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "recipe_similarities" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"recipe_a_id" uuid NOT NULL,
"recipe_b_id" uuid NOT NULL,
"similarity_score" double precision NOT NULL,
"classification" "recipe_similarity_class" NOT NULL,
"details" jsonb,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "recipe_source_registry" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"source_name" text NOT NULL,
"license" text NOT NULL,
"right_to_store" boolean NOT NULL,
"right_to_modify" boolean NOT NULL,
"right_to_display" boolean NOT NULL,
"attribution_required" boolean DEFAULT false NOT NULL,
"attribution_text" text,
"commercial_use" boolean NOT NULL,
"valid_from" timestamp with time zone DEFAULT now() NOT NULL,
"valid_to" timestamp with time zone,
"notes" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "recipe_steps" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"recipe_id" uuid NOT NULL,
"step_number" integer NOT NULL,
"instruction_sv" text NOT NULL,
"timer_seconds" integer,
"temperature_c" integer,
"tip" text
);
--> statement-breakpoint
CREATE TABLE "recipes" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"slug" text NOT NULL,
"title_sv" text NOT NULL,
"description_sv" text DEFAULT '' NOT NULL,
"country" text,
"region" text,
"cuisine" "cuisine" NOT NULL,
"meal_types" "meal_type"[] DEFAULT '{}' NOT NULL,
"tags" text[] DEFAULT '{}' NOT NULL,
"methods" text[] DEFAULT '{}' NOT NULL,
"equipment" text[] DEFAULT '{}' NOT NULL,
"difficulty" "recipe_difficulty" DEFAULT 'easy' NOT NULL,
"prep_time_minutes" integer DEFAULT 0 NOT NULL,
"cook_time_minutes" integer DEFAULT 0 NOT NULL,
"total_time_minutes" integer DEFAULT 0 NOT NULL,
"portions" integer DEFAULT 4 NOT NULL,
"nutrition_per_portion" jsonb NOT NULL,
"allergens" "allergen"[] DEFAULT '{}' NOT NULL,
"spice_level" integer DEFAULT 0 NOT NULL,
"estimated_cost_minor_per_portion" integer,
"storage_guidance_sv" text,
"meal_prep_friendly" boolean DEFAULT false NOT NULL,
"freezer_friendly" boolean DEFAULT false NOT NULL,
"peak_seasons" text[] DEFAULT '{}' NOT NULL,
"holiday_tags" text[] DEFAULT '{}' NOT NULL,
"dna" jsonb NOT NULL,
"variant_type" "recipe_variant_type" DEFAULT 'standard' NOT NULL,
"variant_of_recipe_id" uuid,
"forked_from_recipe_id" uuid,
"status" "recipe_status" DEFAULT 'draft' NOT NULL,
"verification_status" "recipe_verification_status" DEFAULT 'unverified' NOT NULL,
"source_type" "recipe_source_type" NOT NULL,
"source_registry_id" uuid,
"creator_user_id" uuid,
"creator_display_name" text,
"image_urls" text[] DEFAULT '{}' NOT NULL,
"version" integer DEFAULT 1 NOT NULL,
"rating_average" double precision,
"rating_count" integer DEFAULT 0 NOT NULL,
"cook_count" integer DEFAULT 0 NOT NULL,
"favorite_count" integer DEFAULT 0 NOT NULL,
"moderation_note" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "ingredient_translations" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"ingredient_id" text NOT NULL,
"language_tag" varchar(35) NOT NULL,
"name" text NOT NULL,
"aliases" text[] DEFAULT '{}' NOT NULL,
"source" "translation_source" DEFAULT 'seed' NOT NULL,
"status" "translation_status" DEFAULT 'published' NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "recipe_step_translations" (
"recipe_id" uuid NOT NULL,
"language_tag" varchar(35) NOT NULL,
"step_number" integer NOT NULL,
"instruction" text NOT NULL,
"tip" text,
CONSTRAINT "recipe_step_translations_recipe_id_language_tag_step_number_pk" PRIMARY KEY("recipe_id","language_tag","step_number")
);
--> statement-breakpoint
CREATE TABLE "recipe_translations" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"recipe_id" uuid NOT NULL,
"language_tag" varchar(35) NOT NULL,
"title" text NOT NULL,
"description" text,
"storage_guidance" text,
"status" "translation_status" DEFAULT 'draft_ai' NOT NULL,
"source" "translation_source" DEFAULT 'ai' NOT NULL,
"verification" jsonb,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "unit_translations" (
"unit_code" "unit" NOT NULL,
"language_tag" varchar(35) NOT NULL,
"abbreviation" text NOT NULL,
"name" text NOT NULL,
CONSTRAINT "unit_translations_unit_code_language_tag_pk" PRIMARY KEY("unit_code","language_tag")
);
--> statement-breakpoint
CREATE TABLE "allergen_market_rules" (
"region_code" varchar(2) NOT NULL,
"allergen" "allergen" NOT NULL,
"must_highlight" boolean DEFAULT true NOT NULL,
CONSTRAINT "allergen_market_rules_region_code_allergen_pk" PRIMARY KEY("region_code","allergen")
);
--> statement-breakpoint
CREATE TABLE "nutrition_display_profiles" (
"region_code" varchar(2) PRIMARY KEY NOT NULL,
"energy_display" text NOT NULL,
"salt_display" text NOT NULL,
"energy_label_key" text NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "meal_boxes" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"household_id" uuid NOT NULL,
"recipe_id" uuid,
"title_sv" text NOT NULL,
"portions" integer NOT NULL,
"portions_remaining" integer NOT NULL,
"nutrition_per_portion" jsonb,
"cooked_at" date NOT NULL,
"storage_location_id" uuid NOT NULL,
"frozen" boolean DEFAULT false NOT NULL,
"recommended_use_by" date NOT NULL,
"reserved_for_user_id" uuid,
"status" text DEFAULT 'available' NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "meals" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid NOT NULL,
"household_id" uuid,
"date" date NOT NULL,
"meal_type" "meal_type" NOT NULL,
"source" "meal_log_source" NOT NULL,
"recipe_id" uuid,
"title_sv" text NOT NULL,
"portion_fraction" double precision DEFAULT 1 NOT NULL,
"nutrition" jsonb NOT NULL,
"nutrition_is_estimate" boolean DEFAULT false NOT NULL,
"estimate_min_kcal" double precision,
"estimate_max_kcal" double precision,
"items" jsonb,
"photo_url" text,
"scan_job_id" uuid,
"logged_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "shopping_list_items" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"shopping_list_id" uuid NOT NULL,
"canonical_ingredient_id" text,
"display_name" text NOT NULL,
"quantity" double precision DEFAULT 1 NOT NULL,
"unit" "unit" DEFAULT 'COUNT' NOT NULL,
"store_section" text DEFAULT 'hygien_ovrigt' NOT NULL,
"suggested_package_size" text,
"estimated_price_minor" integer,
"checked" boolean DEFAULT false NOT NULL,
"added_by_user_id" uuid,
"origin" text DEFAULT 'manual' NOT NULL,
"sort_order" integer DEFAULT 0 NOT NULL
);
--> statement-breakpoint
CREATE TABLE "shopping_lists" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"household_id" uuid NOT NULL,
"name" text DEFAULT 'Inköpslista' NOT NULL,
"status" text DEFAULT 'active' NOT NULL,
"week_plan_id" uuid,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "week_plan_entries" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"week_plan_id" uuid NOT NULL,
"date" date NOT NULL,
"meal_type" "meal_type" NOT NULL,
"recipe_id" uuid,
"meal_box_id" uuid,
"title_sv" text NOT NULL,
"portions" integer DEFAULT 2 NOT NULL,
"status" text DEFAULT 'planned' NOT NULL,
"reschedule_reason_sv" text,
"sort_order" integer DEFAULT 0 NOT NULL
);
--> statement-breakpoint
CREATE TABLE "week_plans" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"household_id" uuid NOT NULL,
"week_start_date" date NOT NULL,
"status" text DEFAULT 'draft' NOT NULL,
"generated_by" text DEFAULT 'user' NOT NULL,
"notes" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "price_observations" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"canonical_ingredient_id" text,
"product_id" uuid,
"store_name" text,
"price_minor" integer NOT NULL,
"quantity" double precision,
"unit" "unit",
"price_per_kg_minor" integer,
"observed_at" date NOT NULL,
"source" text DEFAULT 'receipt' NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "receipt_lines" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"receipt_id" uuid NOT NULL,
"raw_text" text NOT NULL,
"normalized_name" text,
"canonical_ingredient_id" text,
"product_id" uuid,
"quantity" double precision,
"unit" "unit",
"unit_price_minor" integer,
"total_price_minor" integer,
"confidence" double precision DEFAULT 0 NOT NULL,
"verified_by_user" boolean DEFAULT false NOT NULL,
"added_to_inventory" boolean DEFAULT false NOT NULL
);
--> statement-breakpoint
CREATE TABLE "receipts" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"household_id" uuid NOT NULL,
"store_name" text,
"purchase_date" date,
"total_minor" integer,
"discount_minor" integer,
"image_url" text,
"scan_job_id" uuid,
"status" text DEFAULT 'pending' NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "ai_corrections" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"scan_job_id" uuid,
"user_id" uuid NOT NULL,
"task_type" text NOT NULL,
"ai_output" jsonb NOT NULL,
"user_correction" jsonb NOT NULL,
"model_version" text,
"prompt_version" text,
"consent_snapshot" jsonb NOT NULL,
"exported_to_training" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "scan_jobs" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid NOT NULL,
"household_id" uuid,
"scan_type" "scan_type" NOT NULL,
"job_type" "job_type" NOT NULL,
"status" "job_status" DEFAULT 'queued' NOT NULL,
"s3_keys" text[] DEFAULT '{}' NOT NULL,
"context" jsonb,
"result" jsonb,
"error" text,
"model_version" text,
"prompt_version" text,
"latency_ms" integer,
"cost_usd" double precision,
"attempts" integer DEFAULT 0 NOT NULL,
"completed_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "food_memories" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid,
"household_id" uuid,
"recipe_id" uuid,
"title_sv" text NOT NULL,
"summary_sv" text NOT NULL,
"holiday_tag" text,
"photo_url" text,
"stars" double precision,
"occurred_at" timestamp with time zone NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "memory_items" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid,
"household_id" uuid,
"kind" "memory_kind" NOT NULL,
"key" text NOT NULL,
"summary_sv" text NOT NULL,
"value" jsonb,
"origin" "signal_origin" NOT NULL,
"confidence" double precision DEFAULT 0.5 NOT NULL,
"verified_by_user" boolean DEFAULT false NOT NULL,
"paused" boolean DEFAULT false NOT NULL,
"last_used_at" timestamp with time zone,
"expires_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "taste_signals" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid NOT NULL,
"axis" "taste_axis" NOT NULL,
"direction" double precision NOT NULL,
"strength" double precision DEFAULT 0.5 NOT NULL,
"origin" "signal_origin" NOT NULL,
"ref_recipe_id" uuid,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "season_events" (
"id" text PRIMARY KEY NOT NULL,
"slug" text NOT NULL,
"name_sv" text NOT NULL,
"market" text DEFAULT 'SE' NOT NULL,
"date_rule" jsonb NOT NULL,
"lead_days" integer DEFAULT 7 NOT NULL,
"food_tags" text[] DEFAULT '{}' NOT NULL,
"recipe_slugs" text[] DEFAULT '{}' NOT NULL,
"priority" integer DEFAULT 0 NOT NULL,
"active" boolean DEFAULT true NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "ai_usage_counters" (
"user_id" uuid NOT NULL,
"month" text NOT NULL,
"ai_scans" integer DEFAULT 0 NOT NULL,
"ai_tokens_in" integer DEFAULT 0 NOT NULL,
"ai_tokens_out" integer DEFAULT 0 NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "store_notifications" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"provider" "subscription_provider" NOT NULL,
"notification_type" text,
"raw_payload" jsonb NOT NULL,
"signature_verified" boolean DEFAULT false NOT NULL,
"processed" boolean DEFAULT false NOT NULL,
"processed_at" timestamp with time zone,
"error" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "store_transactions" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"provider" "subscription_provider" NOT NULL,
"transaction_id" text NOT NULL,
"original_transaction_id" text,
"user_id" uuid,
"product_id" text,
"raw_payload" jsonb NOT NULL,
"processed_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "subscription_events" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"subscription_id" uuid,
"user_id" uuid,
"event_type" text NOT NULL,
"payload" jsonb,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "subscriptions" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid NOT NULL,
"household_id" uuid,
"provider" "subscription_provider" NOT NULL,
"product_id" text NOT NULL,
"plan" "subscription_plan" NOT NULL,
"original_transaction_id" text,
"status" "subscription_status" NOT NULL,
"purchased_at" timestamp with time zone,
"expires_at" timestamp with time zone,
"grace_period_expires_at" timestamp with time zone,
"canceled_at" timestamp with time zone,
"last_verified_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "trials" (
"user_id" uuid PRIMARY KEY NOT NULL,
"started_at" timestamp with time zone DEFAULT now() NOT NULL,
"ends_at" timestamp with time zone NOT NULL
);
--> statement-breakpoint
CREATE TABLE "ai_eval_cases" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"task_type" text NOT NULL,
"name_sv" text NOT NULL,
"input_ref" jsonb NOT NULL,
"expected_output" jsonb NOT NULL,
"category" text DEFAULT 'standard' NOT NULL,
"active" boolean DEFAULT true NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "ai_eval_runs" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"task_type" text NOT NULL,
"model_version" text NOT NULL,
"prompt_version" text NOT NULL,
"metrics" jsonb NOT NULL,
"passed" boolean NOT NULL,
"notes" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "audit_logs" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"actor_user_id" uuid,
"actor_type" text DEFAULT 'user' NOT NULL,
"action" text NOT NULL,
"target_type" text,
"target_id" text,
"metadata" jsonb,
"ip" text,
"correlation_id" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "creator_follows" (
"follower_user_id" uuid NOT NULL,
"creator_user_id" uuid NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "creator_follows_follower_user_id_creator_user_id_pk" PRIMARY KEY("follower_user_id","creator_user_id")
);
--> statement-breakpoint
CREATE TABLE "creator_stats" (
"user_id" uuid PRIMARY KEY NOT NULL,
"visibility" "profile_visibility" DEFAULT 'private' NOT NULL,
"level" "creator_level" DEFAULT 'beginner' NOT NULL,
"published_recipes" integer DEFAULT 0 NOT NULL,
"followers" integer DEFAULT 0 NOT NULL,
"total_cooks" integer DEFAULT 0 NOT NULL,
"total_favorites" integer DEFAULT 0 NOT NULL,
"average_rating" double precision,
"verified_recipes" integer DEFAULT 0 NOT NULL,
"badges" text[] DEFAULT '{}' NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "domain_events" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"type" "event_type" NOT NULL,
"user_id" uuid,
"household_id" uuid,
"payload" jsonb NOT NULL,
"correlation_id" text,
"occurred_at" timestamp with time zone DEFAULT now() NOT NULL,
"published_at" timestamp with time zone
);
--> statement-breakpoint
CREATE TABLE "feature_flags" (
"key" text PRIMARY KEY NOT NULL,
"enabled" boolean DEFAULT false NOT NULL,
"description_sv" text,
"rollout_percent" integer DEFAULT 100 NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "idempotency_keys" (
"user_id" uuid NOT NULL,
"key" text NOT NULL,
"endpoint" text NOT NULL,
"response_status" integer,
"response_body" jsonb,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "idempotency_keys_user_id_key_endpoint_pk" PRIMARY KEY("user_id","key","endpoint")
);
--> statement-breakpoint
CREATE TABLE "notifications" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid NOT NULL,
"type" "notification_type" NOT NULL,
"title_sv" text NOT NULL,
"body_sv" text NOT NULL,
"data" jsonb,
"template_key" text,
"variables" jsonb,
"locale" text,
"scheduled_for" timestamp with time zone,
"sent_at" timestamp with time zone,
"read_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "push_tokens" (
"user_id" uuid NOT NULL,
"token" text NOT NULL,
"platform" text NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "push_tokens_user_id_token_pk" PRIMARY KEY("user_id","token")
);
--> statement-breakpoint
CREATE TABLE "waste_summaries" (
"household_id" uuid NOT NULL,
"week_start_date" text NOT NULL,
"discarded_count" integer DEFAULT 0 NOT NULL,
"discarded_value_minor" integer DEFAULT 0 NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "waste_summaries_household_id_week_start_date_pk" PRIMARY KEY("household_id","week_start_date")
);
--> statement-breakpoint
ALTER TABLE "admin_totp" ADD CONSTRAINT "admin_totp_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "email_verification_tokens" ADD CONSTRAINT "email_verification_tokens_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "password_reset_tokens" ADD CONSTRAINT "password_reset_tokens_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "refresh_tokens" ADD CONSTRAINT "refresh_tokens_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_consents" ADD CONSTRAINT "user_consents_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_credentials" ADD CONSTRAINT "user_credentials_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_health_profiles" ADD CONSTRAINT "user_health_profiles_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_preferences" ADD CONSTRAINT "user_preferences_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_locale_preferences" ADD CONSTRAINT "user_locale_preferences_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "household_members" ADD CONSTRAINT "household_members_household_id_households_id_fk" FOREIGN KEY ("household_id") REFERENCES "public"."households"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "household_members" ADD CONSTRAINT "household_members_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "storage_locations" ADD CONSTRAINT "storage_locations_household_id_households_id_fk" FOREIGN KEY ("household_id") REFERENCES "public"."households"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "substitutions" ADD CONSTRAINT "substitutions_from_ingredient_id_canonical_ingredients_id_fk" FOREIGN KEY ("from_ingredient_id") REFERENCES "public"."canonical_ingredients"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "substitutions" ADD CONSTRAINT "substitutions_to_ingredient_id_canonical_ingredients_id_fk" FOREIGN KEY ("to_ingredient_id") REFERENCES "public"."canonical_ingredients"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "products" ADD CONSTRAINT "products_canonical_ingredient_id_canonical_ingredients_id_fk" FOREIGN KEY ("canonical_ingredient_id") REFERENCES "public"."canonical_ingredients"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "inventory_items" ADD CONSTRAINT "inventory_items_household_id_households_id_fk" FOREIGN KEY ("household_id") REFERENCES "public"."households"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "inventory_items" ADD CONSTRAINT "inventory_items_canonical_ingredient_id_canonical_ingredients_id_fk" FOREIGN KEY ("canonical_ingredient_id") REFERENCES "public"."canonical_ingredients"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "inventory_items" ADD CONSTRAINT "inventory_items_product_id_products_id_fk" FOREIGN KEY ("product_id") REFERENCES "public"."products"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "inventory_items" ADD CONSTRAINT "inventory_items_storage_location_id_storage_locations_id_fk" FOREIGN KEY ("storage_location_id") REFERENCES "public"."storage_locations"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "inventory_transactions" ADD CONSTRAINT "inventory_transactions_household_id_households_id_fk" FOREIGN KEY ("household_id") REFERENCES "public"."households"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "inventory_transactions" ADD CONSTRAINT "inventory_transactions_inventory_item_id_inventory_items_id_fk" FOREIGN KEY ("inventory_item_id") REFERENCES "public"."inventory_items"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "inventory_transactions" ADD CONSTRAINT "inventory_transactions_actor_user_id_users_id_fk" FOREIGN KEY ("actor_user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "recipe_cooks" ADD CONSTRAINT "recipe_cooks_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_cooks" ADD CONSTRAINT "recipe_cooks_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_favorites" ADD CONSTRAINT "recipe_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 "recipe_favorites" ADD CONSTRAINT "recipe_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 "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_canonical_ingredient_id_canonical_ingredients_id_fk" FOREIGN KEY ("canonical_ingredient_id") REFERENCES "public"."canonical_ingredients"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "recipe_ratings" ADD CONSTRAINT "recipe_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 "recipe_ratings" ADD CONSTRAINT "recipe_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 "recipe_similarities" ADD CONSTRAINT "recipe_similarities_recipe_a_id_recipes_id_fk" FOREIGN KEY ("recipe_a_id") REFERENCES "public"."recipes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "recipe_similarities" ADD CONSTRAINT "recipe_similarities_recipe_b_id_recipes_id_fk" FOREIGN KEY ("recipe_b_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 "recipes" ADD CONSTRAINT "recipes_source_registry_id_recipe_source_registry_id_fk" FOREIGN KEY ("source_registry_id") REFERENCES "public"."recipe_source_registry"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "recipes" ADD CONSTRAINT "recipes_creator_user_id_users_id_fk" FOREIGN KEY ("creator_user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "ingredient_translations" ADD CONSTRAINT "ingredient_translations_ingredient_id_canonical_ingredients_id_fk" FOREIGN KEY ("ingredient_id") REFERENCES "public"."canonical_ingredients"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "recipe_step_translations" ADD CONSTRAINT "recipe_step_translations_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_translations" ADD CONSTRAINT "recipe_translations_recipe_id_recipes_id_fk" FOREIGN KEY ("recipe_id") REFERENCES "public"."recipes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "meal_boxes" ADD CONSTRAINT "meal_boxes_household_id_households_id_fk" FOREIGN KEY ("household_id") REFERENCES "public"."households"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "meal_boxes" ADD CONSTRAINT "meal_boxes_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_boxes" ADD CONSTRAINT "meal_boxes_storage_location_id_storage_locations_id_fk" FOREIGN KEY ("storage_location_id") REFERENCES "public"."storage_locations"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "meal_boxes" ADD CONSTRAINT "meal_boxes_reserved_for_user_id_users_id_fk" FOREIGN KEY ("reserved_for_user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "meals" ADD CONSTRAINT "meals_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "meals" ADD CONSTRAINT "meals_household_id_households_id_fk" FOREIGN KEY ("household_id") REFERENCES "public"."households"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "meals" ADD CONSTRAINT "meals_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 "shopping_list_items" ADD CONSTRAINT "shopping_list_items_shopping_list_id_shopping_lists_id_fk" FOREIGN KEY ("shopping_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_canonical_ingredient_id_canonical_ingredients_id_fk" FOREIGN KEY ("canonical_ingredient_id") REFERENCES "public"."canonical_ingredients"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "shopping_list_items" ADD CONSTRAINT "shopping_list_items_added_by_user_id_users_id_fk" FOREIGN KEY ("added_by_user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "shopping_lists" ADD CONSTRAINT "shopping_lists_household_id_households_id_fk" FOREIGN KEY ("household_id") REFERENCES "public"."households"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "shopping_lists" ADD CONSTRAINT "shopping_lists_week_plan_id_week_plans_id_fk" FOREIGN KEY ("week_plan_id") REFERENCES "public"."week_plans"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "week_plan_entries" ADD CONSTRAINT "week_plan_entries_week_plan_id_week_plans_id_fk" FOREIGN KEY ("week_plan_id") REFERENCES "public"."week_plans"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "week_plan_entries" ADD CONSTRAINT "week_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 "week_plan_entries" ADD CONSTRAINT "week_plan_entries_meal_box_id_meal_boxes_id_fk" FOREIGN KEY ("meal_box_id") REFERENCES "public"."meal_boxes"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "week_plans" ADD CONSTRAINT "week_plans_household_id_households_id_fk" FOREIGN KEY ("household_id") REFERENCES "public"."households"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "price_observations" ADD CONSTRAINT "price_observations_canonical_ingredient_id_canonical_ingredients_id_fk" FOREIGN KEY ("canonical_ingredient_id") REFERENCES "public"."canonical_ingredients"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "price_observations" ADD CONSTRAINT "price_observations_product_id_products_id_fk" FOREIGN KEY ("product_id") REFERENCES "public"."products"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "receipt_lines" ADD CONSTRAINT "receipt_lines_receipt_id_receipts_id_fk" FOREIGN KEY ("receipt_id") REFERENCES "public"."receipts"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "receipt_lines" ADD CONSTRAINT "receipt_lines_canonical_ingredient_id_canonical_ingredients_id_fk" FOREIGN KEY ("canonical_ingredient_id") REFERENCES "public"."canonical_ingredients"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "receipt_lines" ADD CONSTRAINT "receipt_lines_product_id_products_id_fk" FOREIGN KEY ("product_id") REFERENCES "public"."products"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "receipts" ADD CONSTRAINT "receipts_household_id_households_id_fk" FOREIGN KEY ("household_id") REFERENCES "public"."households"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "ai_corrections" ADD CONSTRAINT "ai_corrections_scan_job_id_scan_jobs_id_fk" FOREIGN KEY ("scan_job_id") REFERENCES "public"."scan_jobs"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "ai_corrections" ADD CONSTRAINT "ai_corrections_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "scan_jobs" ADD CONSTRAINT "scan_jobs_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "scan_jobs" ADD CONSTRAINT "scan_jobs_household_id_households_id_fk" FOREIGN KEY ("household_id") REFERENCES "public"."households"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "food_memories" ADD CONSTRAINT "food_memories_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "food_memories" ADD CONSTRAINT "food_memories_household_id_households_id_fk" FOREIGN KEY ("household_id") REFERENCES "public"."households"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "food_memories" ADD CONSTRAINT "food_memories_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 "memory_items" ADD CONSTRAINT "memory_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 "memory_items" ADD CONSTRAINT "memory_items_household_id_households_id_fk" FOREIGN KEY ("household_id") REFERENCES "public"."households"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "taste_signals" ADD CONSTRAINT "taste_signals_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "taste_signals" ADD CONSTRAINT "taste_signals_ref_recipe_id_recipes_id_fk" FOREIGN KEY ("ref_recipe_id") REFERENCES "public"."recipes"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "ai_usage_counters" ADD CONSTRAINT "ai_usage_counters_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "store_transactions" ADD CONSTRAINT "store_transactions_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 "subscription_events" ADD CONSTRAINT "subscription_events_subscription_id_subscriptions_id_fk" FOREIGN KEY ("subscription_id") REFERENCES "public"."subscriptions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "subscription_events" ADD CONSTRAINT "subscription_events_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 "subscriptions" ADD CONSTRAINT "subscriptions_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "subscriptions" ADD CONSTRAINT "subscriptions_household_id_households_id_fk" FOREIGN KEY ("household_id") REFERENCES "public"."households"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "trials" ADD CONSTRAINT "trials_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "creator_follows" ADD CONSTRAINT "creator_follows_follower_user_id_users_id_fk" FOREIGN KEY ("follower_user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "creator_follows" ADD CONSTRAINT "creator_follows_creator_user_id_users_id_fk" FOREIGN KEY ("creator_user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "creator_stats" ADD CONSTRAINT "creator_stats_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "idempotency_keys" ADD CONSTRAINT "idempotency_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 "notifications" ADD CONSTRAINT "notifications_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "push_tokens" ADD CONSTRAINT "push_tokens_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "waste_summaries" ADD CONSTRAINT "waste_summaries_household_id_households_id_fk" FOREIGN KEY ("household_id") REFERENCES "public"."households"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
CREATE INDEX "email_verification_tokens_user_idx" ON "email_verification_tokens" USING btree ("user_id");--> statement-breakpoint
CREATE UNIQUE INDEX "email_verification_tokens_hash_unique" ON "email_verification_tokens" USING btree ("token_hash");--> statement-breakpoint
CREATE INDEX "password_reset_tokens_user_idx" ON "password_reset_tokens" USING btree ("user_id");--> statement-breakpoint
CREATE UNIQUE INDEX "password_reset_tokens_hash_unique" ON "password_reset_tokens" USING btree ("token_hash");--> statement-breakpoint
CREATE INDEX "refresh_tokens_user_idx" ON "refresh_tokens" USING btree ("user_id");--> statement-breakpoint
CREATE UNIQUE INDEX "refresh_tokens_hash_unique" ON "refresh_tokens" USING btree ("token_hash");--> statement-breakpoint
CREATE UNIQUE INDEX "users_email_unique" ON "users" USING btree ("email");--> statement-breakpoint
CREATE INDEX "household_members_user_idx" ON "household_members" USING btree ("user_id");--> statement-breakpoint
CREATE UNIQUE INDEX "households_invite_code_unique" ON "households" USING btree ("invite_code");--> statement-breakpoint
CREATE INDEX "storage_locations_household_idx" ON "storage_locations" USING btree ("household_id");--> statement-breakpoint
CREATE INDEX "canonical_ingredients_category_idx" ON "canonical_ingredients" USING btree ("category");--> statement-breakpoint
CREATE INDEX "substitutions_from_idx" ON "substitutions" USING btree ("from_ingredient_id");--> statement-breakpoint
CREATE UNIQUE INDEX "substitutions_pair_unique" ON "substitutions" USING btree ("from_ingredient_id","to_ingredient_id");--> statement-breakpoint
CREATE UNIQUE INDEX "products_gtin_version_unique" ON "products" USING btree ("gtin","version") WHERE "products"."gtin" IS NOT NULL;--> statement-breakpoint
CREATE INDEX "products_gtin_current_idx" ON "products" USING btree ("gtin") WHERE "products"."valid_to" IS NULL;--> statement-breakpoint
CREATE INDEX "products_canonical_idx" ON "products" USING btree ("canonical_ingredient_id");--> statement-breakpoint
CREATE INDEX "inventory_items_household_idx" ON "inventory_items" USING btree ("household_id");--> statement-breakpoint
CREATE INDEX "inventory_items_household_bb_idx" ON "inventory_items" USING btree ("household_id","best_before_date");--> statement-breakpoint
CREATE INDEX "inventory_items_location_idx" ON "inventory_items" USING btree ("storage_location_id");--> statement-breakpoint
CREATE INDEX "inventory_items_canonical_idx" ON "inventory_items" USING btree ("canonical_ingredient_id");--> statement-breakpoint
CREATE INDEX "inventory_tx_item_idx" ON "inventory_transactions" USING btree ("inventory_item_id");--> statement-breakpoint
CREATE INDEX "inventory_tx_household_time_idx" ON "inventory_transactions" USING btree ("household_id","created_at");--> statement-breakpoint
CREATE INDEX "inventory_tx_type_idx" ON "inventory_transactions" USING btree ("type");--> statement-breakpoint
CREATE INDEX "recipe_cooks_recipe_idx" ON "recipe_cooks" USING btree ("recipe_id");--> statement-breakpoint
CREATE INDEX "recipe_cooks_user_idx" ON "recipe_cooks" USING btree ("user_id");--> statement-breakpoint
CREATE INDEX "recipe_favorites_user_idx" ON "recipe_favorites" USING btree ("user_id");--> statement-breakpoint
CREATE INDEX "recipe_ingredients_recipe_idx" ON "recipe_ingredients" USING btree ("recipe_id");--> statement-breakpoint
CREATE INDEX "recipe_ingredients_canonical_idx" ON "recipe_ingredients" USING btree ("canonical_ingredient_id");--> statement-breakpoint
CREATE UNIQUE INDEX "recipe_ratings_user_recipe_unique" ON "recipe_ratings" USING btree ("recipe_id","user_id");--> statement-breakpoint
CREATE INDEX "recipe_ratings_recipe_idx" ON "recipe_ratings" USING btree ("recipe_id");--> statement-breakpoint
CREATE UNIQUE INDEX "recipe_similarities_pair_unique" ON "recipe_similarities" USING btree ("recipe_a_id","recipe_b_id");--> statement-breakpoint
CREATE INDEX "recipe_steps_recipe_idx" ON "recipe_steps" USING btree ("recipe_id");--> statement-breakpoint
CREATE UNIQUE INDEX "recipe_steps_recipe_step_unique" ON "recipe_steps" USING btree ("recipe_id","step_number");--> statement-breakpoint
CREATE UNIQUE INDEX "recipes_slug_unique" ON "recipes" USING btree ("slug");--> statement-breakpoint
CREATE INDEX "recipes_status_idx" ON "recipes" USING btree ("status");--> statement-breakpoint
CREATE INDEX "recipes_cuisine_idx" ON "recipes" USING btree ("cuisine");--> statement-breakpoint
CREATE INDEX "recipes_variant_of_idx" ON "recipes" USING btree ("variant_of_recipe_id");--> statement-breakpoint
CREATE INDEX "recipes_creator_idx" ON "recipes" USING btree ("creator_user_id");--> statement-breakpoint
CREATE INDEX "recipes_total_time_idx" ON "recipes" USING btree ("total_time_minutes");--> statement-breakpoint
CREATE UNIQUE INDEX "ingredient_translations_unique" ON "ingredient_translations" USING btree ("ingredient_id","language_tag");--> statement-breakpoint
CREATE INDEX "ingredient_translations_lang_idx" ON "ingredient_translations" USING btree ("language_tag");--> statement-breakpoint
CREATE UNIQUE INDEX "recipe_translations_unique" ON "recipe_translations" USING btree ("recipe_id","language_tag");--> statement-breakpoint
CREATE INDEX "recipe_translations_lang_idx" ON "recipe_translations" USING btree ("language_tag","status");--> statement-breakpoint
CREATE INDEX "meal_boxes_household_idx" ON "meal_boxes" USING btree ("household_id");--> statement-breakpoint
CREATE INDEX "meal_boxes_use_by_idx" ON "meal_boxes" USING btree ("household_id","recommended_use_by");--> statement-breakpoint
CREATE INDEX "meals_user_date_idx" ON "meals" USING btree ("user_id","date");--> statement-breakpoint
CREATE INDEX "meals_household_idx" ON "meals" USING btree ("household_id");--> statement-breakpoint
CREATE INDEX "shopping_list_items_list_idx" ON "shopping_list_items" USING btree ("shopping_list_id");--> statement-breakpoint
CREATE INDEX "shopping_lists_household_idx" ON "shopping_lists" USING btree ("household_id");--> statement-breakpoint
CREATE INDEX "week_plan_entries_plan_idx" ON "week_plan_entries" USING btree ("week_plan_id");--> statement-breakpoint
CREATE INDEX "week_plans_household_week_idx" ON "week_plans" USING btree ("household_id","week_start_date");--> statement-breakpoint
CREATE INDEX "price_observations_ingredient_idx" ON "price_observations" USING btree ("canonical_ingredient_id","observed_at");--> statement-breakpoint
CREATE INDEX "receipt_lines_receipt_idx" ON "receipt_lines" USING btree ("receipt_id");--> statement-breakpoint
CREATE INDEX "receipts_household_idx" ON "receipts" USING btree ("household_id","purchase_date");--> statement-breakpoint
CREATE INDEX "ai_corrections_task_idx" ON "ai_corrections" USING btree ("task_type","created_at");--> statement-breakpoint
CREATE INDEX "scan_jobs_user_idx" ON "scan_jobs" USING btree ("user_id","created_at");--> statement-breakpoint
CREATE INDEX "scan_jobs_status_idx" ON "scan_jobs" USING btree ("status");--> statement-breakpoint
CREATE INDEX "food_memories_household_idx" ON "food_memories" USING btree ("household_id","occurred_at");--> statement-breakpoint
CREATE INDEX "food_memories_holiday_idx" ON "food_memories" USING btree ("holiday_tag");--> statement-breakpoint
CREATE INDEX "memory_items_user_idx" ON "memory_items" USING btree ("user_id","kind");--> statement-breakpoint
CREATE INDEX "memory_items_household_idx" ON "memory_items" USING btree ("household_id","kind");--> statement-breakpoint
CREATE INDEX "memory_items_key_idx" ON "memory_items" USING btree ("key");--> statement-breakpoint
CREATE INDEX "taste_signals_user_idx" ON "taste_signals" USING btree ("user_id","axis");--> statement-breakpoint
CREATE UNIQUE INDEX "season_events_slug_market_unique" ON "season_events" USING btree ("slug","market");--> statement-breakpoint
CREATE UNIQUE INDEX "ai_usage_user_month_unique" ON "ai_usage_counters" USING btree ("user_id","month");--> statement-breakpoint
CREATE INDEX "store_notifications_pending_idx" ON "store_notifications" USING btree ("processed","created_at");--> statement-breakpoint
CREATE UNIQUE INDEX "store_transactions_unique" ON "store_transactions" USING btree ("provider","transaction_id");--> statement-breakpoint
CREATE INDEX "subscription_events_sub_idx" ON "subscription_events" USING btree ("subscription_id","created_at");--> statement-breakpoint
CREATE INDEX "subscriptions_user_idx" ON "subscriptions" USING btree ("user_id");--> statement-breakpoint
CREATE UNIQUE INDEX "subscriptions_original_tx_unique" ON "subscriptions" USING btree ("provider","original_transaction_id") WHERE "subscriptions"."original_transaction_id" IS NOT NULL;--> statement-breakpoint
CREATE INDEX "ai_eval_runs_task_idx" ON "ai_eval_runs" USING btree ("task_type","created_at");--> statement-breakpoint
CREATE INDEX "audit_logs_actor_idx" ON "audit_logs" USING btree ("actor_user_id","created_at");--> statement-breakpoint
CREATE INDEX "audit_logs_action_idx" ON "audit_logs" USING btree ("action","created_at");--> statement-breakpoint
CREATE INDEX "domain_events_unpublished_idx" ON "domain_events" USING btree ("published_at","occurred_at");--> statement-breakpoint
CREATE INDEX "domain_events_type_idx" ON "domain_events" USING btree ("type","occurred_at");--> statement-breakpoint
CREATE INDEX "domain_events_household_idx" ON "domain_events" USING btree ("household_id","occurred_at");--> statement-breakpoint
CREATE INDEX "notifications_user_idx" ON "notifications" USING btree ("user_id","created_at");