fix(backend): 修复构建错误并添加 TOTP 数据库迁移

修复内容:
- identity-service: 添加 CurrentUserPayload 接口定义
- identity-service: 添加 user_totp 表的数据库迁移文件
- wallet-service: 安装 axios 依赖
- wallet-service: 修复 withdrawal-status.handler.ts 中的类型错误
  - userId.toString() → userId.value (BigInt 类型)
  - unfreezeUsdt() → unfreeze() (正确的方法名)
  - amount.asNumber → amount.value (Money 值对象属性)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-15 05:29:29 -08:00
parent b01277ab7d
commit 579e8c241e
4 changed files with 31 additions and 3 deletions

View File

@ -0,0 +1,21 @@
-- CreateTable: user_totp
-- TOTP 二次验证表,用于提现、转账等敏感操作
CREATE TABLE "user_totp" (
"id" BIGSERIAL NOT NULL,
"user_id" BIGINT NOT NULL,
"encrypted_secret" VARCHAR(100) NOT NULL,
"is_enabled" BOOLEAN NOT NULL DEFAULT false,
"is_verified" BOOLEAN NOT NULL DEFAULT false,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"enabled_at" TIMESTAMP(3),
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "user_totp_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "user_totp_user_id_key" ON "user_totp"("user_id");
-- CreateIndex
CREATE INDEX "idx_totp_user" ON "user_totp"("user_id");

View File

@ -1,6 +1,12 @@
import { createParamDecorator, ExecutionContext, SetMetadata } from '@nestjs/common';
import { IS_PUBLIC_KEY } from '../guards/jwt-auth.guard';
export interface CurrentUserPayload {
userId: string;
accountSequence: string;
deviceId: string;
}
export const CurrentUser = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();

View File

@ -38,6 +38,7 @@
"@nestjs/schedule": "^4.1.2",
"@nestjs/swagger": "^7.1.17",
"@prisma/client": "^5.7.0",
"axios": "^1.13.2",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"decimal.js": "^10.4.3",

View File

@ -103,12 +103,12 @@ export class WithdrawalStatusHandler implements OnModuleInit {
// Refund frozen funds back to available balance if needed
if (order.needsUnfreeze()) {
const wallet = await this.walletRepo.findByUserId(order.userId.toString());
const wallet = await this.walletRepo.findByUserId(order.userId.value);
if (wallet) {
// Unfreeze the amount (add back to available balance)
wallet.unfreezeUsdt(order.amount.asNumber);
wallet.unfreeze(order.amount);
await this.walletRepo.save(wallet);
this.logger.log(`[FAILED] Refunded ${order.amount.asNumber} USDT to user ${order.userId}`);
this.logger.log(`[FAILED] Refunded ${order.amount.value} USDT to user ${order.userId}`);
}
}