CREATE EXTENSION IF NOT EXISTS vector;--> statement-breakpoint CREATE TYPE "public"."application_effort_estimate" AS ENUM('loi_only', 'short_form', 'full_federal', 'unknown');--> statement-breakpoint CREATE TYPE "public"."contact_priority" AS ENUM('named', 'generic');--> statement-breakpoint CREATE TYPE "public"."contact_source_provider" AS ENUM('apollo', 'irs_990', 'website', 'manual');--> statement-breakpoint CREATE TYPE "public"."email_status" AS ENUM('unverified', 'valid', 'risky', 'invalid');--> statement-breakpoint CREATE TYPE "public"."grant_source" AS ENUM('grants_gov', 'nh_state', 'irs_990pf', 'pnd_rss', 'candid', 'manual');--> statement-breakpoint CREATE TYPE "public"."grant_status" AS ENUM('open', 'expired', 'closed');--> statement-breakpoint CREATE TYPE "public"."icp_band" AS ENUM('below', 'primary', 'above', 'unknown');--> statement-breakpoint CREATE TYPE "public"."match_reject_reason" AS ENUM('wrong_eligibility', 'wrong_geography', 'bad_capacity_fit', 'weak_mission_fit', 'stale_deadline', 'bad_contact', 'other');--> statement-breakpoint CREATE TYPE "public"."match_review_status" AS ENUM('pending', 'approved', 'rejected', 'edited');--> statement-breakpoint CREATE TYPE "public"."pipeline_event_type" AS ENUM('enrolled', 'sent', 'opened', 'replied', 'bounced', 'unsubscribed', 'brief_requested', 'brief_sent', 'demo_booked', 'demo_held', 'pilot_started', 'converted');--> statement-breakpoint CREATE TYPE "public"."registration_status" AS ENUM('good_standing', 'lapsed', 'unknown');--> statement-breakpoint CREATE TABLE "contacts" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "org_id" uuid NOT NULL, "full_name" text, "title" text, "email" text, "email_status" "email_status" DEFAULT 'unverified' NOT NULL, "source_provider" "contact_source_provider", "priority" "contact_priority" DEFAULT 'generic' NOT NULL, "created_at" timestamp with time zone DEFAULT now() ); --> statement-breakpoint CREATE TABLE "grants" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "funder" text NOT NULL, "title" text NOT NULL, "synopsis" text, "eligibility_entity_types" text[], "geographic_scope" text, "program_areas" text[], "award_floor" integer, "award_ceiling" integer, "expected_awards_count" integer, "open_date" timestamp with time zone, "close_date" timestamp with time zone, "match_requirement" boolean DEFAULT false NOT NULL, "application_effort_estimate" "application_effort_estimate" DEFAULT 'unknown' NOT NULL, "application_form_supported" boolean DEFAULT false NOT NULL, "source_url" text NOT NULL, "source" "grant_source" NOT NULL, "status" "grant_status" DEFAULT 'open' NOT NULL, "synopsis_embedding" vector(1536), "last_verified_at" timestamp with time zone, "created_at" timestamp with time zone DEFAULT now(), "updated_at" timestamp with time zone DEFAULT now() ); --> statement-breakpoint CREATE TABLE "matches" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "org_id" uuid NOT NULL, "grant_id" uuid NOT NULL, "total_score" integer NOT NULL, "subscores" jsonb, "hard_gates_passed" boolean DEFAULT false NOT NULL, "easy_win" boolean DEFAULT false NOT NULL, "rationale" jsonb, "review_status" "match_review_status" DEFAULT 'pending' NOT NULL, "reject_reason" "match_reject_reason", "is_hero" boolean DEFAULT false NOT NULL, "created_at" timestamp with time zone DEFAULT now(), "updated_at" timestamp with time zone DEFAULT now() ); --> statement-breakpoint CREATE TABLE "org_profiles" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "org_id" uuid NOT NULL, "mission_statement" text, "programs" jsonb, "service_geography" text, "recent_news" jsonb, "known_funders" jsonb, "staff" jsonb, "budget_band" text, "sources" jsonb, "confidence" real, "profile_embedding" vector(1536), "created_at" timestamp with time zone DEFAULT now() ); --> statement-breakpoint CREATE TABLE "orgs" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "name" text NOT NULL, "city" text, "state" text DEFAULT 'NH' NOT NULL, "ein" text, "ntee_code" text, "total_revenue" integer, "fiscal_year_end" text, "registration_status" "registration_status" DEFAULT 'unknown' NOT NULL, "icp_band" "icp_band" DEFAULT 'unknown' NOT NULL, "source_registry" text, "created_at" timestamp with time zone DEFAULT now(), "updated_at" timestamp with time zone DEFAULT now() ); --> statement-breakpoint CREATE TABLE "pipeline_events" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "org_id" uuid, "contact_id" uuid, "match_id" uuid, "event_type" "pipeline_event_type" NOT NULL, "payload" jsonb, "occurred_at" timestamp with time zone DEFAULT now() NOT NULL, "created_at" timestamp with time zone DEFAULT now() ); --> statement-breakpoint ALTER TABLE "contacts" ADD CONSTRAINT "contacts_org_id_orgs_id_fk" FOREIGN KEY ("org_id") REFERENCES "public"."orgs"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "matches" ADD CONSTRAINT "matches_org_id_orgs_id_fk" FOREIGN KEY ("org_id") REFERENCES "public"."orgs"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "matches" ADD CONSTRAINT "matches_grant_id_grants_id_fk" FOREIGN KEY ("grant_id") REFERENCES "public"."grants"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "org_profiles" ADD CONSTRAINT "org_profiles_org_id_orgs_id_fk" FOREIGN KEY ("org_id") REFERENCES "public"."orgs"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "pipeline_events" ADD CONSTRAINT "pipeline_events_org_id_orgs_id_fk" FOREIGN KEY ("org_id") REFERENCES "public"."orgs"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "pipeline_events" ADD CONSTRAINT "pipeline_events_contact_id_contacts_id_fk" FOREIGN KEY ("contact_id") REFERENCES "public"."contacts"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint ALTER TABLE "pipeline_events" ADD CONSTRAINT "pipeline_events_match_id_matches_id_fk" FOREIGN KEY ("match_id") REFERENCES "public"."matches"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint CREATE INDEX "idx_contacts_org" ON "contacts" USING btree ("org_id");--> statement-breakpoint CREATE INDEX "idx_contacts_email" ON "contacts" USING btree ("email");--> statement-breakpoint CREATE UNIQUE INDEX "idx_grants_source_url" ON "grants" USING btree ("source_url");--> statement-breakpoint CREATE INDEX "idx_grants_status" ON "grants" USING btree ("status");--> statement-breakpoint CREATE INDEX "idx_grants_close_date" ON "grants" USING btree ("close_date");--> statement-breakpoint CREATE INDEX "idx_grants_source" ON "grants" USING btree ("source");--> statement-breakpoint CREATE INDEX "grants_synopsis_embedding_idx" ON "grants" USING hnsw ("synopsis_embedding" vector_cosine_ops);--> statement-breakpoint CREATE INDEX "idx_matches_org" ON "matches" USING btree ("org_id");--> statement-breakpoint CREATE INDEX "idx_matches_grant" ON "matches" USING btree ("grant_id");--> statement-breakpoint CREATE INDEX "idx_matches_review_status" ON "matches" USING btree ("review_status");--> statement-breakpoint CREATE INDEX "idx_org_profiles_org" ON "org_profiles" USING btree ("org_id");--> statement-breakpoint CREATE INDEX "org_profiles_embedding_idx" ON "org_profiles" USING hnsw ("profile_embedding" vector_cosine_ops);--> statement-breakpoint CREATE UNIQUE INDEX "idx_orgs_ein" ON "orgs" USING btree ("ein") WHERE "orgs"."ein" IS NOT NULL;--> statement-breakpoint CREATE INDEX "idx_orgs_icp_band" ON "orgs" USING btree ("icp_band");--> statement-breakpoint CREATE INDEX "idx_orgs_state" ON "orgs" USING btree ("state");--> statement-breakpoint CREATE INDEX "idx_pipeline_events_org" ON "pipeline_events" USING btree ("org_id");--> statement-breakpoint CREATE INDEX "idx_pipeline_events_contact" ON "pipeline_events" USING btree ("contact_id");--> statement-breakpoint CREATE INDEX "idx_pipeline_events_match" ON "pipeline_events" USING btree ("match_id");--> statement-breakpoint CREATE INDEX "idx_pipeline_events_type_occurred" ON "pipeline_events" USING btree ("event_type","occurred_at");