CREATE TABLE "abuse_events" ( "id" text PRIMARY KEY NOT NULL, "organization_id" text, "project_id" text, "request_id" text, "kind" text NOT NULL, "severity" text DEFAULT 'low' NOT NULL, "detail" text, "resolved" boolean DEFAULT false NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> 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 with time zone, "refresh_token_expires_at" timestamp with time zone, "scope" text, "password" 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 "api_keys" ( "id" text PRIMARY KEY NOT NULL, "organization_id" text NOT NULL, "project_id" text NOT NULL, "created_by_user_id" text, "name" text NOT NULL, "key_hash" text NOT NULL, "key_prefix" text NOT NULL, "last4" text NOT NULL, "mode" text DEFAULT 'live' NOT NULL, "scopes" jsonb DEFAULT '["fetch:execute","sessions:write","usage:read"]'::jsonb NOT NULL, "expires_at" timestamp with time zone, "last_used_at" timestamp with time zone, "revoked_at" timestamp with time zone, "rotated_from_id" text, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "audit_logs" ( "id" text PRIMARY KEY NOT NULL, "organization_id" text, "user_id" text, "action" text NOT NULL, "target" text, "metadata" jsonb, "ip_address" text, "user_agent" text, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "billing_events" ( "id" text PRIMARY KEY NOT NULL, "organization_id" text, "type" text NOT NULL, "stripe_event_id" text, "payload" jsonb, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "domain_profiles" ( "domain" text PRIMARY KEY NOT NULL, "preferred_network" text, "preferred_provider" text, "requests" integer DEFAULT 0 NOT NULL, "successes" integer DEFAULT 0 NOT NULL, "blocks" integer DEFAULT 0 NOT NULL, "captchas" integer DEFAULT 0 NOT NULL, "browser_required" integer DEFAULT 0 NOT NULL, "avg_latency_ms" double precision DEFAULT 0 NOT NULL, "route_stats" jsonb DEFAULT '{}'::jsonb NOT NULL, "policy" jsonb, "last_seen_at" timestamp with time zone DEFAULT now() NOT NULL, "updated_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "feature_flags" ( "key" text PRIMARY KEY NOT NULL, "enabled" boolean DEFAULT false NOT NULL, "description" text, "plans" jsonb, "organization_ids" jsonb, "updated_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "fetch_requests" ( "id" text PRIMARY KEY NOT NULL, "organization_id" text NOT NULL, "project_id" text NOT NULL, "api_key_id" text, "source" text DEFAULT 'api' NOT NULL, "url" text NOT NULL, "final_url" text, "domain" text NOT NULL, "method" text DEFAULT 'GET' NOT NULL, "requested_network" text DEFAULT 'auto' NOT NULL, "network" text, "country" text, "region" text, "city" text, "session_id" text, "browser" boolean DEFAULT false NOT NULL, "format" text DEFAULT 'html' NOT NULL, "status" text DEFAULT 'pending' NOT NULL, "http_status" integer, "error_code" text, "error_message" text, "attempts" integer DEFAULT 0 NOT NULL, "latency_ms" integer, "bytes_in" bigint DEFAULT 0 NOT NULL, "bytes_out" bigint DEFAULT 0 NOT NULL, "cost_usd" double precision DEFAULT 0 NOT NULL, "price_usd" double precision DEFAULT 0 NOT NULL, "cached" boolean DEFAULT false NOT NULL, "request_headers" jsonb, "response_headers" jsonb, "timing" jsonb, "client_ip" text, "user_agent" text, "created_at" timestamp with time zone DEFAULT now() NOT NULL, "completed_at" timestamp with time zone ); --> statement-breakpoint CREATE TABLE "legal_acceptances" ( "id" text PRIMARY KEY NOT NULL, "user_id" text NOT NULL, "document" text NOT NULL, "version" text NOT NULL, "ip_address" text, "accepted_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "organization_members" ( "organization_id" text NOT NULL, "user_id" text NOT NULL, "role" text DEFAULT 'owner' NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL, CONSTRAINT "organization_members_organization_id_user_id_pk" PRIMARY KEY("organization_id","user_id") ); --> statement-breakpoint CREATE TABLE "organizations" ( "id" text PRIMARY KEY NOT NULL, "name" text NOT NULL, "slug" text NOT NULL, "plan" text DEFAULT 'free' NOT NULL, "owner_user_id" text NOT NULL, "provider_visibility" boolean DEFAULT false NOT NULL, "soft_limit_usd" double precision, "hard_limit_usd" double precision, "stripe_customer_id" text, "suspended" boolean DEFAULT false 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 "projects" ( "id" text PRIMARY KEY NOT NULL, "organization_id" text NOT NULL, "name" text NOT NULL, "slug" text NOT NULL, "description" text, "environment" text DEFAULT 'production' NOT NULL, "default_country" text, "default_network" text DEFAULT 'auto' NOT NULL, "log_level" text DEFAULT 'metadata' NOT NULL, "soft_limit_usd" double precision, "hard_limit_usd" double precision, "monthly_request_limit" integer, "archived_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 "provider_configs" ( "id" text PRIMARY KEY NOT NULL, "label" text NOT NULL, "enabled" boolean DEFAULT true NOT NULL, "networks" jsonb DEFAULT '["residential"]'::jsonb NOT NULL, "price_per_gb_usd" jsonb DEFAULT '{}'::jsonb NOT NULL, "weight" double precision DEFAULT 1 NOT NULL, "max_concurrency" integer DEFAULT 200 NOT NULL, "notes" text, "updated_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "provider_health" ( "id" text PRIMARY KEY NOT NULL, "provider" text NOT NULL, "network" text NOT NULL, "status" text NOT NULL, "latency_ms" integer, "success_rate" double precision, "detail" text, "checked_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "proxy_sessions" ( "id" text PRIMARY KEY NOT NULL, "organization_id" text NOT NULL, "project_id" text NOT NULL, "label" text, "provider" text NOT NULL, "network" text NOT NULL, "country" text, "region" text, "city" text, "sticky_key" text NOT NULL, "cookies" jsonb DEFAULT '[]'::jsonb NOT NULL, "status" text DEFAULT 'active' NOT NULL, "request_count" integer DEFAULT 0 NOT NULL, "last_used_at" timestamp with time zone, "expires_at" timestamp with time zone NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "request_attempts" ( "id" text PRIMARY KEY NOT NULL, "request_id" text NOT NULL, "attempt_no" integer NOT NULL, "provider" text NOT NULL, "network" text NOT NULL, "country" text, "session_key" text, "outcome" text NOT NULL, "http_status" integer, "error_code" text, "error_detail" text, "block_reason" text, "duration_ms" integer DEFAULT 0 NOT NULL, "bytes_in" bigint DEFAULT 0 NOT NULL, "bytes_out" bigint DEFAULT 0 NOT NULL, "unit_price_per_gb" double precision DEFAULT 0 NOT NULL, "cost_usd" double precision DEFAULT 0 NOT NULL, "routing_score" double precision, "timing" jsonb, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "routing_metrics" ( "id" text PRIMARY KEY NOT NULL, "bucket" timestamp with time zone NOT NULL, "provider" text NOT NULL, "network" text NOT NULL, "country" text, "requests" integer DEFAULT 0 NOT NULL, "successes" integer DEFAULT 0 NOT NULL, "blocked" integer DEFAULT 0 NOT NULL, "errors" integer DEFAULT 0 NOT NULL, "latency_sum_ms" bigint DEFAULT 0 NOT NULL, "bytes" bigint DEFAULT 0 NOT NULL, "cost_usd" double precision DEFAULT 0 NOT NULL ); --> statement-breakpoint CREATE TABLE "sessions" ( "id" text PRIMARY KEY NOT NULL, "expires_at" timestamp with time zone NOT NULL, "token" text NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL, "updated_at" timestamp with time zone DEFAULT now() NOT NULL, "ip_address" text, "user_agent" text, "user_id" text NOT NULL ); --> statement-breakpoint CREATE TABLE "status_incidents" ( "id" text PRIMARY KEY NOT NULL, "component" text NOT NULL, "title" text NOT NULL, "body" text, "severity" text DEFAULT 'minor' NOT NULL, "started_at" timestamp with time zone DEFAULT now() NOT NULL, "resolved_at" timestamp with time zone ); --> statement-breakpoint CREATE TABLE "subscriptions" ( "id" text PRIMARY KEY NOT NULL, "organization_id" text NOT NULL, "plan" text NOT NULL, "status" text DEFAULT 'active' NOT NULL, "stripe_subscription_id" text, "current_period_start" timestamp with time zone, "current_period_end" timestamp with time zone, "cancel_at_period_end" boolean DEFAULT false 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 "usage_events" ( "id" text PRIMARY KEY NOT NULL, "organization_id" text NOT NULL, "project_id" text, "request_id" text, "metric" text NOT NULL, "quantity" double precision NOT NULL, "unit" text NOT NULL, "cost_usd" double precision DEFAULT 0 NOT NULL, "upstream_cost_usd" double precision DEFAULT 0 NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "users" ( "id" text PRIMARY KEY NOT NULL, "name" text DEFAULT '' NOT NULL, "email" text NOT NULL, "email_verified" boolean DEFAULT false NOT NULL, "image" text, "role" text DEFAULT 'user' NOT NULL, "banned" boolean DEFAULT false NOT NULL, "ban_reason" text, "onboarding_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 "verifications" ( "id" text PRIMARY KEY NOT NULL, "identifier" text NOT NULL, "value" text NOT NULL, "expires_at" timestamp with time zone 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 "webhook_deliveries" ( "id" text PRIMARY KEY NOT NULL, "webhook_id" text NOT NULL, "event" text NOT NULL, "payload" jsonb NOT NULL, "status" text DEFAULT 'pending' NOT NULL, "response_status" integer, "attempts" integer DEFAULT 0 NOT NULL, "next_attempt_at" timestamp with time zone, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "webhooks" ( "id" text PRIMARY KEY NOT NULL, "organization_id" text NOT NULL, "project_id" text, "url" text NOT NULL, "secret" text NOT NULL, "events" jsonb DEFAULT '[]'::jsonb NOT NULL, "enabled" boolean DEFAULT true NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint ALTER TABLE "abuse_events" ADD CONSTRAINT "abuse_events_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> 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_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "api_keys" ADD CONSTRAINT "api_keys_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "api_keys" ADD CONSTRAINT "api_keys_created_by_user_id_users_id_fk" FOREIGN KEY ("created_by_user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("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 "billing_events" ADD CONSTRAINT "billing_events_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "fetch_requests" ADD CONSTRAINT "fetch_requests_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "fetch_requests" ADD CONSTRAINT "fetch_requests_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "fetch_requests" ADD CONSTRAINT "fetch_requests_api_key_id_api_keys_id_fk" FOREIGN KEY ("api_key_id") REFERENCES "public"."api_keys"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "legal_acceptances" ADD CONSTRAINT "legal_acceptances_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "organization_members" ADD CONSTRAINT "organization_members_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "organization_members" ADD CONSTRAINT "organization_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 "organizations" ADD CONSTRAINT "organizations_owner_user_id_users_id_fk" FOREIGN KEY ("owner_user_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint ALTER TABLE "projects" ADD CONSTRAINT "projects_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "proxy_sessions" ADD CONSTRAINT "proxy_sessions_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "proxy_sessions" ADD CONSTRAINT "proxy_sessions_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "request_attempts" ADD CONSTRAINT "request_attempts_request_id_fetch_requests_id_fk" FOREIGN KEY ("request_id") REFERENCES "public"."fetch_requests"("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 "subscriptions" ADD CONSTRAINT "subscriptions_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "usage_events" ADD CONSTRAINT "usage_events_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "usage_events" ADD CONSTRAINT "usage_events_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "webhook_deliveries" ADD CONSTRAINT "webhook_deliveries_webhook_id_webhooks_id_fk" FOREIGN KEY ("webhook_id") REFERENCES "public"."webhooks"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "webhooks" ADD CONSTRAINT "webhooks_organization_id_organizations_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "webhooks" ADD CONSTRAINT "webhooks_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint CREATE INDEX "abuse_events_org_idx" ON "abuse_events" USING btree ("organization_id");--> statement-breakpoint CREATE INDEX "accounts_user_idx" ON "accounts" USING btree ("user_id");--> statement-breakpoint CREATE UNIQUE INDEX "api_keys_hash_uq" ON "api_keys" USING btree ("key_hash");--> statement-breakpoint CREATE INDEX "api_keys_project_idx" ON "api_keys" USING btree ("project_id");--> statement-breakpoint CREATE INDEX "api_keys_org_idx" ON "api_keys" USING btree ("organization_id");--> statement-breakpoint CREATE INDEX "audit_logs_org_created_idx" ON "audit_logs" USING btree ("organization_id","created_at");--> statement-breakpoint CREATE INDEX "audit_logs_user_idx" ON "audit_logs" USING btree ("user_id");--> statement-breakpoint CREATE INDEX "billing_events_org_idx" ON "billing_events" USING btree ("organization_id");--> statement-breakpoint CREATE INDEX "fetch_requests_project_created_idx" ON "fetch_requests" USING btree ("project_id","created_at");--> statement-breakpoint CREATE INDEX "fetch_requests_org_created_idx" ON "fetch_requests" USING btree ("organization_id","created_at");--> statement-breakpoint CREATE INDEX "fetch_requests_domain_idx" ON "fetch_requests" USING btree ("domain");--> statement-breakpoint CREATE INDEX "fetch_requests_created_idx" ON "fetch_requests" USING btree ("created_at");--> statement-breakpoint CREATE INDEX "legal_acceptances_user_idx" ON "legal_acceptances" USING btree ("user_id");--> statement-breakpoint CREATE INDEX "org_members_user_idx" ON "organization_members" USING btree ("user_id");--> statement-breakpoint CREATE UNIQUE INDEX "organizations_slug_uq" ON "organizations" USING btree ("slug");--> statement-breakpoint CREATE INDEX "organizations_owner_idx" ON "organizations" USING btree ("owner_user_id");--> statement-breakpoint CREATE UNIQUE INDEX "projects_org_slug_uq" ON "projects" USING btree ("organization_id","slug");--> statement-breakpoint CREATE INDEX "projects_org_idx" ON "projects" USING btree ("organization_id");--> statement-breakpoint CREATE INDEX "provider_health_provider_checked_idx" ON "provider_health" USING btree ("provider","checked_at");--> statement-breakpoint CREATE INDEX "proxy_sessions_project_idx" ON "proxy_sessions" USING btree ("project_id");--> statement-breakpoint CREATE INDEX "proxy_sessions_expires_idx" ON "proxy_sessions" USING btree ("expires_at");--> statement-breakpoint CREATE INDEX "request_attempts_request_idx" ON "request_attempts" USING btree ("request_id");--> statement-breakpoint CREATE INDEX "request_attempts_provider_created_idx" ON "request_attempts" USING btree ("provider","created_at");--> statement-breakpoint CREATE UNIQUE INDEX "routing_metrics_bucket_uq" ON "routing_metrics" USING btree ("bucket","provider","network","country");--> statement-breakpoint CREATE UNIQUE INDEX "sessions_token_uq" ON "sessions" USING btree ("token");--> statement-breakpoint CREATE INDEX "sessions_user_idx" ON "sessions" USING btree ("user_id");--> statement-breakpoint CREATE INDEX "usage_events_org_created_idx" ON "usage_events" USING btree ("organization_id","created_at");--> statement-breakpoint CREATE INDEX "usage_events_project_created_idx" ON "usage_events" USING btree ("project_id","created_at");--> statement-breakpoint CREATE UNIQUE INDEX "users_email_uq" ON "users" USING btree ("email");--> statement-breakpoint CREATE INDEX "verifications_identifier_idx" ON "verifications" USING btree ("identifier");--> statement-breakpoint CREATE INDEX "webhook_deliveries_webhook_idx" ON "webhook_deliveries" USING btree ("webhook_id");