CREATE TYPE "public"."inventory_status" AS ENUM('ACTIVE', 'SOLD', 'ARCHIVED');--> statement-breakpoint CREATE TYPE "public"."listing_status" AS ENUM('DRAFT', 'AVAILABLE', 'PENDING', 'CLOSED', 'ARCHIVED');--> statement-breakpoint CREATE TYPE "public"."user_role" AS ENUM('ADMIN');--> statement-breakpoint CREATE TABLE "categories" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "name" text NOT NULL, "slug" text NOT NULL, "active" boolean DEFAULT true NOT NULL, "sort" integer DEFAULT 0 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 "condition_profiles" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "category_id" uuid NOT NULL, "name" text NOT NULL, "active" boolean DEFAULT true NOT NULL, "sort" integer DEFAULT 0 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 "conditions" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "condition_profile_id" uuid NOT NULL, "name" text NOT NULL, "code" text NOT NULL, "quality_rank" integer NOT NULL, "description" text, "active" boolean DEFAULT true NOT NULL, "sort" integer DEFAULT 0 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 "image_derivative_jobs" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "inventory_image_id" uuid NOT NULL, "source_key" text NOT NULL, "status" text DEFAULT 'PENDING' NOT NULL, "derivatives" jsonb DEFAULT '[]'::jsonb NOT NULL, "error" 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_images" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "inventory_item_id" uuid NOT NULL, "storage_key" text NOT NULL, "original_filename" text NOT NULL, "mime_type" text NOT NULL, "file_size" integer NOT NULL, "width" integer NOT NULL, "height" integer NOT NULL, "alt_text" text, "sort_order" integer DEFAULT 0 NOT NULL, "is_primary" boolean DEFAULT false NOT NULL, "processing_status" text DEFAULT 'PENDING' 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 "inventory_items" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "product_id" uuid NOT NULL, "condition_id" uuid NOT NULL, "status" "inventory_status" DEFAULT 'ACTIVE' 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 "listings" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "inventory_item_id" uuid NOT NULL, "product_name" text NOT NULL, "category_id" uuid NOT NULL, "condition_id" uuid NOT NULL, "asking_price_minor" integer NOT NULL, "status" "listing_status" DEFAULT 'DRAFT' 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 "mfa_methods" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "user_id" uuid NOT NULL, "type" text NOT NULL, "secret_ciphertext" text NOT NULL, "name" text NOT NULL, "is_enabled" boolean DEFAULT false NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL, "last_used_at" timestamp with time zone, "disabled_at" timestamp with time zone ); --> 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 "products" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "seller_id" uuid NOT NULL, "category_id" uuid NOT NULL, "name" text NOT NULL, "slug" text NOT NULL, "description" text, "brand" text, "set_name" text, "card_number" text, "event_name" text, "release_year" integer, "created_at" timestamp with time zone DEFAULT now() NOT NULL, "updated_at" timestamp with time zone DEFAULT now() NOT NULL, CONSTRAINT "products_release_year_valid" CHECK ("products"."release_year" IS NULL OR "products"."release_year" BETWEEN 1996 AND 9999) ); --> statement-breakpoint CREATE TABLE "security_audit_events" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "user_id" uuid, "event" text NOT NULL, "ip_address" text, "user_agent" text, "metadata" jsonb DEFAULT '{}'::jsonb NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "sellers" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "user_id" uuid NOT NULL, "display_name" 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 "sessions" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "user_id" uuid NOT NULL, "session_token_hash" text NOT NULL, "csrf_token_hash" text NOT NULL, "expires_at" timestamp with time zone NOT NULL, "last_activity_at" timestamp with time zone DEFAULT now() NOT NULL, "ip_address" text, "user_agent" text, "revoked_at" timestamp with time zone, "created_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, "password_hash" text NOT NULL, "role" "user_role" DEFAULT 'ADMIN' NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL, "updated_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint ALTER TABLE "condition_profiles" ADD CONSTRAINT "condition_profiles_category_id_categories_id_fk" FOREIGN KEY ("category_id") REFERENCES "public"."categories"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint ALTER TABLE "conditions" ADD CONSTRAINT "conditions_condition_profile_id_condition_profiles_id_fk" FOREIGN KEY ("condition_profile_id") REFERENCES "public"."condition_profiles"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint ALTER TABLE "image_derivative_jobs" ADD CONSTRAINT "image_derivative_jobs_inventory_image_id_inventory_images_id_fk" FOREIGN KEY ("inventory_image_id") REFERENCES "public"."inventory_images"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint ALTER TABLE "inventory_images" ADD CONSTRAINT "inventory_images_inventory_item_id_inventory_items_id_fk" FOREIGN KEY ("inventory_item_id") REFERENCES "public"."inventory_items"("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_condition_id_conditions_id_fk" FOREIGN KEY ("condition_id") REFERENCES "public"."conditions"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint ALTER TABLE "listings" ADD CONSTRAINT "listings_inventory_item_id_inventory_items_id_fk" FOREIGN KEY ("inventory_item_id") REFERENCES "public"."inventory_items"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint ALTER TABLE "listings" ADD CONSTRAINT "listings_condition_id_conditions_id_fk" FOREIGN KEY ("condition_id") REFERENCES "public"."conditions"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint ALTER TABLE "mfa_methods" ADD CONSTRAINT "mfa_methods_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action 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 no action ON UPDATE no action;--> statement-breakpoint ALTER TABLE "products" ADD CONSTRAINT "products_seller_id_sellers_id_fk" FOREIGN KEY ("seller_id") REFERENCES "public"."sellers"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint ALTER TABLE "products" ADD CONSTRAINT "products_category_id_categories_id_fk" FOREIGN KEY ("category_id") REFERENCES "public"."categories"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint ALTER TABLE "security_audit_events" ADD CONSTRAINT "security_audit_events_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint ALTER TABLE "sellers" ADD CONSTRAINT "sellers_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action 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 no action ON UPDATE no action;--> statement-breakpoint CREATE UNIQUE INDEX "categories_name_unique" ON "categories" USING btree ("name");--> statement-breakpoint CREATE UNIQUE INDEX "categories_slug_unique" ON "categories" USING btree ("slug");--> statement-breakpoint CREATE UNIQUE INDEX "conditions_profile_code_unique" ON "conditions" USING btree ("condition_profile_id","code");--> statement-breakpoint CREATE INDEX "image_derivative_jobs_image_id_index" ON "image_derivative_jobs" USING btree ("inventory_image_id");--> statement-breakpoint CREATE INDEX "inventory_images_inventory_item_id_index" ON "inventory_images" USING btree ("inventory_item_id");--> statement-breakpoint CREATE INDEX "listings_inventory_item_id_index" ON "listings" USING btree ("inventory_item_id");--> statement-breakpoint CREATE INDEX "listings_status_index" ON "listings" USING btree ("status");--> statement-breakpoint CREATE INDEX "mfa_methods_user_id_index" ON "mfa_methods" USING btree ("user_id");--> statement-breakpoint CREATE UNIQUE INDEX "password_reset_tokens_token_hash_unique" ON "password_reset_tokens" USING btree ("token_hash");--> statement-breakpoint CREATE INDEX "password_reset_tokens_user_id_index" ON "password_reset_tokens" USING btree ("user_id");--> statement-breakpoint CREATE UNIQUE INDEX "products_seller_slug_unique" ON "products" USING btree ("seller_id","slug");--> statement-breakpoint CREATE INDEX "security_audit_events_user_id_index" ON "security_audit_events" USING btree ("user_id");--> statement-breakpoint CREATE INDEX "security_audit_events_event_created_at_index" ON "security_audit_events" USING btree ("event","created_at");--> statement-breakpoint CREATE UNIQUE INDEX "sellers_user_id_unique" ON "sellers" USING btree ("user_id");--> statement-breakpoint CREATE UNIQUE INDEX "sessions_token_hash_unique" ON "sessions" USING btree ("session_token_hash");--> statement-breakpoint CREATE INDEX "sessions_user_id_index" ON "sessions" USING btree ("user_id");--> statement-breakpoint CREATE INDEX "sessions_expires_at_index" ON "sessions" USING btree ("expires_at");--> statement-breakpoint CREATE UNIQUE INDEX "users_email_unique" ON "users" USING btree ("email");