-- DropIndex DROP INDEX IF EXISTS "onboarding_requests_email_verification_token_hash_key"; -- DropIndex DROP INDEX IF EXISTS "onboarding_requests_expires_at_idx"; -- AlterTable ALTER TABLE "onboarding_requests" ADD COLUMN "otp_hash" TEXT, ADD COLUMN "otp_expires_at" TIMESTAMP(3), ADD COLUMN "otp_attempts" INTEGER NOT NULL DEFAULT 0, ADD COLUMN "otp_last_sent_at" TIMESTAMP(3), ADD COLUMN "otp_resend_count" INTEGER NOT NULL DEFAULT 0; -- Backfill for existing rows UPDATE "onboarding_requests" SET "otp_hash" = md5("id"::text || ':legacy'), "otp_expires_at" = COALESCE("expires_at", NOW()), "otp_last_sent_at" = COALESCE("email_verification_sent_at", NOW()); -- Enforce required fields ALTER TABLE "onboarding_requests" ALTER COLUMN "otp_hash" SET NOT NULL, ALTER COLUMN "otp_expires_at" SET NOT NULL, ALTER COLUMN "otp_last_sent_at" SET NOT NULL; -- CreateIndex CREATE INDEX "onboarding_requests_otp_expires_at_idx" ON "onboarding_requests"("otp_expires_at"); -- Drop legacy columns ALTER TABLE "onboarding_requests" DROP COLUMN "email_verification_token_hash", DROP COLUMN "email_verification_sent_at", DROP COLUMN "expires_at";