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
|
-- Step 1: Add account_sequence columns to all tables first
|
||||||
ALTER TABLE "authorization_roles" ADD COLUMN "account_sequence" BIGINT;
|
ALTER TABLE "authorization_roles" ADD COLUMN "account_sequence" TEXT;
|
||||||
ALTER TABLE "monthly_assessments" ADD COLUMN "account_sequence" BIGINT;
|
ALTER TABLE "monthly_assessments" ADD COLUMN "account_sequence" TEXT;
|
||||||
ALTER TABLE "monthly_bypasses" ADD COLUMN "account_sequence" BIGINT;
|
ALTER TABLE "monthly_bypasses" ADD COLUMN "account_sequence" TEXT;
|
||||||
ALTER TABLE "stickman_rankings" ADD COLUMN "account_sequence" BIGINT;
|
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)
|
-- 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 "authorization_roles" SET "account_sequence" = "user_id" WHERE "account_sequence" IS NULL;
|
||||||
UPDATE "monthly_assessments" SET "account_sequence" = CAST("user_id" AS BIGINT) WHERE "account_sequence" IS NULL;
|
UPDATE "monthly_assessments" SET "account_sequence" = "user_id" WHERE "account_sequence" IS NULL;
|
||||||
UPDATE "monthly_bypasses" SET "account_sequence" = CAST("user_id" AS BIGINT) WHERE "account_sequence" IS NULL;
|
UPDATE "monthly_bypasses" SET "account_sequence" = "user_id" WHERE "account_sequence" IS NULL;
|
||||||
UPDATE "stickman_rankings" SET "account_sequence" = CAST("user_id" AS BIGINT) 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
|
-- Step 3: Make account_sequence NOT NULL
|
||||||
ALTER TABLE "authorization_roles" ALTER COLUMN "account_sequence" SET NOT NULL;
|
ALTER TABLE "authorization_roles" ALTER COLUMN "account_sequence" SET NOT NULL;
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ services:
|
||||||
- DATABASE_URL=postgresql://rwa_user:rwa_secure_password@rwa-postgres:5432/rwa_backup?schema=public
|
- DATABASE_URL=postgresql://rwa_user:rwa_secure_password@rwa-postgres:5432/rwa_backup?schema=public
|
||||||
# Service Authentication
|
# Service Authentication
|
||||||
- SERVICE_JWT_SECRET=${SERVICE_JWT_SECRET:-your-service-jwt-secret}
|
- SERVICE_JWT_SECRET=${SERVICE_JWT_SECRET:-your-service-jwt-secret}
|
||||||
- ALLOWED_SERVICES=identity-service,recovery-service
|
- ALLOWED_SERVICES=identity-service,recovery-service,mpc-service
|
||||||
# Backup Encryption
|
# Backup Encryption
|
||||||
- BACKUP_ENCRYPTION_KEY=${BACKUP_ENCRYPTION_KEY:-0123456789abcdef0123456789abcdef}
|
- BACKUP_ENCRYPTION_KEY=${BACKUP_ENCRYPTION_KEY:-0123456789abcdef0123456789abcdef}
|
||||||
- BACKUP_ENCRYPTION_KEY_ID=${BACKUP_ENCRYPTION_KEY_ID:-key-v1}
|
- BACKUP_ENCRYPTION_KEY_ID=${BACKUP_ENCRYPTION_KEY_ID:-key-v1}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
CREATE TABLE "backup_shares" (
|
CREATE TABLE "backup_shares" (
|
||||||
"share_id" BIGSERIAL NOT NULL,
|
"share_id" BIGSERIAL NOT NULL,
|
||||||
"user_id" BIGINT NOT NULL,
|
"user_id" BIGINT NOT NULL,
|
||||||
"account_sequence" BIGINT NOT NULL,
|
"account_sequence" VARCHAR(12) NOT NULL,
|
||||||
"public_key" VARCHAR(130) NOT NULL,
|
"public_key" VARCHAR(130) NOT NULL,
|
||||||
"party_index" INTEGER NOT NULL DEFAULT 2,
|
"party_index" INTEGER NOT NULL DEFAULT 2,
|
||||||
"threshold" INTEGER NOT NULL DEFAULT 2,
|
"threshold" INTEGER NOT NULL DEFAULT 2,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ model BackupShare {
|
||||||
|
|
||||||
// 用户标识 (来自 identity-service)
|
// 用户标识 (来自 identity-service)
|
||||||
userId BigInt @unique @map("user_id")
|
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 密钥信息
|
// MPC 密钥信息
|
||||||
publicKey String @unique @map("public_key") @db.VarChar(130)
|
publicKey String @unique @map("public_key") @db.VarChar(130)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
-- AlterTable: monitored_addresses
|
-- AlterTable: monitored_addresses
|
||||||
-- Add new columns for system accounts and account_sequence
|
-- 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 "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_type" VARCHAR(50);
|
||||||
ALTER TABLE "monitored_addresses" ADD COLUMN "system_account_id" BIGINT;
|
ALTER TABLE "monitored_addresses" ADD COLUMN "system_account_id" BIGINT;
|
||||||
ALTER TABLE "monitored_addresses" ADD COLUMN "region_code" VARCHAR(10);
|
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
|
-- AlterTable: deposit_transactions
|
||||||
-- Add new columns for system accounts and account_sequence
|
-- 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 "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_type" VARCHAR(50);
|
||||||
ALTER TABLE "deposit_transactions" ADD COLUMN "system_account_id" BIGINT;
|
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
|
-- CreateTable: recovery_mnemonics
|
||||||
CREATE TABLE "recovery_mnemonics" (
|
CREATE TABLE "recovery_mnemonics" (
|
||||||
"id" BIGSERIAL NOT NULL,
|
"id" BIGSERIAL NOT NULL,
|
||||||
"account_sequence" INTEGER NOT NULL,
|
"account_sequence" VARCHAR(20) NOT NULL,
|
||||||
"public_key" VARCHAR(130) NOT NULL,
|
"public_key" VARCHAR(130) NOT NULL,
|
||||||
"encrypted_mnemonic" TEXT NOT NULL,
|
"encrypted_mnemonic" TEXT NOT NULL,
|
||||||
"mnemonic_hash" VARCHAR(64) NOT NULL,
|
"mnemonic_hash" VARCHAR(64) NOT NULL,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "user_accounts" (
|
CREATE TABLE "user_accounts" (
|
||||||
"user_id" BIGSERIAL NOT NULL,
|
"user_id" BIGSERIAL NOT NULL,
|
||||||
"account_sequence" BIGINT NOT NULL,
|
"account_sequence" VARCHAR(12) NOT NULL,
|
||||||
"phone_number" VARCHAR(20),
|
"phone_number" VARCHAR(20),
|
||||||
"nickname" VARCHAR(100) NOT NULL,
|
"nickname" VARCHAR(100) NOT NULL,
|
||||||
"avatar_url" TEXT,
|
"avatar_url" TEXT,
|
||||||
"inviter_sequence" BIGINT,
|
"inviter_sequence" VARCHAR(12),
|
||||||
"referral_code" VARCHAR(10) NOT NULL,
|
"referral_code" VARCHAR(10) NOT NULL,
|
||||||
"kyc_status" VARCHAR(20) NOT NULL DEFAULT 'NOT_VERIFIED',
|
"kyc_status" VARCHAR(20) NOT NULL DEFAULT 'NOT_VERIFIED',
|
||||||
"real_name" VARCHAR(100),
|
"real_name" VARCHAR(100),
|
||||||
|
|
@ -61,13 +61,17 @@ CREATE TABLE "wallet_addresses" (
|
||||||
|
|
||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "account_sequence_generator" (
|
CREATE TABLE "account_sequence_generator" (
|
||||||
"id" INTEGER NOT NULL DEFAULT 1,
|
"id" SERIAL NOT NULL,
|
||||||
"current_sequence" BIGINT NOT NULL DEFAULT 0,
|
"date_key" VARCHAR(6) NOT NULL,
|
||||||
|
"current_sequence" INTEGER NOT NULL DEFAULT 0,
|
||||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
CONSTRAINT "account_sequence_generator_pkey" PRIMARY KEY ("id")
|
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
|
-- CreateTable
|
||||||
CREATE TABLE "user_events" (
|
CREATE TABLE "user_events" (
|
||||||
"event_id" BIGSERIAL NOT NULL,
|
"event_id" BIGSERIAL NOT NULL,
|
||||||
|
|
@ -346,7 +350,3 @@ ALTER TABLE "user_devices" ADD CONSTRAINT "user_devices_user_id_fkey" FOREIGN KE
|
||||||
-- AddForeignKey
|
-- 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;
|
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;
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,10 @@ services:
|
||||||
MPC_COORDINATOR_TIMEOUT: 30000
|
MPC_COORDINATOR_TIMEOUT: 30000
|
||||||
# Share Encryption
|
# Share Encryption
|
||||||
SHARE_MASTER_KEY: ${SHARE_MASTER_KEY:-0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef}
|
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
|
# Timeouts
|
||||||
MPC_KEYGEN_TIMEOUT: 300000
|
MPC_KEYGEN_TIMEOUT: 300000
|
||||||
MPC_SIGNING_TIMEOUT: 180000
|
MPC_SIGNING_TIMEOUT: 180000
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
CREATE TABLE "referral_relationships" (
|
CREATE TABLE "referral_relationships" (
|
||||||
"relationship_id" BIGSERIAL NOT NULL,
|
"relationship_id" BIGSERIAL NOT NULL,
|
||||||
"user_id" BIGINT NOT NULL,
|
"user_id" BIGINT NOT NULL,
|
||||||
"account_sequence" INTEGER NOT NULL,
|
"account_sequence" VARCHAR(12) NOT NULL,
|
||||||
"referrer_id" BIGINT,
|
"referrer_id" BIGINT,
|
||||||
"root_user_id" BIGINT,
|
"root_user_id" BIGINT,
|
||||||
"my_referral_code" VARCHAR(20) NOT NULL,
|
"my_referral_code" VARCHAR(20) NOT NULL,
|
||||||
|
|
@ -48,7 +48,7 @@ CREATE TABLE "direct_referrals" (
|
||||||
"direct_referral_id" BIGSERIAL NOT NULL,
|
"direct_referral_id" BIGSERIAL NOT NULL,
|
||||||
"referrer_id" BIGINT NOT NULL,
|
"referrer_id" BIGINT NOT NULL,
|
||||||
"referral_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_nickname" VARCHAR(100),
|
||||||
"referral_avatar" VARCHAR(255),
|
"referral_avatar" VARCHAR(255),
|
||||||
"personal_planting_count" INTEGER NOT NULL DEFAULT 0,
|
"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}`,
|
`Processing ${event.eventType} event: accountSequence=${payload.accountSequence}, inviterSequence=${payload.inviterSequence}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// 使用 accountSequence 作为 userId,因为 identity-service 的 userId 是内部自增ID,
|
// 从 accountSequence 提取数值部分作为 userId
|
||||||
// 在事件发布时可能还是临时值 0,而 accountSequence 是全局唯一的业务标识
|
// accountSequence 格式: D + YYMMDD + 5位序号 (例如: D25121200000)
|
||||||
// 注意:userId 仍然需要是 bigint,这里我们需要从 accountSequence 字符串中提取数值部分或使用其他方式
|
// 去掉 "D" 前缀后得到 11 位数字,作为全局唯一的 userId
|
||||||
// 暂时保持原有逻辑,但 accountSequence 本身现在是字符串类型
|
// 这样可以避免依赖 identity-service 的临时 userId (可能是 0)
|
||||||
|
const userIdFromSequence = BigInt(payload.accountSequence.substring(1)); // 去掉 "D" 前缀
|
||||||
|
|
||||||
const command = new CreateReferralRelationshipCommand(
|
const command = new CreateReferralRelationshipCommand(
|
||||||
BigInt(payload.userId), // 使用 userId
|
userIdFromSequence, // 使用从 accountSequence 提取的数值作为 userId
|
||||||
payload.accountSequence, // 现在是字符串格式
|
payload.accountSequence, // 完整的 accountSequence 字符串
|
||||||
null, // referrerCode - 不通过推荐码查找
|
null, // referrerCode - 不通过推荐码查找
|
||||||
payload.inviterSequence, // 通过 accountSequence 查找推荐人,现在是字符串格式
|
payload.inviterSequence, // 通过 accountSequence 查找推荐人
|
||||||
);
|
);
|
||||||
|
|
||||||
const result = await this.referralService.createReferralRelationship(command);
|
const result = await this.referralService.createReferralRelationship(command);
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,19 @@
|
||||||
-- Add account_sequence column to reward_ledger_entries
|
-- 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
|
-- 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_status" ON "reward_ledger_entries"("account_sequence", "reward_status");
|
||||||
CREATE INDEX "idx_account_created" ON "reward_ledger_entries"("account_sequence", "created_at" DESC);
|
CREATE INDEX "idx_account_created" ON "reward_ledger_entries"("account_sequence", "created_at" DESC);
|
||||||
|
|
||||||
-- Add account_sequence column to reward_summaries
|
-- 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
|
-- 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 UNIQUE INDEX "reward_summaries_account_sequence_key" ON "reward_summaries"("account_sequence");
|
||||||
CREATE INDEX "idx_summary_account" ON "reward_summaries"("account_sequence");
|
CREATE INDEX "idx_summary_account" ON "reward_summaries"("account_sequence");
|
||||||
|
|
||||||
-- Add account_sequence column to settlement_records
|
-- 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
|
-- Add index for account_sequence on settlement_records
|
||||||
CREATE INDEX "idx_settlement_account" ON "settlement_records"("account_sequence");
|
CREATE INDEX "idx_settlement_account" ON "settlement_records"("account_sequence");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue