M0: foundation — monorepo, PostGIS schema, deck query, app shell

Greenfield scaffold for Linkder, a swipe-to-hire marketplace for local
professional services.

- pnpm/turbo monorepo: apps/web, packages/{shared,db}
- Postgres 16 + PostGIS via docker compose (ports 5442/6389 to avoid
  clashing with other local stacks)
- Drizzle schema, 23 tables, geography(Point,4326) with GiST indexes
- Domain core in packages/shared: integer-cent money, status transition
  graphs, deck ranking weights, cancellation policy — 46 unit tests
- Deck query: filtering in Postgres on the GiST index, ranking in JS so
  the weights stay tunable — 18 integration tests against a seeded DB
- Deterministic seed placing pros at known distances, including three
  that must NOT appear on a deck (out of radius, unverified, away)
- Next.js 15 app shell with a working swipe deck
- CI: typecheck, lint, test, build against live postgres+redis

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
serfowi
2026-08-20 13:32:35 -04:00
co-authored by Claude Opus 5
commit 19623bcccb
66 changed files with 12412 additions and 0 deletions
@@ -0,0 +1,353 @@
CREATE TYPE "public"."booking_status" AS ENUM('scheduled', 'in_progress', 'awaiting_confirmation', 'completed', 'cancelled', 'disputed');--> statement-breakpoint
CREATE TYPE "public"."credential_kind" AS ENUM('id', 'licence', 'insurance');--> statement-breakpoint
CREATE TYPE "public"."job_status" AS ENUM('open', 'matched', 'booked', 'completed', 'cancelled');--> statement-breakpoint
CREATE TYPE "public"."media_kind" AS ENUM('photo', 'work_sample');--> statement-breakpoint
CREATE TYPE "public"."payment_status" AS ENUM('pending', 'held', 'released', 'refunded', 'partially_refunded', 'failed');--> statement-breakpoint
CREATE TYPE "public"."quote_kind" AS ENUM('fixed', 'hourly');--> statement-breakpoint
CREATE TYPE "public"."quote_status" AS ENUM('sent', 'accepted', 'declined', 'withdrawn', 'expired');--> statement-breakpoint
CREATE TYPE "public"."request_status" AS ENUM('pending', 'accepted', 'declined', 'expired');--> statement-breakpoint
CREATE TYPE "public"."review_status" AS ENUM('pending', 'approved', 'rejected');--> statement-breakpoint
CREATE TYPE "public"."swipe_direction" AS ENUM('left', 'right');--> statement-breakpoint
CREATE TYPE "public"."urgency" AS ENUM('now', 'this_week', 'flexible');--> statement-breakpoint
CREATE TYPE "public"."user_role" AS ENUM('client', 'pro', 'admin');--> statement-breakpoint
CREATE TYPE "public"."verification_status" AS ENUM('draft', 'pending', 'verified', 'rejected', 'suspended');--> statement-breakpoint
CREATE TABLE "accounts" (
"user_id" uuid NOT NULL,
"type" text NOT NULL,
"provider" text NOT NULL,
"provider_account_id" text NOT NULL,
"refresh_token" text,
"access_token" text,
"expires_at" integer,
"token_type" text,
"scope" text,
"id_token" text,
"session_state" text,
CONSTRAINT "accounts_provider_provider_account_id_pk" PRIMARY KEY("provider","provider_account_id")
);
--> statement-breakpoint
CREATE TABLE "phone_otps" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"phone" text NOT NULL,
"code_hash" text NOT NULL,
"attempts" integer DEFAULT 0 NOT NULL,
"consumed" boolean DEFAULT false NOT NULL,
"expires_at" timestamp with time zone NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "sessions" (
"session_token" text PRIMARY KEY NOT NULL,
"user_id" uuid NOT NULL,
"expires" timestamp with time zone NOT NULL
);
--> statement-breakpoint
CREATE TABLE "users" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"name" text,
"email" text,
"email_verified" timestamp with time zone,
"phone" text,
"phone_verified" timestamp with time zone,
"image" text,
"role" "user_role" DEFAULT 'client' NOT NULL,
"banned_at" timestamp with time zone,
"last_active_at" timestamp with time zone DEFAULT now(),
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "users_email_unique" UNIQUE("email"),
CONSTRAINT "users_phone_unique" UNIQUE("phone")
);
--> statement-breakpoint
CREATE TABLE "verification_tokens" (
"identifier" text NOT NULL,
"token" text NOT NULL,
"expires" timestamp with time zone NOT NULL,
CONSTRAINT "verification_tokens_identifier_token_pk" PRIMARY KEY("identifier","token")
);
--> statement-breakpoint
CREATE TABLE "categories" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"slug" text NOT NULL,
"name" text NOT NULL,
"icon" text,
"position" integer DEFAULT 0 NOT NULL,
"is_active" boolean DEFAULT true NOT NULL,
CONSTRAINT "categories_slug_unique" UNIQUE("slug")
);
--> statement-breakpoint
CREATE TABLE "credentials" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"pro_id" uuid NOT NULL,
"kind" "credential_kind" NOT NULL,
"file_url" text NOT NULL,
"issuer" text,
"expires_at" timestamp with time zone,
"review_status" "review_status" DEFAULT 'pending' NOT NULL,
"reviewed_by" uuid,
"reviewed_at" timestamp with time zone,
"review_notes" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "pro_availability" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"pro_id" uuid NOT NULL,
"weekday" integer NOT NULL,
"start_minute" integer NOT NULL,
"end_minute" integer NOT NULL
);
--> statement-breakpoint
CREATE TABLE "pro_categories" (
"pro_id" uuid NOT NULL,
"category_id" uuid NOT NULL,
CONSTRAINT "pro_categories_pro_id_category_id_pk" PRIMARY KEY("pro_id","category_id")
);
--> statement-breakpoint
CREATE TABLE "pro_media" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"pro_id" uuid NOT NULL,
"url" text NOT NULL,
"kind" "media_kind" DEFAULT 'photo' NOT NULL,
"position" integer DEFAULT 0 NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "pro_profiles" (
"user_id" uuid PRIMARY KEY NOT NULL,
"headline" text NOT NULL,
"bio" text NOT NULL,
"hourly_rate_cents" integer NOT NULL,
"years_experience" integer DEFAULT 0 NOT NULL,
"base_location" geography(Point,4326) NOT NULL,
"service_radius_m" integer DEFAULT 15000 NOT NULL,
"verification_status" "verification_status" DEFAULT 'draft' NOT NULL,
"verified_at" timestamp with time zone,
"suspended_reason" text,
"is_accepting_jobs" boolean DEFAULT true NOT NULL,
"rating_avg" numeric(3, 2),
"rating_count" integer DEFAULT 0 NOT NULL,
"completed_jobs" integer DEFAULT 0 NOT NULL,
"response_rate" numeric(4, 3),
"avg_response_minutes" integer,
"stripe_account_id" text,
"stripe_payouts_enabled" 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,
CONSTRAINT "pro_profiles_stripe_account_id_unique" UNIQUE("stripe_account_id")
);
--> statement-breakpoint
CREATE TABLE "verification_sessions" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"pro_id" uuid NOT NULL,
"provider" text DEFAULT 'didit' NOT NULL,
"external_id" text NOT NULL,
"status" text DEFAULT 'pending' NOT NULL,
"decision" text,
"raw_payload" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"completed_at" timestamp with time zone,
CONSTRAINT "verification_sessions_external_id_unique" UNIQUE("external_id")
);
--> statement-breakpoint
CREATE TABLE "jobs" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"client_id" uuid NOT NULL,
"category_id" uuid NOT NULL,
"title" text NOT NULL,
"description" text NOT NULL,
"photos" text[] DEFAULT '{}'::text[] NOT NULL,
"urgency" "urgency" DEFAULT 'flexible' NOT NULL,
"budget_min_cents" integer,
"budget_max_cents" integer,
"location" geography(Point,4326) NOT NULL,
"address_text" text NOT NULL,
"status" "job_status" DEFAULT 'open' 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 "matches" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"request_id" uuid NOT NULL,
"job_id" uuid NOT NULL,
"pro_id" uuid NOT NULL,
"client_id" uuid NOT NULL,
"last_message_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "matches_request_id_unique" UNIQUE("request_id")
);
--> statement-breakpoint
CREATE TABLE "requests" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"job_id" uuid NOT NULL,
"pro_id" uuid NOT NULL,
"status" "request_status" DEFAULT 'pending' NOT NULL,
"expires_at" timestamp with time zone NOT NULL,
"responded_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "requests_job_pro_unique" UNIQUE("job_id","pro_id")
);
--> statement-breakpoint
CREATE TABLE "swipes" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"job_id" uuid NOT NULL,
"pro_id" uuid NOT NULL,
"direction" "swipe_direction" NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "swipes_job_pro_unique" UNIQUE("job_id","pro_id")
);
--> statement-breakpoint
CREATE TABLE "messages" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"match_id" uuid NOT NULL,
"sender_id" uuid NOT NULL,
"body" text NOT NULL,
"attachments" text[] DEFAULT '{}'::text[] NOT NULL,
"read_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "bookings" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"match_id" uuid NOT NULL,
"quote_id" uuid NOT NULL,
"scheduled_start" timestamp with time zone NOT NULL,
"scheduled_end" timestamp with time zone NOT NULL,
"status" "booking_status" DEFAULT 'scheduled' NOT NULL,
"pro_completed_at" timestamp with time zone,
"client_confirmed_at" timestamp with time zone,
"cancelled_at" timestamp with time zone,
"cancelled_by" uuid,
"cancellation_reason" 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 "payments" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"booking_id" uuid NOT NULL,
"stripe_payment_intent_id" text,
"stripe_transfer_id" text,
"stripe_refund_id" text,
"amount_cents" integer NOT NULL,
"platform_fee_cents" integer NOT NULL,
"platform_fee_bps" integer NOT NULL,
"refunded_cents" integer DEFAULT 0 NOT NULL,
"currency" text DEFAULT 'eur' NOT NULL,
"status" "payment_status" DEFAULT 'pending' NOT NULL,
"captured_at" timestamp with time zone,
"released_at" timestamp with time zone,
"failure_reason" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "payments_booking_id_unique" UNIQUE("booking_id"),
CONSTRAINT "payments_stripe_payment_intent_id_unique" UNIQUE("stripe_payment_intent_id"),
CONSTRAINT "payments_stripe_transfer_id_unique" UNIQUE("stripe_transfer_id")
);
--> statement-breakpoint
CREATE TABLE "processed_stripe_events" (
"event_id" text PRIMARY KEY NOT NULL,
"type" text NOT NULL,
"processed_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "quotes" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"match_id" uuid NOT NULL,
"kind" "quote_kind" DEFAULT 'fixed' NOT NULL,
"amount_cents" integer NOT NULL,
"hours_estimate" integer,
"scope" text NOT NULL,
"status" "quote_status" DEFAULT 'sent' NOT NULL,
"valid_until" timestamp with time zone NOT NULL,
"responded_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "reviews" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"booking_id" uuid NOT NULL,
"author_id" uuid NOT NULL,
"subject_id" uuid NOT NULL,
"rating" integer NOT NULL,
"body" text NOT NULL,
"published_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "reviews_booking_author_unique" UNIQUE("booking_id","author_id")
);
--> statement-breakpoint
CREATE TABLE "audit_log" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"actor_id" uuid,
"action" text NOT NULL,
"entity" text NOT NULL,
"entity_id" text,
"metadata" jsonb,
"ip" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
ALTER TABLE "accounts" ADD CONSTRAINT "accounts_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "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 "credentials" ADD CONSTRAINT "credentials_pro_id_pro_profiles_user_id_fk" FOREIGN KEY ("pro_id") REFERENCES "public"."pro_profiles"("user_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "credentials" ADD CONSTRAINT "credentials_reviewed_by_users_id_fk" FOREIGN KEY ("reviewed_by") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "pro_availability" ADD CONSTRAINT "pro_availability_pro_id_pro_profiles_user_id_fk" FOREIGN KEY ("pro_id") REFERENCES "public"."pro_profiles"("user_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "pro_categories" ADD CONSTRAINT "pro_categories_pro_id_pro_profiles_user_id_fk" FOREIGN KEY ("pro_id") REFERENCES "public"."pro_profiles"("user_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "pro_categories" ADD CONSTRAINT "pro_categories_category_id_categories_id_fk" FOREIGN KEY ("category_id") REFERENCES "public"."categories"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "pro_media" ADD CONSTRAINT "pro_media_pro_id_pro_profiles_user_id_fk" FOREIGN KEY ("pro_id") REFERENCES "public"."pro_profiles"("user_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "pro_profiles" ADD CONSTRAINT "pro_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 "verification_sessions" ADD CONSTRAINT "verification_sessions_pro_id_pro_profiles_user_id_fk" FOREIGN KEY ("pro_id") REFERENCES "public"."pro_profiles"("user_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "jobs" ADD CONSTRAINT "jobs_client_id_users_id_fk" FOREIGN KEY ("client_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "jobs" ADD CONSTRAINT "jobs_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 "matches" ADD CONSTRAINT "matches_request_id_requests_id_fk" FOREIGN KEY ("request_id") REFERENCES "public"."requests"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "matches" ADD CONSTRAINT "matches_job_id_jobs_id_fk" FOREIGN KEY ("job_id") REFERENCES "public"."jobs"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "matches" ADD CONSTRAINT "matches_pro_id_pro_profiles_user_id_fk" FOREIGN KEY ("pro_id") REFERENCES "public"."pro_profiles"("user_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "matches" ADD CONSTRAINT "matches_client_id_users_id_fk" FOREIGN KEY ("client_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "requests" ADD CONSTRAINT "requests_job_id_jobs_id_fk" FOREIGN KEY ("job_id") REFERENCES "public"."jobs"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "requests" ADD CONSTRAINT "requests_pro_id_pro_profiles_user_id_fk" FOREIGN KEY ("pro_id") REFERENCES "public"."pro_profiles"("user_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "swipes" ADD CONSTRAINT "swipes_job_id_jobs_id_fk" FOREIGN KEY ("job_id") REFERENCES "public"."jobs"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "swipes" ADD CONSTRAINT "swipes_pro_id_pro_profiles_user_id_fk" FOREIGN KEY ("pro_id") REFERENCES "public"."pro_profiles"("user_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "messages" ADD CONSTRAINT "messages_match_id_matches_id_fk" FOREIGN KEY ("match_id") REFERENCES "public"."matches"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "messages" ADD CONSTRAINT "messages_sender_id_users_id_fk" FOREIGN KEY ("sender_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "bookings" ADD CONSTRAINT "bookings_match_id_matches_id_fk" FOREIGN KEY ("match_id") REFERENCES "public"."matches"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "bookings" ADD CONSTRAINT "bookings_quote_id_quotes_id_fk" FOREIGN KEY ("quote_id") REFERENCES "public"."quotes"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "bookings" ADD CONSTRAINT "bookings_cancelled_by_users_id_fk" FOREIGN KEY ("cancelled_by") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "payments" ADD CONSTRAINT "payments_booking_id_bookings_id_fk" FOREIGN KEY ("booking_id") REFERENCES "public"."bookings"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "quotes" ADD CONSTRAINT "quotes_match_id_matches_id_fk" FOREIGN KEY ("match_id") REFERENCES "public"."matches"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "reviews" ADD CONSTRAINT "reviews_booking_id_bookings_id_fk" FOREIGN KEY ("booking_id") REFERENCES "public"."bookings"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "reviews" ADD CONSTRAINT "reviews_author_id_users_id_fk" FOREIGN KEY ("author_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "reviews" ADD CONSTRAINT "reviews_subject_id_users_id_fk" FOREIGN KEY ("subject_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "audit_log" ADD CONSTRAINT "audit_log_actor_id_users_id_fk" FOREIGN KEY ("actor_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
CREATE INDEX "phone_otps_phone_idx" ON "phone_otps" USING btree ("phone","expires_at");--> statement-breakpoint
CREATE INDEX "users_role_idx" ON "users" USING btree ("role");--> statement-breakpoint
CREATE INDEX "users_phone_idx" ON "users" USING btree ("phone");--> statement-breakpoint
CREATE INDEX "credentials_pro_idx" ON "credentials" USING btree ("pro_id");--> statement-breakpoint
CREATE INDEX "credentials_review_idx" ON "credentials" USING btree ("review_status");--> statement-breakpoint
CREATE INDEX "credentials_expiry_idx" ON "credentials" USING btree ("expires_at");--> statement-breakpoint
CREATE INDEX "pro_availability_pro_idx" ON "pro_availability" USING btree ("pro_id","weekday");--> statement-breakpoint
CREATE INDEX "pro_categories_category_idx" ON "pro_categories" USING btree ("category_id");--> statement-breakpoint
CREATE INDEX "pro_media_pro_idx" ON "pro_media" USING btree ("pro_id","position");--> statement-breakpoint
CREATE INDEX "pro_profiles_location_gist" ON "pro_profiles" USING gist ("base_location");--> statement-breakpoint
CREATE INDEX "pro_profiles_deck_idx" ON "pro_profiles" USING btree ("verification_status","is_accepting_jobs") WHERE "pro_profiles"."verification_status" = 'verified' AND "pro_profiles"."is_accepting_jobs" = true;--> statement-breakpoint
CREATE INDEX "verification_sessions_pro_idx" ON "verification_sessions" USING btree ("pro_id");--> statement-breakpoint
CREATE INDEX "jobs_location_gist" ON "jobs" USING gist ("location");--> statement-breakpoint
CREATE INDEX "jobs_client_idx" ON "jobs" USING btree ("client_id","status");--> statement-breakpoint
CREATE INDEX "jobs_open_idx" ON "jobs" USING btree ("category_id") WHERE "jobs"."status" = 'open';--> statement-breakpoint
CREATE INDEX "matches_pro_idx" ON "matches" USING btree ("pro_id","last_message_at");--> statement-breakpoint
CREATE INDEX "matches_client_idx" ON "matches" USING btree ("client_id","last_message_at");--> statement-breakpoint
CREATE INDEX "matches_job_idx" ON "matches" USING btree ("job_id");--> statement-breakpoint
CREATE INDEX "requests_pending_idx" ON "requests" USING btree ("pro_id","expires_at") WHERE "requests"."status" = 'pending';--> statement-breakpoint
CREATE INDEX "requests_job_idx" ON "requests" USING btree ("job_id","status");--> statement-breakpoint
CREATE INDEX "swipes_job_idx" ON "swipes" USING btree ("job_id");--> statement-breakpoint
CREATE INDEX "messages_match_idx" ON "messages" USING btree ("match_id","created_at");--> statement-breakpoint
CREATE INDEX "messages_unread_idx" ON "messages" USING btree ("match_id","sender_id") WHERE "messages"."read_at" IS NULL;--> statement-breakpoint
CREATE INDEX "bookings_match_idx" ON "bookings" USING btree ("match_id");--> statement-breakpoint
CREATE INDEX "bookings_status_idx" ON "bookings" USING btree ("status","pro_completed_at");--> statement-breakpoint
CREATE INDEX "bookings_schedule_idx" ON "bookings" USING btree ("scheduled_start");--> statement-breakpoint
CREATE INDEX "payments_status_idx" ON "payments" USING btree ("status");--> statement-breakpoint
CREATE INDEX "payments_intent_idx" ON "payments" USING btree ("stripe_payment_intent_id");--> statement-breakpoint
CREATE INDEX "quotes_match_idx" ON "quotes" USING btree ("match_id","status");--> statement-breakpoint
CREATE INDEX "reviews_subject_idx" ON "reviews" USING btree ("subject_id","published_at");--> statement-breakpoint
CREATE INDEX "audit_log_entity_idx" ON "audit_log" USING btree ("entity","entity_id");--> statement-breakpoint
CREATE INDEX "audit_log_actor_idx" ON "audit_log" USING btree ("actor_id","created_at");
File diff suppressed because it is too large Load Diff
+13
View File
@@ -0,0 +1,13 @@
{
"version": "7",
"dialect": "postgresql",
"entries": [
{
"idx": 0,
"version": "7",
"when": 1787246593084,
"tag": "0000_old_gorilla_man",
"breakpoints": true
}
]
}