fix: 修复多个服务的 accountSequence 类型和推荐关系 bug
1. referral-service: 修复 userId 从临时值 0 导致的 "用户ID必须大于0" 错误 - 从 accountSequence 提取数值部分作为 userId (去掉 "D" 前缀) - 避免依赖 identity-service 发送的临时 userId 2. 多服务 migration 修复: accountSequence/inviterSequence 类型从 BIGINT 改为 VARCHAR(12) - identity-service: account_sequence, inviter_sequence - authorization-service: account_sequence - blockchain-service: account_sequence - referral-service: account_sequence - reward-service: account_sequence - backup-service: account_sequence 3. mpc-service 与 backup-service 集成: - mpc-service: 添加 BACKUP_SERVICE_URL, BACKUP_SERVICE_ENABLED, SERVICE_JWT_SECRET - backup-service: ALLOWED_SERVICES 添加 mpc-service 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
4be9c1fb82
commit
75c49951b7
|
|
@ -1,14 +1,14 @@
|
|||
-- Step 1: Add account_sequence columns to all tables first
|
||||
ALTER TABLE "authorization_roles" ADD COLUMN "account_sequence" BIGINT;
|
||||
ALTER TABLE "monthly_assessments" ADD COLUMN "account_sequence" BIGINT;
|
||||
ALTER TABLE "monthly_bypasses" ADD COLUMN "account_sequence" BIGINT;
|
||||
ALTER TABLE "stickman_rankings" ADD COLUMN "account_sequence" BIGINT;
|
||||
ALTER TABLE "authorization_roles" ADD COLUMN "account_sequence" TEXT;
|
||||
ALTER TABLE "monthly_assessments" ADD COLUMN "account_sequence" TEXT;
|
||||
ALTER TABLE "monthly_bypasses" ADD COLUMN "account_sequence" TEXT;
|
||||
ALTER TABLE "stickman_rankings" ADD COLUMN "account_sequence" TEXT;
|
||||
|
||||
-- Step 2: Backfill account_sequence from existing user_id (which is still String at this point)
|
||||
UPDATE "authorization_roles" SET "account_sequence" = CAST("user_id" AS BIGINT) WHERE "account_sequence" IS NULL;
|
||||
UPDATE "monthly_assessments" SET "account_sequence" = CAST("user_id" AS BIGINT) WHERE "account_sequence" IS NULL;
|
||||
UPDATE "monthly_bypasses" SET "account_sequence" = CAST("user_id" AS BIGINT) WHERE "account_sequence" IS NULL;
|
||||
UPDATE "stickman_rankings" SET "account_sequence" = CAST("user_id" AS BIGINT) WHERE "account_sequence" IS NULL;
|
||||
UPDATE "authorization_roles" SET "account_sequence" = "user_id" WHERE "account_sequence" IS NULL;
|
||||
UPDATE "monthly_assessments" SET "account_sequence" = "user_id" WHERE "account_sequence" IS NULL;
|
||||
UPDATE "monthly_bypasses" SET "account_sequence" = "user_id" WHERE "account_sequence" IS NULL;
|
||||
UPDATE "stickman_rankings" SET "account_sequence" = "user_id" WHERE "account_sequence" IS NULL;
|
||||
|
||||
-- Step 3: Make account_sequence NOT NULL
|
||||
ALTER TABLE "authorization_roles" ALTER COLUMN "account_sequence" SET NOT NULL;
|
||||
|
|
|
|||
|
|
@ -1,47 +1,47 @@
|
|||
# =============================================================================
|
||||
# Backup Service - Docker Compose (Development/Standalone)
|
||||
# =============================================================================
|
||||
# For production, use the root docker-compose.yml in ../
|
||||
#
|
||||
# For standalone development:
|
||||
# 1. First start shared infrastructure: cd .. && ./deploy.sh up postgres redis kafka
|
||||
# 2. Then: docker compose up -d --build
|
||||
# =============================================================================
|
||||
|
||||
services:
|
||||
backup-service:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: rwa-backup-service
|
||||
ports:
|
||||
- "3002:3002"
|
||||
environment:
|
||||
# Application
|
||||
- NODE_ENV=production
|
||||
- APP_PORT=3002
|
||||
- APP_ENV=production
|
||||
# Database (shared PostgreSQL)
|
||||
- DATABASE_URL=postgresql://rwa_user:rwa_secure_password@rwa-postgres:5432/rwa_backup?schema=public
|
||||
# Service Authentication
|
||||
- SERVICE_JWT_SECRET=${SERVICE_JWT_SECRET:-your-service-jwt-secret}
|
||||
- ALLOWED_SERVICES=identity-service,recovery-service
|
||||
# Backup Encryption
|
||||
- BACKUP_ENCRYPTION_KEY=${BACKUP_ENCRYPTION_KEY:-0123456789abcdef0123456789abcdef}
|
||||
- BACKUP_ENCRYPTION_KEY_ID=${BACKUP_ENCRYPTION_KEY_ID:-key-v1}
|
||||
# Rate Limits
|
||||
- MAX_RETRIEVE_PER_DAY=3
|
||||
- MAX_STORE_PER_MINUTE=10
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:3002/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
networks:
|
||||
rwa-network:
|
||||
external: true
|
||||
# =============================================================================
|
||||
# Backup Service - Docker Compose (Development/Standalone)
|
||||
# =============================================================================
|
||||
# For production, use the root docker-compose.yml in ../
|
||||
#
|
||||
# For standalone development:
|
||||
# 1. First start shared infrastructure: cd .. && ./deploy.sh up postgres redis kafka
|
||||
# 2. Then: docker compose up -d --build
|
||||
# =============================================================================
|
||||
|
||||
services:
|
||||
backup-service:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: rwa-backup-service
|
||||
ports:
|
||||
- "3002:3002"
|
||||
environment:
|
||||
# Application
|
||||
- NODE_ENV=production
|
||||
- APP_PORT=3002
|
||||
- APP_ENV=production
|
||||
# Database (shared PostgreSQL)
|
||||
- DATABASE_URL=postgresql://rwa_user:rwa_secure_password@rwa-postgres:5432/rwa_backup?schema=public
|
||||
# Service Authentication
|
||||
- SERVICE_JWT_SECRET=${SERVICE_JWT_SECRET:-your-service-jwt-secret}
|
||||
- ALLOWED_SERVICES=identity-service,recovery-service,mpc-service
|
||||
# Backup Encryption
|
||||
- BACKUP_ENCRYPTION_KEY=${BACKUP_ENCRYPTION_KEY:-0123456789abcdef0123456789abcdef}
|
||||
- BACKUP_ENCRYPTION_KEY_ID=${BACKUP_ENCRYPTION_KEY_ID:-key-v1}
|
||||
# Rate Limits
|
||||
- MAX_RETRIEVE_PER_DAY=3
|
||||
- MAX_STORE_PER_MINUTE=10
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:3002/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- rwa-network
|
||||
|
||||
networks:
|
||||
rwa-network:
|
||||
external: true
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
CREATE TABLE "backup_shares" (
|
||||
"share_id" BIGSERIAL NOT NULL,
|
||||
"user_id" BIGINT NOT NULL,
|
||||
"account_sequence" BIGINT NOT NULL,
|
||||
"account_sequence" VARCHAR(12) NOT NULL,
|
||||
"public_key" VARCHAR(130) NOT NULL,
|
||||
"party_index" INTEGER NOT NULL DEFAULT 2,
|
||||
"threshold" INTEGER NOT NULL DEFAULT 2,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ model BackupShare {
|
|||
|
||||
// 用户标识 (来自 identity-service)
|
||||
userId BigInt @unique @map("user_id")
|
||||
accountSequence String @unique @map("account_sequence") // 格式: D + YYMMDD + 5位序号
|
||||
accountSequence String @unique @map("account_sequence") @db.VarChar(12) // 格式: D + YYMMDD + 5位序号
|
||||
|
||||
// MPC 密钥信息
|
||||
publicKey String @unique @map("public_key") @db.VarChar(130)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
-- AlterTable: monitored_addresses
|
||||
-- Add new columns for system accounts and account_sequence
|
||||
ALTER TABLE "monitored_addresses" ADD COLUMN "address_type" VARCHAR(20) NOT NULL DEFAULT 'USER';
|
||||
ALTER TABLE "monitored_addresses" ADD COLUMN "account_sequence" BIGINT;
|
||||
ALTER TABLE "monitored_addresses" ADD COLUMN "account_sequence" VARCHAR(20);
|
||||
ALTER TABLE "monitored_addresses" ADD COLUMN "system_account_type" VARCHAR(50);
|
||||
ALTER TABLE "monitored_addresses" ADD COLUMN "system_account_id" BIGINT;
|
||||
ALTER TABLE "monitored_addresses" ADD COLUMN "region_code" VARCHAR(10);
|
||||
|
|
@ -16,7 +16,7 @@ ALTER TABLE "monitored_addresses" ALTER COLUMN "user_id" DROP NOT NULL;
|
|||
-- AlterTable: deposit_transactions
|
||||
-- Add new columns for system accounts and account_sequence
|
||||
ALTER TABLE "deposit_transactions" ADD COLUMN "address_type" VARCHAR(20) NOT NULL DEFAULT 'USER';
|
||||
ALTER TABLE "deposit_transactions" ADD COLUMN "account_sequence" BIGINT;
|
||||
ALTER TABLE "deposit_transactions" ADD COLUMN "account_sequence" VARCHAR(20);
|
||||
ALTER TABLE "deposit_transactions" ADD COLUMN "system_account_type" VARCHAR(50);
|
||||
ALTER TABLE "deposit_transactions" ADD COLUMN "system_account_id" BIGINT;
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ ALTER TABLE "deposit_transactions" ALTER COLUMN "user_id" DROP NOT NULL;
|
|||
-- CreateTable: recovery_mnemonics
|
||||
CREATE TABLE "recovery_mnemonics" (
|
||||
"id" BIGSERIAL NOT NULL,
|
||||
"account_sequence" INTEGER NOT NULL,
|
||||
"account_sequence" VARCHAR(20) NOT NULL,
|
||||
"public_key" VARCHAR(130) NOT NULL,
|
||||
"encrypted_mnemonic" TEXT NOT NULL,
|
||||
"mnemonic_hash" VARCHAR(64) NOT NULL,
|
||||
|
|
|
|||
|
|
@ -1,352 +1,352 @@
|
|||
-- CreateTable
|
||||
CREATE TABLE "user_accounts" (
|
||||
"user_id" BIGSERIAL NOT NULL,
|
||||
"account_sequence" BIGINT NOT NULL,
|
||||
"phone_number" VARCHAR(20),
|
||||
"nickname" VARCHAR(100) NOT NULL,
|
||||
"avatar_url" TEXT,
|
||||
"inviter_sequence" BIGINT,
|
||||
"referral_code" VARCHAR(10) NOT NULL,
|
||||
"kyc_status" VARCHAR(20) NOT NULL DEFAULT 'NOT_VERIFIED',
|
||||
"real_name" VARCHAR(100),
|
||||
"id_card_number" VARCHAR(20),
|
||||
"id_card_front_url" VARCHAR(500),
|
||||
"id_card_back_url" VARCHAR(500),
|
||||
"kyc_verified_at" TIMESTAMP(3),
|
||||
"status" VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
|
||||
"registered_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"last_login_at" TIMESTAMP(3),
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "user_accounts_pkey" PRIMARY KEY ("user_id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "user_devices" (
|
||||
"id" BIGSERIAL NOT NULL,
|
||||
"user_id" BIGINT NOT NULL,
|
||||
"device_id" VARCHAR(100) NOT NULL,
|
||||
"device_name" VARCHAR(100),
|
||||
"device_info" JSONB,
|
||||
"platform" VARCHAR(20),
|
||||
"device_model" VARCHAR(100),
|
||||
"os_version" VARCHAR(50),
|
||||
"app_version" VARCHAR(20),
|
||||
"screen_width" INTEGER,
|
||||
"screen_height" INTEGER,
|
||||
"locale" VARCHAR(10),
|
||||
"timezone" VARCHAR(50),
|
||||
"added_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"last_active_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "user_devices_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "wallet_addresses" (
|
||||
"address_id" BIGSERIAL NOT NULL,
|
||||
"user_id" BIGINT NOT NULL,
|
||||
"chain_type" VARCHAR(20) NOT NULL,
|
||||
"address" VARCHAR(100) NOT NULL,
|
||||
"public_key" VARCHAR(130) NOT NULL,
|
||||
"address_digest" VARCHAR(66) NOT NULL,
|
||||
"mpc_signature_r" VARCHAR(66) NOT NULL,
|
||||
"mpc_signature_s" VARCHAR(66) NOT NULL,
|
||||
"mpc_signature_v" INTEGER NOT NULL,
|
||||
"status" VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
|
||||
"bound_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "wallet_addresses_pkey" PRIMARY KEY ("address_id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "account_sequence_generator" (
|
||||
"id" INTEGER NOT NULL DEFAULT 1,
|
||||
"current_sequence" BIGINT NOT NULL DEFAULT 0,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "account_sequence_generator_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "user_events" (
|
||||
"event_id" BIGSERIAL NOT NULL,
|
||||
"event_type" VARCHAR(50) NOT NULL,
|
||||
"aggregate_id" VARCHAR(100) NOT NULL,
|
||||
"aggregate_type" VARCHAR(50) NOT NULL,
|
||||
"event_data" JSONB NOT NULL,
|
||||
"user_id" BIGINT,
|
||||
"occurred_at" TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"version" INTEGER NOT NULL DEFAULT 1,
|
||||
|
||||
CONSTRAINT "user_events_pkey" PRIMARY KEY ("event_id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "device_tokens" (
|
||||
"id" BIGSERIAL NOT NULL,
|
||||
"user_id" BIGINT NOT NULL,
|
||||
"device_id" VARCHAR(100) NOT NULL,
|
||||
"refresh_token_hash" VARCHAR(64) NOT NULL,
|
||||
"expires_at" TIMESTAMP(3) NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"revoked_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "device_tokens_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "dead_letter_events" (
|
||||
"id" BIGSERIAL NOT NULL,
|
||||
"topic" VARCHAR(100) NOT NULL,
|
||||
"event_id" VARCHAR(100) NOT NULL,
|
||||
"event_type" VARCHAR(50) NOT NULL,
|
||||
"aggregate_id" VARCHAR(100) NOT NULL,
|
||||
"aggregate_type" VARCHAR(50) NOT NULL,
|
||||
"payload" JSONB,
|
||||
"error_message" TEXT NOT NULL,
|
||||
"error_stack" TEXT,
|
||||
"retry_count" INTEGER NOT NULL DEFAULT 0,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"processed_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "dead_letter_events_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "sms_codes" (
|
||||
"id" BIGSERIAL NOT NULL,
|
||||
"phone_number" VARCHAR(20) NOT NULL,
|
||||
"code" VARCHAR(10) NOT NULL,
|
||||
"purpose" VARCHAR(50) NOT NULL,
|
||||
"expires_at" TIMESTAMP(3) NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"used_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "sms_codes_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "mpc_key_shares" (
|
||||
"share_id" BIGSERIAL NOT NULL,
|
||||
"user_id" BIGINT NOT NULL,
|
||||
"public_key" VARCHAR(130) NOT NULL,
|
||||
"party_index" INTEGER NOT NULL,
|
||||
"threshold" INTEGER NOT NULL DEFAULT 2,
|
||||
"total_parties" INTEGER NOT NULL DEFAULT 3,
|
||||
"encrypted_share_data" TEXT NOT NULL,
|
||||
"status" VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"rotated_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "mpc_key_shares_pkey" PRIMARY KEY ("share_id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "mpc_sessions" (
|
||||
"session_id" VARCHAR(50) NOT NULL,
|
||||
"session_type" VARCHAR(20) NOT NULL,
|
||||
"user_id" BIGINT,
|
||||
"public_key" VARCHAR(130),
|
||||
"status" VARCHAR(20) NOT NULL DEFAULT 'PENDING',
|
||||
"error_message" TEXT,
|
||||
"message_hash" VARCHAR(66),
|
||||
"signature_r" VARCHAR(66),
|
||||
"signature_s" VARCHAR(66),
|
||||
"signature_v" INTEGER,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"completed_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "mpc_sessions_pkey" PRIMARY KEY ("session_id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "referral_links" (
|
||||
"link_id" BIGSERIAL NOT NULL,
|
||||
"user_id" BIGINT NOT NULL,
|
||||
"referral_code" VARCHAR(10) NOT NULL,
|
||||
"short_code" VARCHAR(10) NOT NULL,
|
||||
"channel" VARCHAR(50),
|
||||
"campaign_id" VARCHAR(50),
|
||||
"click_count" INTEGER NOT NULL DEFAULT 0,
|
||||
"register_count" INTEGER NOT NULL DEFAULT 0,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"expires_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "referral_links_pkey" PRIMARY KEY ("link_id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_accounts_account_sequence_key" ON "user_accounts"("account_sequence");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_accounts_phone_number_key" ON "user_accounts"("phone_number");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_accounts_referral_code_key" ON "user_accounts"("referral_code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_phone" ON "user_accounts"("phone_number");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_sequence" ON "user_accounts"("account_sequence");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_referral_code" ON "user_accounts"("referral_code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_inviter" ON "user_accounts"("inviter_sequence");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_kyc_status" ON "user_accounts"("kyc_status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_status" ON "user_accounts"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_device" ON "user_devices"("device_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_user" ON "user_devices"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_last_active" ON "user_devices"("last_active_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_platform" ON "user_devices"("platform");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "uk_user_device" ON "user_devices"("user_id", "device_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_wallet_user" ON "wallet_addresses"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_address" ON "wallet_addresses"("address");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_public_key" ON "wallet_addresses"("public_key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "uk_user_chain" ON "wallet_addresses"("user_id", "chain_type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "uk_chain_address" ON "wallet_addresses"("chain_type", "address");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_aggregate" ON "user_events"("aggregate_type", "aggregate_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_event_type" ON "user_events"("event_type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_event_user" ON "user_events"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_occurred" ON "user_events"("occurred_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "device_tokens_refresh_token_hash_key" ON "device_tokens"("refresh_token_hash");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_user_device_token" ON "device_tokens"("user_id", "device_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_expires" ON "device_tokens"("expires_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_topic" ON "dead_letter_events"("topic");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_dead_letter_event_type" ON "dead_letter_events"("event_type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_dead_letter_created" ON "dead_letter_events"("created_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_processed" ON "dead_letter_events"("processed_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_phone_purpose" ON "sms_codes"("phone_number", "purpose");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_sms_expires" ON "sms_codes"("expires_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "mpc_key_shares_user_id_key" ON "mpc_key_shares"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "mpc_key_shares_public_key_key" ON "mpc_key_shares"("public_key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_mpc_public_key" ON "mpc_key_shares"("public_key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_mpc_status" ON "mpc_key_shares"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_session_type" ON "mpc_sessions"("session_type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_session_user" ON "mpc_sessions"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_session_status" ON "mpc_sessions"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_session_created" ON "mpc_sessions"("created_at");
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "recovery_mnemonics" (
|
||||
"id" BIGSERIAL NOT NULL,
|
||||
"user_id" BIGINT NOT NULL,
|
||||
"public_key" VARCHAR(130) NOT NULL,
|
||||
"encrypted_mnemonic" TEXT NOT NULL,
|
||||
"mnemonic_hash" VARCHAR(64) NOT NULL,
|
||||
"status" VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
|
||||
"is_backed_up" BOOLEAN NOT NULL DEFAULT false,
|
||||
"revoked_at" TIMESTAMP(3),
|
||||
"revoked_reason" VARCHAR(200),
|
||||
"replaced_by_id" BIGINT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "recovery_mnemonics_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "uk_user_active_mnemonic" ON "recovery_mnemonics"("user_id", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_recovery_user" ON "recovery_mnemonics"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_recovery_public_key" ON "recovery_mnemonics"("public_key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_recovery_status" ON "recovery_mnemonics"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "referral_links_short_code_key" ON "referral_links"("short_code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_referral_link_user" ON "referral_links"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_referral_link_code" ON "referral_links"("referral_code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_referral_link_channel" ON "referral_links"("channel");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_referral_link_created" ON "referral_links"("created_at");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "user_devices" ADD CONSTRAINT "user_devices_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user_accounts"("user_id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "wallet_addresses" ADD CONSTRAINT "wallet_addresses_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user_accounts"("user_id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- Initialize sequence generator
|
||||
INSERT INTO "account_sequence_generator" ("id", "current_sequence", "updated_at")
|
||||
VALUES (1, 0, CURRENT_TIMESTAMP)
|
||||
ON CONFLICT ("id") DO NOTHING;
|
||||
-- CreateTable
|
||||
CREATE TABLE "user_accounts" (
|
||||
"user_id" BIGSERIAL NOT NULL,
|
||||
"account_sequence" VARCHAR(12) NOT NULL,
|
||||
"phone_number" VARCHAR(20),
|
||||
"nickname" VARCHAR(100) NOT NULL,
|
||||
"avatar_url" TEXT,
|
||||
"inviter_sequence" VARCHAR(12),
|
||||
"referral_code" VARCHAR(10) NOT NULL,
|
||||
"kyc_status" VARCHAR(20) NOT NULL DEFAULT 'NOT_VERIFIED',
|
||||
"real_name" VARCHAR(100),
|
||||
"id_card_number" VARCHAR(20),
|
||||
"id_card_front_url" VARCHAR(500),
|
||||
"id_card_back_url" VARCHAR(500),
|
||||
"kyc_verified_at" TIMESTAMP(3),
|
||||
"status" VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
|
||||
"registered_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"last_login_at" TIMESTAMP(3),
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "user_accounts_pkey" PRIMARY KEY ("user_id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "user_devices" (
|
||||
"id" BIGSERIAL NOT NULL,
|
||||
"user_id" BIGINT NOT NULL,
|
||||
"device_id" VARCHAR(100) NOT NULL,
|
||||
"device_name" VARCHAR(100),
|
||||
"device_info" JSONB,
|
||||
"platform" VARCHAR(20),
|
||||
"device_model" VARCHAR(100),
|
||||
"os_version" VARCHAR(50),
|
||||
"app_version" VARCHAR(20),
|
||||
"screen_width" INTEGER,
|
||||
"screen_height" INTEGER,
|
||||
"locale" VARCHAR(10),
|
||||
"timezone" VARCHAR(50),
|
||||
"added_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"last_active_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "user_devices_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "wallet_addresses" (
|
||||
"address_id" BIGSERIAL NOT NULL,
|
||||
"user_id" BIGINT NOT NULL,
|
||||
"chain_type" VARCHAR(20) NOT NULL,
|
||||
"address" VARCHAR(100) NOT NULL,
|
||||
"public_key" VARCHAR(130) NOT NULL,
|
||||
"address_digest" VARCHAR(66) NOT NULL,
|
||||
"mpc_signature_r" VARCHAR(66) NOT NULL,
|
||||
"mpc_signature_s" VARCHAR(66) NOT NULL,
|
||||
"mpc_signature_v" INTEGER NOT NULL,
|
||||
"status" VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
|
||||
"bound_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "wallet_addresses_pkey" PRIMARY KEY ("address_id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "account_sequence_generator" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"date_key" VARCHAR(6) NOT NULL,
|
||||
"current_sequence" INTEGER NOT NULL DEFAULT 0,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "account_sequence_generator_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex: account_sequence_generator unique constraint
|
||||
CREATE UNIQUE INDEX "account_sequence_generator_date_key_key" ON "account_sequence_generator"("date_key");
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "user_events" (
|
||||
"event_id" BIGSERIAL NOT NULL,
|
||||
"event_type" VARCHAR(50) NOT NULL,
|
||||
"aggregate_id" VARCHAR(100) NOT NULL,
|
||||
"aggregate_type" VARCHAR(50) NOT NULL,
|
||||
"event_data" JSONB NOT NULL,
|
||||
"user_id" BIGINT,
|
||||
"occurred_at" TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"version" INTEGER NOT NULL DEFAULT 1,
|
||||
|
||||
CONSTRAINT "user_events_pkey" PRIMARY KEY ("event_id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "device_tokens" (
|
||||
"id" BIGSERIAL NOT NULL,
|
||||
"user_id" BIGINT NOT NULL,
|
||||
"device_id" VARCHAR(100) NOT NULL,
|
||||
"refresh_token_hash" VARCHAR(64) NOT NULL,
|
||||
"expires_at" TIMESTAMP(3) NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"revoked_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "device_tokens_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "dead_letter_events" (
|
||||
"id" BIGSERIAL NOT NULL,
|
||||
"topic" VARCHAR(100) NOT NULL,
|
||||
"event_id" VARCHAR(100) NOT NULL,
|
||||
"event_type" VARCHAR(50) NOT NULL,
|
||||
"aggregate_id" VARCHAR(100) NOT NULL,
|
||||
"aggregate_type" VARCHAR(50) NOT NULL,
|
||||
"payload" JSONB,
|
||||
"error_message" TEXT NOT NULL,
|
||||
"error_stack" TEXT,
|
||||
"retry_count" INTEGER NOT NULL DEFAULT 0,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"processed_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "dead_letter_events_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "sms_codes" (
|
||||
"id" BIGSERIAL NOT NULL,
|
||||
"phone_number" VARCHAR(20) NOT NULL,
|
||||
"code" VARCHAR(10) NOT NULL,
|
||||
"purpose" VARCHAR(50) NOT NULL,
|
||||
"expires_at" TIMESTAMP(3) NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"used_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "sms_codes_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "mpc_key_shares" (
|
||||
"share_id" BIGSERIAL NOT NULL,
|
||||
"user_id" BIGINT NOT NULL,
|
||||
"public_key" VARCHAR(130) NOT NULL,
|
||||
"party_index" INTEGER NOT NULL,
|
||||
"threshold" INTEGER NOT NULL DEFAULT 2,
|
||||
"total_parties" INTEGER NOT NULL DEFAULT 3,
|
||||
"encrypted_share_data" TEXT NOT NULL,
|
||||
"status" VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"rotated_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "mpc_key_shares_pkey" PRIMARY KEY ("share_id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "mpc_sessions" (
|
||||
"session_id" VARCHAR(50) NOT NULL,
|
||||
"session_type" VARCHAR(20) NOT NULL,
|
||||
"user_id" BIGINT,
|
||||
"public_key" VARCHAR(130),
|
||||
"status" VARCHAR(20) NOT NULL DEFAULT 'PENDING',
|
||||
"error_message" TEXT,
|
||||
"message_hash" VARCHAR(66),
|
||||
"signature_r" VARCHAR(66),
|
||||
"signature_s" VARCHAR(66),
|
||||
"signature_v" INTEGER,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"completed_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "mpc_sessions_pkey" PRIMARY KEY ("session_id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "referral_links" (
|
||||
"link_id" BIGSERIAL NOT NULL,
|
||||
"user_id" BIGINT NOT NULL,
|
||||
"referral_code" VARCHAR(10) NOT NULL,
|
||||
"short_code" VARCHAR(10) NOT NULL,
|
||||
"channel" VARCHAR(50),
|
||||
"campaign_id" VARCHAR(50),
|
||||
"click_count" INTEGER NOT NULL DEFAULT 0,
|
||||
"register_count" INTEGER NOT NULL DEFAULT 0,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"expires_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "referral_links_pkey" PRIMARY KEY ("link_id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_accounts_account_sequence_key" ON "user_accounts"("account_sequence");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_accounts_phone_number_key" ON "user_accounts"("phone_number");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_accounts_referral_code_key" ON "user_accounts"("referral_code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_phone" ON "user_accounts"("phone_number");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_sequence" ON "user_accounts"("account_sequence");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_referral_code" ON "user_accounts"("referral_code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_inviter" ON "user_accounts"("inviter_sequence");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_kyc_status" ON "user_accounts"("kyc_status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_status" ON "user_accounts"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_device" ON "user_devices"("device_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_user" ON "user_devices"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_last_active" ON "user_devices"("last_active_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_platform" ON "user_devices"("platform");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "uk_user_device" ON "user_devices"("user_id", "device_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_wallet_user" ON "wallet_addresses"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_address" ON "wallet_addresses"("address");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_public_key" ON "wallet_addresses"("public_key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "uk_user_chain" ON "wallet_addresses"("user_id", "chain_type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "uk_chain_address" ON "wallet_addresses"("chain_type", "address");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_aggregate" ON "user_events"("aggregate_type", "aggregate_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_event_type" ON "user_events"("event_type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_event_user" ON "user_events"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_occurred" ON "user_events"("occurred_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "device_tokens_refresh_token_hash_key" ON "device_tokens"("refresh_token_hash");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_user_device_token" ON "device_tokens"("user_id", "device_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_expires" ON "device_tokens"("expires_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_topic" ON "dead_letter_events"("topic");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_dead_letter_event_type" ON "dead_letter_events"("event_type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_dead_letter_created" ON "dead_letter_events"("created_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_processed" ON "dead_letter_events"("processed_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_phone_purpose" ON "sms_codes"("phone_number", "purpose");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_sms_expires" ON "sms_codes"("expires_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "mpc_key_shares_user_id_key" ON "mpc_key_shares"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "mpc_key_shares_public_key_key" ON "mpc_key_shares"("public_key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_mpc_public_key" ON "mpc_key_shares"("public_key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_mpc_status" ON "mpc_key_shares"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_session_type" ON "mpc_sessions"("session_type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_session_user" ON "mpc_sessions"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_session_status" ON "mpc_sessions"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_session_created" ON "mpc_sessions"("created_at");
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "recovery_mnemonics" (
|
||||
"id" BIGSERIAL NOT NULL,
|
||||
"user_id" BIGINT NOT NULL,
|
||||
"public_key" VARCHAR(130) NOT NULL,
|
||||
"encrypted_mnemonic" TEXT NOT NULL,
|
||||
"mnemonic_hash" VARCHAR(64) NOT NULL,
|
||||
"status" VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
|
||||
"is_backed_up" BOOLEAN NOT NULL DEFAULT false,
|
||||
"revoked_at" TIMESTAMP(3),
|
||||
"revoked_reason" VARCHAR(200),
|
||||
"replaced_by_id" BIGINT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "recovery_mnemonics_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "uk_user_active_mnemonic" ON "recovery_mnemonics"("user_id", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_recovery_user" ON "recovery_mnemonics"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_recovery_public_key" ON "recovery_mnemonics"("public_key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_recovery_status" ON "recovery_mnemonics"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "referral_links_short_code_key" ON "referral_links"("short_code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_referral_link_user" ON "referral_links"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_referral_link_code" ON "referral_links"("referral_code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_referral_link_channel" ON "referral_links"("channel");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_referral_link_created" ON "referral_links"("created_at");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "user_devices" ADD CONSTRAINT "user_devices_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user_accounts"("user_id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "wallet_addresses" ADD CONSTRAINT "wallet_addresses_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user_accounts"("user_id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,10 @@ services:
|
|||
MPC_COORDINATOR_TIMEOUT: 30000
|
||||
# Share Encryption
|
||||
SHARE_MASTER_KEY: ${SHARE_MASTER_KEY:-0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef}
|
||||
# Backup Service
|
||||
BACKUP_SERVICE_URL: ${BACKUP_SERVICE_URL:-http://rwa-backup-service:3002}
|
||||
BACKUP_SERVICE_ENABLED: ${BACKUP_SERVICE_ENABLED:-true}
|
||||
SERVICE_JWT_SECRET: ${SERVICE_JWT_SECRET:-your-service-jwt-secret-change-in-production}
|
||||
# Timeouts
|
||||
MPC_KEYGEN_TIMEOUT: 300000
|
||||
MPC_SIGNING_TIMEOUT: 180000
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
CREATE TABLE "referral_relationships" (
|
||||
"relationship_id" BIGSERIAL NOT NULL,
|
||||
"user_id" BIGINT NOT NULL,
|
||||
"account_sequence" INTEGER NOT NULL,
|
||||
"account_sequence" VARCHAR(12) NOT NULL,
|
||||
"referrer_id" BIGINT,
|
||||
"root_user_id" BIGINT,
|
||||
"my_referral_code" VARCHAR(20) NOT NULL,
|
||||
|
|
@ -48,7 +48,7 @@ CREATE TABLE "direct_referrals" (
|
|||
"direct_referral_id" BIGSERIAL NOT NULL,
|
||||
"referrer_id" BIGINT NOT NULL,
|
||||
"referral_id" BIGINT NOT NULL,
|
||||
"referral_sequence" BIGINT NOT NULL,
|
||||
"referral_sequence" VARCHAR(12) NOT NULL,
|
||||
"referral_nickname" VARCHAR(100),
|
||||
"referral_avatar" VARCHAR(255),
|
||||
"personal_planting_count" INTEGER NOT NULL DEFAULT 0,
|
||||
|
|
|
|||
|
|
@ -64,15 +64,17 @@ export class UserRegisteredHandler implements OnModuleInit {
|
|||
`Processing ${event.eventType} event: accountSequence=${payload.accountSequence}, inviterSequence=${payload.inviterSequence}`,
|
||||
);
|
||||
|
||||
// 使用 accountSequence 作为 userId,因为 identity-service 的 userId 是内部自增ID,
|
||||
// 在事件发布时可能还是临时值 0,而 accountSequence 是全局唯一的业务标识
|
||||
// 注意:userId 仍然需要是 bigint,这里我们需要从 accountSequence 字符串中提取数值部分或使用其他方式
|
||||
// 暂时保持原有逻辑,但 accountSequence 本身现在是字符串类型
|
||||
// 从 accountSequence 提取数值部分作为 userId
|
||||
// accountSequence 格式: D + YYMMDD + 5位序号 (例如: D25121200000)
|
||||
// 去掉 "D" 前缀后得到 11 位数字,作为全局唯一的 userId
|
||||
// 这样可以避免依赖 identity-service 的临时 userId (可能是 0)
|
||||
const userIdFromSequence = BigInt(payload.accountSequence.substring(1)); // 去掉 "D" 前缀
|
||||
|
||||
const command = new CreateReferralRelationshipCommand(
|
||||
BigInt(payload.userId), // 使用 userId
|
||||
payload.accountSequence, // 现在是字符串格式
|
||||
userIdFromSequence, // 使用从 accountSequence 提取的数值作为 userId
|
||||
payload.accountSequence, // 完整的 accountSequence 字符串
|
||||
null, // referrerCode - 不通过推荐码查找
|
||||
payload.inviterSequence, // 通过 accountSequence 查找推荐人,现在是字符串格式
|
||||
payload.inviterSequence, // 通过 accountSequence 查找推荐人
|
||||
);
|
||||
|
||||
const result = await this.referralService.createReferralRelationship(command);
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
-- Add account_sequence column to reward_ledger_entries
|
||||
ALTER TABLE "reward_ledger_entries" ADD COLUMN "account_sequence" BIGINT;
|
||||
ALTER TABLE "reward_ledger_entries" ADD COLUMN "account_sequence" VARCHAR(20);
|
||||
|
||||
-- Add indexes for account_sequence on reward_ledger_entries
|
||||
CREATE INDEX "idx_account_status" ON "reward_ledger_entries"("account_sequence", "reward_status");
|
||||
CREATE INDEX "idx_account_created" ON "reward_ledger_entries"("account_sequence", "created_at" DESC);
|
||||
|
||||
-- Add account_sequence column to reward_summaries
|
||||
ALTER TABLE "reward_summaries" ADD COLUMN "account_sequence" BIGINT;
|
||||
ALTER TABLE "reward_summaries" ADD COLUMN "account_sequence" VARCHAR(20);
|
||||
|
||||
-- Add unique constraint and index for account_sequence on reward_summaries
|
||||
CREATE UNIQUE INDEX "reward_summaries_account_sequence_key" ON "reward_summaries"("account_sequence");
|
||||
CREATE INDEX "idx_summary_account" ON "reward_summaries"("account_sequence");
|
||||
|
||||
-- Add account_sequence column to settlement_records
|
||||
ALTER TABLE "settlement_records" ADD COLUMN "account_sequence" BIGINT;
|
||||
ALTER TABLE "settlement_records" ADD COLUMN "account_sequence" VARCHAR(20);
|
||||
|
||||
-- Add index for account_sequence on settlement_records
|
||||
CREATE INDEX "idx_settlement_account" ON "settlement_records"("account_sequence");
|
||||
|
|
|
|||
Loading…
Reference in New Issue