-- OEM community voting + gamification ledger. -- oem_votes: one row per (user, oem_code) uyumlu/uyumsuz verdict cast from the -- catalog part rows. Votes pool globally per code; part/vehicle/category are -- analytics breadcrumbs only (catalog routes pass catalog_vehicles ids → no FK, -- mirrors oem_code_copies). Re-votes update the row in place. -- oem_vote_points: append-only, exactly one row per vote (vote_id unique), -- written in the same transaction. points = 1 (vote) + 2 (agreed with strict -- majority at cast time; first voter always 3). Never retro-adjusted. CREATE TABLE "oem_votes" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "user_id" uuid NOT NULL, "oem_code" varchar(100) NOT NULL, "vote" varchar(12) NOT NULL, "part_id" uuid, "vehicle_id" uuid, "category_id" uuid, "created_at" timestamp with time zone DEFAULT now() NOT NULL, "updated_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE TABLE "oem_vote_points" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "user_id" uuid NOT NULL, "vote_id" uuid NOT NULL, "oem_code" varchar(100) NOT NULL, "points" integer NOT NULL, "correct" boolean DEFAULT false NOT NULL, "created_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint ALTER TABLE "oem_votes" ADD CONSTRAINT "oem_votes_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "oem_vote_points" ADD CONSTRAINT "oem_vote_points_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "oem_vote_points" ADD CONSTRAINT "oem_vote_points_vote_id_oem_votes_id_fk" FOREIGN KEY ("vote_id") REFERENCES "public"."oem_votes"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint CREATE UNIQUE INDEX "oem_votes_user_oem_idx" ON "oem_votes" USING btree ("user_id","oem_code");--> statement-breakpoint CREATE INDEX "oem_votes_oem_code_idx" ON "oem_votes" USING btree ("oem_code");--> statement-breakpoint CREATE UNIQUE INDEX "oem_vote_points_vote_id_idx" ON "oem_vote_points" USING btree ("vote_id");--> statement-breakpoint CREATE INDEX "oem_vote_points_user_id_idx" ON "oem_vote_points" USING btree ("user_id");