244 lines
7.5 KiB
SQL
244 lines
7.5 KiB
SQL
-- ============================================================================
|
|
-- auth-service 初始化 migration
|
|
-- 合并自: 20260111000000_init, 20260111083500_allow_nullable_phone_password,
|
|
-- 20260112110000_add_nickname_to_synced_legacy_users
|
|
-- ============================================================================
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "UserStatus" AS ENUM ('ACTIVE', 'DISABLED', 'DELETED');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "KycStatus" AS ENUM ('PENDING', 'SUBMITTED', 'VERIFIED', 'REJECTED');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "SmsVerificationType" AS ENUM ('REGISTER', 'LOGIN', 'RESET_PASSWORD', 'CHANGE_PHONE');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "SmsStatus" AS ENUM ('PENDING', 'SENT', 'DELIVERED', 'FAILED');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "LoginType" AS ENUM ('PASSWORD', 'SMS_CODE', 'LEGACY_MIGRATE');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "OutboxStatus" AS ENUM ('PENDING', 'PUBLISHED', 'FAILED');
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "users" (
|
|
"id" BIGSERIAL NOT NULL,
|
|
"phone" TEXT NOT NULL,
|
|
"password_hash" TEXT NOT NULL,
|
|
"account_sequence" TEXT NOT NULL,
|
|
"status" "UserStatus" NOT NULL DEFAULT 'ACTIVE',
|
|
"kycStatus" "KycStatus" NOT NULL DEFAULT 'PENDING',
|
|
"real_name" TEXT,
|
|
"id_card_no" TEXT,
|
|
"id_card_front" TEXT,
|
|
"id_card_back" TEXT,
|
|
"kyc_submitted_at" TIMESTAMP(3),
|
|
"kyc_verified_at" TIMESTAMP(3),
|
|
"kyc_reject_reason" TEXT,
|
|
"login_fail_count" INTEGER NOT NULL DEFAULT 0,
|
|
"locked_until" TIMESTAMP(3),
|
|
"last_login_at" TIMESTAMP(3),
|
|
"last_login_ip" TEXT,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "synced_legacy_users" (
|
|
"id" BIGSERIAL NOT NULL,
|
|
"legacy_id" BIGINT NOT NULL,
|
|
"account_sequence" TEXT NOT NULL,
|
|
"phone" TEXT,
|
|
"password_hash" TEXT,
|
|
"nickname" TEXT,
|
|
"status" TEXT NOT NULL,
|
|
"legacy_created_at" TIMESTAMP(3) NOT NULL,
|
|
"migrated_to_v2" BOOLEAN NOT NULL DEFAULT false,
|
|
"migrated_at" TIMESTAMP(3),
|
|
"source_sequence_num" BIGINT NOT NULL,
|
|
"synced_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "synced_legacy_users_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "refresh_tokens" (
|
|
"id" BIGSERIAL NOT NULL,
|
|
"user_id" BIGINT NOT NULL,
|
|
"token" TEXT NOT NULL,
|
|
"device_info" TEXT,
|
|
"ip_address" TEXT,
|
|
"expires_at" TIMESTAMP(3) NOT NULL,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"revoked_at" TIMESTAMP(3),
|
|
|
|
CONSTRAINT "refresh_tokens_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "sms_verifications" (
|
|
"id" BIGSERIAL NOT NULL,
|
|
"phone" TEXT NOT NULL,
|
|
"code" TEXT NOT NULL,
|
|
"type" "SmsVerificationType" NOT NULL,
|
|
"expires_at" TIMESTAMP(3) NOT NULL,
|
|
"verified_at" TIMESTAMP(3),
|
|
"attempts" INTEGER NOT NULL DEFAULT 0,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "sms_verifications_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "sms_logs" (
|
|
"id" BIGSERIAL NOT NULL,
|
|
"user_id" BIGINT,
|
|
"phone" TEXT NOT NULL,
|
|
"type" "SmsVerificationType" NOT NULL,
|
|
"content" TEXT,
|
|
"status" "SmsStatus" NOT NULL DEFAULT 'PENDING',
|
|
"provider" TEXT,
|
|
"provider_id" TEXT,
|
|
"error_msg" TEXT,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "sms_logs_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "login_logs" (
|
|
"id" BIGSERIAL NOT NULL,
|
|
"user_id" BIGINT,
|
|
"phone" TEXT NOT NULL,
|
|
"type" "LoginType" NOT NULL,
|
|
"success" BOOLEAN NOT NULL,
|
|
"fail_reason" TEXT,
|
|
"ip_address" TEXT,
|
|
"user_agent" TEXT,
|
|
"device_info" TEXT,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "login_logs_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "daily_sequence_counters" (
|
|
"id" BIGSERIAL NOT NULL,
|
|
"date_key" TEXT NOT NULL,
|
|
"last_seq" INTEGER NOT NULL DEFAULT 0,
|
|
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "daily_sequence_counters_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "outbox_events" (
|
|
"id" BIGSERIAL NOT NULL,
|
|
"aggregate_type" TEXT NOT NULL,
|
|
"aggregate_id" TEXT NOT NULL,
|
|
"event_type" TEXT NOT NULL,
|
|
"payload" JSONB NOT NULL,
|
|
"topic" TEXT NOT NULL,
|
|
"key" TEXT NOT NULL,
|
|
"status" "OutboxStatus" NOT NULL DEFAULT 'PENDING',
|
|
"retry_count" INTEGER NOT NULL DEFAULT 0,
|
|
"max_retries" INTEGER NOT NULL DEFAULT 3,
|
|
"last_error" TEXT,
|
|
"published_at" TIMESTAMP(3),
|
|
"next_retry_at" TIMESTAMP(3),
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "outbox_events_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "users_phone_key" ON "users"("phone");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "users_account_sequence_key" ON "users"("account_sequence");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "users_phone_idx" ON "users"("phone");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "users_account_sequence_idx" ON "users"("account_sequence");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "users_status_idx" ON "users"("status");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "users_kycStatus_idx" ON "users"("kycStatus");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "synced_legacy_users_legacy_id_key" ON "synced_legacy_users"("legacy_id");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "synced_legacy_users_account_sequence_key" ON "synced_legacy_users"("account_sequence");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "synced_legacy_users_phone_idx" ON "synced_legacy_users"("phone");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "synced_legacy_users_account_sequence_idx" ON "synced_legacy_users"("account_sequence");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "synced_legacy_users_migrated_to_v2_idx" ON "synced_legacy_users"("migrated_to_v2");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "refresh_tokens_token_key" ON "refresh_tokens"("token");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "refresh_tokens_user_id_idx" ON "refresh_tokens"("user_id");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "refresh_tokens_token_idx" ON "refresh_tokens"("token");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "refresh_tokens_expires_at_idx" ON "refresh_tokens"("expires_at");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "sms_verifications_phone_type_idx" ON "sms_verifications"("phone", "type");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "sms_verifications_expires_at_idx" ON "sms_verifications"("expires_at");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "sms_logs_phone_idx" ON "sms_logs"("phone");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "sms_logs_user_id_idx" ON "sms_logs"("user_id");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "sms_logs_created_at_idx" ON "sms_logs"("created_at");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "login_logs_user_id_idx" ON "login_logs"("user_id");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "login_logs_phone_idx" ON "login_logs"("phone");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "login_logs_created_at_idx" ON "login_logs"("created_at");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "daily_sequence_counters_date_key_key" ON "daily_sequence_counters"("date_key");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "outbox_events_status_idx" ON "outbox_events"("status");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "outbox_events_next_retry_at_idx" ON "outbox_events"("next_retry_at");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "refresh_tokens" ADD CONSTRAINT "refresh_tokens_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "sms_logs" ADD CONSTRAINT "sms_logs_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "login_logs" ADD CONSTRAINT "login_logs_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|