Migrate participant_golf_skills from per-season to canonical table (one row per real-world player), mirroring the existing participant_surface_elos pattern. Adds admin UI to copy participants between same-sport seasons with EV stubs, transactional writes, and comprehensive tests.
80 lines
3.9 KiB
PL/PgSQL
80 lines
3.9 KiB
PL/PgSQL
-- Step 1: Create the backup per-season table
|
|
CREATE TABLE IF NOT EXISTS "season_participant_golf_skills" (
|
|
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
"participant_id" uuid NOT NULL,
|
|
"sports_season_id" uuid NOT NULL,
|
|
"sg_total" numeric(5, 2),
|
|
"datagolf_rank" integer,
|
|
"masters_odds" integer,
|
|
"us_open_odds" integer,
|
|
"open_championship_odds" integer,
|
|
"pga_championship_odds" integer,
|
|
"updated_at" timestamp DEFAULT now() NOT NULL
|
|
);
|
|
--> statement-breakpoint
|
|
|
|
-- Step 2: Copy existing per-season data to backup table
|
|
INSERT INTO "season_participant_golf_skills" ("id", "participant_id", "sports_season_id", "sg_total", "datagolf_rank", "masters_odds", "us_open_odds", "open_championship_odds", "pga_championship_odds", "updated_at")
|
|
SELECT "id", "participant_id", "sports_season_id", "sg_total", "datagolf_rank", "masters_odds", "us_open_odds", "open_championship_odds", "pga_championship_odds", "updated_at"
|
|
FROM "participant_golf_skills";
|
|
--> statement-breakpoint
|
|
|
|
-- Step 3: Add FK constraints on backup table
|
|
DO $$ BEGIN
|
|
ALTER TABLE "season_participant_golf_skills" ADD CONSTRAINT "season_participant_golf_skills_participant_id_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_participants"("id") ON DELETE cascade ON UPDATE no action;
|
|
EXCEPTION
|
|
WHEN duplicate_object THEN null;
|
|
END $$;
|
|
--> statement-breakpoint
|
|
DO $$ BEGIN
|
|
ALTER TABLE "season_participant_golf_skills" ADD CONSTRAINT "season_participant_golf_skills_sports_season_id_sports_seasons_id_fk" FOREIGN KEY ("sports_season_id") REFERENCES "public"."sports_seasons"("id") ON DELETE cascade ON UPDATE no action;
|
|
EXCEPTION
|
|
WHEN duplicate_object THEN null;
|
|
END $$;
|
|
--> statement-breakpoint
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "season_participant_golf_skills_unique" ON "season_participant_golf_skills" USING btree ("participant_id","sports_season_id");
|
|
--> statement-breakpoint
|
|
|
|
-- Step 4 + 5: Clear and repurpose participant_golf_skills as canonical table.
|
|
-- Wrapped in a transaction so that a failure between TRUNCATE and re-INSERT
|
|
-- doesn't leave the table empty. The backup table from steps 1-3 remains as a
|
|
-- safety net regardless.
|
|
BEGIN;
|
|
--> statement-breakpoint
|
|
ALTER TABLE "participant_golf_skills" DROP CONSTRAINT IF EXISTS "participant_golf_skills_participant_id_season_participants_id_fk";
|
|
--> statement-breakpoint
|
|
ALTER TABLE "participant_golf_skills" DROP CONSTRAINT IF EXISTS "participant_golf_skills_sports_season_id_sports_seasons_id_fk";
|
|
--> statement-breakpoint
|
|
DROP INDEX IF EXISTS "participant_golf_skills_unique";
|
|
--> statement-breakpoint
|
|
ALTER TABLE "participant_golf_skills" DROP COLUMN IF EXISTS "sports_season_id";
|
|
--> statement-breakpoint
|
|
TRUNCATE "participant_golf_skills";
|
|
--> statement-breakpoint
|
|
DO $$ BEGIN
|
|
ALTER TABLE "participant_golf_skills" ADD CONSTRAINT "participant_golf_skills_participant_id_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."participants"("id") ON DELETE cascade ON UPDATE no action;
|
|
EXCEPTION
|
|
WHEN duplicate_object THEN null;
|
|
END $$;
|
|
--> statement-breakpoint
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "participant_golf_skills_participant_unique" ON "participant_golf_skills" USING btree ("participant_id");
|
|
--> statement-breakpoint
|
|
|
|
-- Migrate data from per-season to canonical, taking latest values per canonical participant
|
|
INSERT INTO "participant_golf_skills" ("id", "participant_id", "sg_total", "datagolf_rank", "masters_odds", "us_open_odds", "open_championship_odds", "pga_championship_odds", "updated_at")
|
|
SELECT DISTINCT ON (sp.participant_id)
|
|
gen_random_uuid(),
|
|
sp.participant_id,
|
|
backup.sg_total,
|
|
backup.datagolf_rank,
|
|
backup.masters_odds,
|
|
backup.us_open_odds,
|
|
backup.open_championship_odds,
|
|
backup.pga_championship_odds,
|
|
backup.updated_at
|
|
FROM "season_participant_golf_skills" backup
|
|
JOIN "season_participants" sp ON backup.participant_id = sp.id
|
|
WHERE sp.participant_id IS NOT NULL
|
|
ORDER BY sp.participant_id, backup.updated_at DESC;
|
|
--> statement-breakpoint
|
|
COMMIT;
|