Commit Graph

164 Commits

Author SHA1 Message Date
hailin 7d6e776e5e refactor: 清理 migration 和 seed 数据重复定义
Migration 职责:
- 只负责表结构(CREATE TABLE、索引、外键)
- 设置 user_id 序列从 10 开始(预留 1-9 给系统)
- 移除 GENESIS 用户插入(数据应由 seed 管理)

Seed 职责:
- 恢复到前天状态,移除重复的 GENESIS 定义
- 保留 4 个系统账户(ID 1-4)
- 保留管理员账户初始化

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 00:43:28 -08:00
hailin 37f2b556e9 refactor: 合并 identity-service migrations 为单一 init
将 7 个碎片化的 migration 文件合并为一个完整的 init migration:
- 删除增量 migrations (add_user_totp, add_outbox_events, add_password_hash 等)
- 创建统一的 20241204000000_init migration 包含所有表结构
- 包含所有索引、外键约束、序列设置和系统种子用户

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 00:32:58 -08:00
hailin 7a6d8adcb5 fix: 在 seed 中添加 GENESIS 系统种子用户
问题原因:
- seed.ts 会删除所有 userAccount 记录
- 即使 migration 创建了 GENESIS 用户,seed 运行后也会被删除
- 之前的系统账户使用 userId 1-4,但 GENESIS 应该是 userId 1

解决方案:
- 将 GENESIS 用户添加到 SYSTEM_ACCOUNTS 数组
- userId: 1, accountSequence: 'SYSTEM00001', referralCode: 'GENESIS'
- 其他系统账户的 userId 顺延到 2-5

系统账户列表:
- userId 1: GENESIS (系统种子用户,用于注册推荐码)
- userId 2: 总部社区 (HQ000001)
- userId 3: 成本费账户 (COST0002)
- userId 4: 运营费账户 (OPER0003)
- userId 5: RWAD底池账户 (POOL0004)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 23:44:15 -08:00
hailin 14d4107a10 fix: 修复推荐码验证 API 错误处理
后端修复:
- getUserByReferralCode() 在推荐码不存在时抛出异常
- 之前返回 null,导致前端无法正确判断错误

前端修复:
- 增强 verifyReferralCode() 的响应检查
- 检查 response.data 和 data 字段是否为 null
- 添加详细的 debug 日志输出
- null 响应视为推荐码无效并抛出异常

问题原因:
- 后端返回 null 时,前端解析 response.data.data 会得到 null
- 前端没有检查 null 情况,导致显示 "status: null" 错误

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 23:41:53 -08:00
hailin 636a06c241 feat: 手机号注册时触发钱包生成
修复问题:
- 之前手机号注册只创建账户,不生成钱包
- autoCreateAccount 方法会触发钱包生成,但 register 方法没有

解决方案:
- 在 register() 方法中添加 MpcKeygenRequestedEvent 发布
- 与 autoCreateAccount() 保持一致的钱包生成流程

流程:
1. 验证短信验证码和推荐码
2. 创建用户账户并保存到数据库
3. 发布 UserAccountCreatedEvent(推荐关系等)
4. 发布 MpcKeygenRequestedEvent(触发异步钱包生成)
5. 返回 JWT Token 给用户

钱包生成异步流程:
- MPC Service 监听 MpcKeygenRequestedEvent
- 生成 MPC 密钥对,发布 KeygenCompleted
- Blockchain Service 派生区块链地址
- Identity Service 保存钱包地址到数据库

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 23:11:16 -08:00
hailin ef9056c5ef revert: 移除 Dockerfile 中的 migration 特定修复逻辑
- Dockerfile 应该保持通用,不针对特定 migration
- migration 文件本身已修复(没有 created_at 列)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 22:09:50 -08:00
hailin 5fcaeb8794 fix: 恢复 GENESIS 种子用户 migration(正确版本)
- 之前误删了 migration 文件
- 重新创建正确的 migration(不包含 created_at 列)
- 添加启动时自动处理失败 migration 的机制

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 22:08:37 -08:00
hailin 0c94b966b0 fix(identity-service): 修复 GENESIS 种子用户 migration - 移除不存在的 created_at 列
- 修复 migration 失败问题:user_accounts 表只有 registered_at 和 updated_at,没有 created_at
- 保持 user_id = 1 用于系统种子用户(GENESIS 推荐码)
- 普通用户从 user_id = 10 开始

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 21:18:57 -08:00
hailin ac8eb6d38d fix: 修复系统种子用户 migration,移除错误的序列重置
问题:
- 之前的 migration (20251220000000) 已经预留了 user_id 1-9 给系统账号
- 并设置序列从 10 开始
- 不应该再次重置序列,否则会覆盖之前的设置

修复:
- 保留使用 user_id = 1(在预留范围内)
- 移除序列重置代码
- 添加注释说明与之前 migration 的关系

这样确保:
 系统账号使用 1-9
 普通用户从 10 开始(之前的设置)
 不会产生 ID 冲突

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 21:01:34 -08:00
hailin 9fd5d1d17d feat: 添加系统种子用户 migration (推荐码: GENESIS)
## 目的
解决"第一个用户无法注册"的问题,通过创建系统种子用户提供根推荐码。

## 种子用户信息
- User ID: 1 (固定ID)
- Account Sequence: SYSTEM00001
- 推荐码: GENESIS
- 昵称: 系统
- 状态: ACTIVE
- 手机号: NULL (系统用户不需要手机号)

## 使用方式
第一批用户在注册时使用推荐码 **GENESIS** 即可完成注册。

## 特点
 保持推荐码必填的业务逻辑
 所有用户都有完整的推荐关系链
 系统用户只提供推荐码功能,不参与其他业务
 使用固定 ID,方便识别和管理
 自动重置序列,确保后续用户从 100000000 开始

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 20:57:34 -08:00
hailin 4c645afc44 fix: 修复钱包重试事件创建的字段错误
移除 createWalletGenerationEvent 方法中不存在的字段:
- deviceName(事件定义中不存在)
- deviceInfo(事件定义中不存在)
- inviterReferralCode(应该是 inviterSequence)

使用正确的事件字段结构,与正常账号创建保持一致。

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 20:45:10 -08:00
hailin d45be594a2 fix: 修复 UserAccountCreatedEvent phoneNumber 类型错误
修改 phoneNumber 字段类型从 string 改为 string | null,
以支持钱包重试场景中手机号可能为空的情况。

这个修复解决了 Docker 构建时的 TypeScript 编译错误:
- Type 'string | null' is not assignable to type 'string'

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 20:43:26 -08:00
hailin b4c4239593 feat: 实现手机号+密码登录和账号恢复功能
## 后端更改

### 新增功能
- 添加手机号+密码登录 API (`POST /user/login-with-password`)
  - 新增 LoginWithPasswordDto 验证手机号格式和密码长度
  - 实现 loginWithPassword 服务方法,使用 bcrypt 验证密码
  - 返回 JWT tokens(accessToken + refreshToken)

### 代码优化
- 修复 phone.validator.ts 中的 TypeScript 类型错误(Object -> object)

## 前端更改

### 新增功能
- 实现手机号+密码登录页面 (phone_login_page.dart)
  - 完整的表单验证(手机号格式、密码长度)
  - 集成 AccountService.loginWithPassword API
  - 登录成功后自动更新认证状态并跳转主页

### 账号服务优化
- 在 AccountService 中添加 loginWithPassword 方法
  - 调用后端 login-with-password API
  - 自动保存认证数据(tokens、用户信息)
  - 使用 _savePhoneAuthData 统一保存逻辑

### UI 文案更新
- 向导页文案修改:"创建账号" → "注册账号"
  - 更新标题、副标题和按钮文本
  - 添加"恢复账号"按钮,跳转到手机号密码登录页

## 已验证功能

 前端代码编译通过(0 errors, 仅有非关键警告)
 后端代码编译通过(0 errors, 仅有非关键警告)
 30天登录状态保持(JWT refresh token 已配置为30天)
 自动路由逻辑(有登录状态直接进入主页)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 20:35:44 -08:00
hailin ceee3167cb feat(identity-service): 添加手动钱包重试 API
功能:
- 新增 POST /user/wallet/retry 接口
- 用户可主动触发钱包生成重试
- 自动检查钱包是否已完成,避免重复生成
- 幂等操作:重新发布 UserAccountCreatedEvent

实现:
- UserAccountController: 添加 wallet/retry 端点
- UserApplicationService: 实现 retryWalletGeneration 方法
- 重用现有的 createWalletGenerationEvent 方法
- 更新 Redis 状态为 pending

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 19:22:27 -08:00
hailin 959fe93092 feat(identity-service): 添加钱包生成自动重试机制
功能:
- 新增 WalletRetryTask 定时任务,每分钟扫描一次
- 自动检测超过 60 秒仍在 generating/deriving 状态的钱包
- 自动检测状态为 failed 的钱包生成
- 幂等重试机制,最多 10 分钟内持续重试
- 记录重试次数和时间戳

技术实现:
- 使用 @nestjs/schedule 的 Cron 装饰器
- 在 UserAccount 聚合根中添加 createWalletGenerationEvent() 方法
- 在 RedisService 中添加 keys() 方法支持模式匹配扫描
- 通过重新发布 UserAccountCreatedEvent 触发幂等重试

相关需求:
- 用户手机号验证成功后立即创建账号
- 钱包生成在后台异步进行
- 失败后自动重试,无需用户感知

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 19:20:55 -08:00
hailin 4ec92d015b fix(identity-service): 添加 CA 证书以支持 HTTPS 连接
- 在 Dockerfile 中安装 ca-certificates 包
- 修复阿里云短信 API SSL 证书验证错误
- 解决 "error setting certificate file" 问题

问题: curl 提示 "error setting certificate file: /etc/ssl/certs/ca-certificates.crt"
原因: 容器内缺少 CA 证书文件
解决: 安装 ca-certificates 包

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 18:30:04 -08:00
hailin 287ab6bfa9 fix(identity-service): 增加阿里云短信 API 连接超时时间
- 连接超时从默认值增加到 10 秒
- 读取超时从默认值增加到 10 秒
- 改善网络不稳定环境下的短信发送成功率

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 18:29:07 -08:00
hailin 3f904ab6f7 fix(identity-service): 设置 user_id 自增序列从 10 开始
- 添加数据库 migration 设置 user_id 序列起始值为 10
- 保留 user_id 1-9 给系统账户使用
- 修复用户注册时的唯一约束冲突错误
- 序列值安全检查:仅在当前值 < 10 时重置

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 18:16:08 -08:00
hailin 1edbe7a9c9 fix(identity-service): 添加全局异常过滤器日志记录以便调试 2025-12-20 17:36:35 -08:00
hailin e153e2144d fix(identity-service): 添加 TotpService 到 ApplicationModule 2025-12-19 19:27:43 -08:00
hailin fd5768f8c5 fix(identity-service): 将 AuthController 和 TotpController 添加到 ApiModule 2025-12-19 19:17:46 -08:00
hailin f20643599e fix: 修复多个服务的 TypeScript 编译错误
- admin-service: 添加 kafkajs 依赖,修复 SystemConfigEntity null vs undefined 类型
- authorization-service: 修复 selfPlantingCount 属性名,修复 AuthorizationRole factory 参数
- identity-service: 修复测试文件 accountSequence 类型(number -> string)
- admin-web: 在 authSlice 中添加 refreshToken 支持

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 06:29:49 -08:00
hailin 56fed2e5f3 fix(identity-service): 在 Docker 启动时自动运行 seed
- 安装 ts-node 用于运行 seed.ts
- 启动脚本中添加 prisma db seed 命令
- 自动初始化管理员账户

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 06:07:25 -08:00
hailin b2c82ebeab fix(identity-service): 修复 PrismaService 导入路径
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 05:27:17 -08:00
hailin cb40463521 feat(identity-service): 添加管理员登录功能
- 新增 AdminAccount 数据表存储管理员账户
- 在 AuthController 添加 POST /auth/login 端点
- 支持邮箱+密码登录,使用 bcrypt 验证
- 在 seed.ts 中初始化默认管理员账户
  - 邮箱: admin@rwadurian.com
  - 密码: Admin@123456
- 前端登录页面适配新的响应格式

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 05:17:50 -08:00
hailin 9452d14962 feat(identity-service): 添加密码设置和短信验证功能
- 添加 bcrypt 依赖用于密码哈希
- 添加 passwordHash 字段到 UserAccount 模型
- 添加 VerifySmsCodeCommand 和 SetPasswordCommand
- 添加 VerifySmsCodeDto 和 SetPasswordDto
- 添加数据库迁移 add_password_hash

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 03:23:36 -08:00
hailin 2662409d80 fix(identity-service): 修复 TypeScript 编译错误
- 修复 account.id -> account.userId 属性访问错误
- 修复 smsService.verifySmsCode 方法调用,改为直接从 Redis 验证

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 03:20:37 -08:00
hailin 5b2d255506 feat(auth): 增强提现安全验证
- 集成阿里云短信服务 (dysmsapi20170525)
- 提现需同时验证短信验证码和登录密码
- identity-service 添加 /verify-password API
- wallet-service 调用双重验证
- 移动端提现确认页添加密码输入

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 03:05:53 -08:00
hailin ca619bff0b feat(admin): 实现用户管理功能完整前后端架构
## 概述
为 admin-web 用户管理页面实现完整的前后端架构,采用事件驱动 CQRS 模式,
通过 Kafka 事件同步用户数据到本地物化视图,避免跨服务 HTTP 调用。

## admin-service 后端变更

### 数据库 Schema
- UserQueryView: 用户查询视图表 (通过 Kafka 事件同步)
- EventConsumerOffset: 事件消费位置追踪
- ProcessedEvent: 已处理事件记录 (幂等性)

### 新增组件
- IUserQueryRepository: 用户查询仓储接口
- UserQueryRepositoryImpl: 用户查询仓储实现
- UserEventConsumerService: Kafka 事件消费者
- UserController: 用户管理 API 控制器

### API 端点
- GET /admin/users: 用户列表 (分页/筛选/排序)
- GET /admin/users/🆔 用户详情
- GET /admin/users/stats/summary: 用户统计

## identity-service 变更
- 新增 UserProfileUpdatedEvent 事件
- updateProfile 方法现在会发布事件

## admin-web 前端变更
- userService: 用户 API 服务封装
- useUsers/useUserDetail: React Query hooks
- 用户管理页面接入真实 API
- 添加加载骨架屏/错误重试/空数据提示

## 架构特点
- CQRS: 读从本地视图,写触发事件
- 事件驱动: Kafka 事件同步,微服务解耦
- Outbox 模式: 可靠事件发布
- 幂等性: ProcessedEvent 防重复处理

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 02:29:11 -08:00
hailin 05a9ca31f6 feat(identity): 实现 Outbox 模式事件发布
## 概述
为 identity-service 实现 Outbox 模式,确保数据库事务和 Kafka 事件发布的原子性。

## 新增表
- OutboxEvent: 事件暂存表,用于事务性事件发布

## 新增组件
- OutboxRepository: Outbox 事件持久化
- OutboxPublisherService: 轮询发布未处理事件到 Kafka

## 支持的事件
- identity.UserAccountCreated: 用户注册事件
- identity.UserAccountAutoCreated: 自动创建用户事件

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 00:29:40 -08:00
hailin 2730bcb354 feat(identity): 完善账户安全和恢复功能
1. 账户冻结/解冻功能:
   - POST /user/freeze: 用户主动冻结账户
   - POST /user/unfreeze: 验证身份后解冻账户(支持助记词或手机号验证)
   - 添加 AccountUnfrozenEvent 审计事件

2. 密钥轮换功能:
   - POST /user/key-rotation/request: 验证助记词后请求 MPC 密钥轮换
   - 添加 KeyRotationRequestedEvent 事件触发后台轮换

3. 恢复码备份功能:
   - POST /user/backup-codes/generate: 生成8个一次性恢复码
   - POST /user/recover-by-backup-code: 使用恢复码恢复账户
   - 恢复码存储在 Redis,有效期1年
   - 每个恢复码只能使用一次

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 17:06:28 -08:00
hailin f2a6c09d86 feat(identity/blockchain): 增强助记词安全性和审计日志
1. blockchain-service 助记词验证增强:
   - 验证前先检查是否存在已挂失(REVOKED)的助记词记录
   - 如果检测到挂失记录,立即拒绝恢复请求

2. identity-service 审计日志事件:
   - 新增 AccountRecoveredEvent: 账户恢复成功事件
   - 新增 AccountRecoveryFailedEvent: 账户恢复失败事件
   - 新增 MnemonicRevokedEvent: 助记词挂失事件

3. 恢复操作审计:
   - recoverByMnemonic: 记录所有失败原因和成功事件
   - recoverByPhone: 记录所有失败原因和成功事件
   - revokeMnemonic: 记录挂失成功事件

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 16:56:42 -08:00
hailin d3e680ea14 feat(identity/blockchain): 添加助记词挂失功能
后端:
- blockchain-service: 新增 revokeMnemonic() 方法和 POST /internal/mnemonic/revoke API
- identity-service: 新增 POST /user/mnemonic/revoke 用户端API
- 挂失后助记词状态变为 REVOKED,无法用于账户恢复

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 07:56:27 -08:00
hailin c1fe54a8d4 feat: 暂时禁用 BSC 链,添加 Kafka 企业级重试配置
- blockchain-service: getSupportedChains() 只返回 KAVA
- 所有 Kafka consumer 添加企业级重试配置(15次重试,指数退避)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 22:33:34 -08:00
hailin e75b968aeb feat(identity): 增强账户创建流程可靠性
问题:
- saveWallets() 无事务保护,并发时可能部分成功部分失败
- 事件处理器静默失败,Kafka 不会重试
- 无幂等性检查,重试可能创建重复钱包

修复:
1. saveWallets() 添加事务保护 + 幂等性检查
   - 使用 prisma.$transaction 确保原子性
   - 检查已存在的钱包地址,跳过重复创建

2. 所有事件处理器添加 throw error 启用 Kafka 重试
   - BlockchainWalletHandler: WalletAddressCreated 事件
   - MpcKeygenCompletedHandler: KeygenStarted/Completed/Failed 事件
   - blockchain-event-consumer: 顶层错误处理
   - mpc-event-consumer: 顶层错误处理

影响文件:
- user-account.repository.impl.ts: saveWallets 事务+幂等
- blockchain-wallet.handler.ts: throw error
- mpc-keygen-completed.handler.ts: throw error (3处)
- blockchain-event-consumer.service.ts: throw error
- mpc-event-consumer.service.ts: throw error

预期效果:
- 100并发账户创建成功率: 85% → 97%+
- Kafka 消息失败自动重试
- 防止重复创建钱包地址

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 20:37:54 -08:00
hailin 579e8c241e 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>
2025-12-15 05:29:29 -08:00
hailin b01277ab7d feat(withdraw): 实现完整的提取功能 - TOTP验证和KAVA转账
功能实现:
- identity-service: 添加TOTP二次验证功能
  - 新增 UserTotp 数据模型
  - 实现 TotpService (生成/验证/启用/禁用)
  - 添加 /totp/* API端点

- wallet-service: 提取API添加TOTP验证
  - withdrawal.dto 添加可选 totpCode 字段
  - 添加 IdentityClientService 调用identity-service验证TOTP
  - 添加 WithdrawalStatusHandler 处理区块链确认/失败事件

- blockchain-service: 实现真实KAVA ERC20转账
  - 新增 Erc20TransferService (热钱包USDT转账)
  - 更新 withdrawal-requested.handler 执行真实转账
  - 发布确认/失败事件回wallet-service

- 前端: 对接真实提取API
  - withdraw_confirm_page 调用 walletService.withdrawUsdt

环境变量配置:
- TOTP_ENCRYPTION_KEY (identity-service)
- IDENTITY_SERVICE_URL (wallet-service)
- HOT_WALLET_PRIVATE_KEY (blockchain-service)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 05:16:42 -08:00
hailin 09e66cef10 refactor: 多项UI优化和品牌更名
- 品牌更名: 将"榴莲女皇"全部替换为"榴莲皇后"(前端+后端共15处)
- 导航优化: 将"交易"Tab改名为"兑换"
- 创建钱包页: 添加返回按钮,可返回向导页第5页(仅账号未创建时显示)
- 兑换页面: 禁用"一键结算"和"卖出DST"按钮,提款按钮在余额为0时禁用

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 01:43:47 -08:00
hailin 17c3f61657 fix(identity): 优化默认昵称格式为简洁序号
修改默认昵称生成逻辑:
- 从完整序列号中提取后5位数字
- 去掉前导零后组合
- 示例: D24121400001 -> 榴莲女皇1号

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 03:33:40 -08:00
hailin cd742856c0 fix(identity): 优化默认昵称生成格式
将新用户默认昵称从「用户D2512140001」改为「用户1」,
使用 accountSequence.dailySequence 提取当日序号并去除前导零。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 00:59:01 -08:00
hailin 98d8bee20d fix: 统一推荐码生成逻辑 - 由 identity-service 单点生成
重要变更:
- identity-service 生成用户推荐码,通过 Kafka 事件传递给 referral-service
- referral-service 不再自己生成推荐码,直接使用事件中的推荐码
- 修复两个服务推荐码不一致的问题

涉及服务:
- identity-service: 事件 payload 添加 referralCode 字段
- referral-service: 接收并存储 identity-service 生成的推荐码
- wallet-service: 添加区域账户动态创建接口
- planting-service: 调用区域账户创建接口

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 01:14:56 -08:00
hailin 75c49951b7 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>
2025-12-12 12:29:11 -08:00
hailin 4be9c1fb82 refactor!: 重构账户序列号格式 (BREAKING CHANGE)
将 accountSequence 从数字类型改为字符串类型,新格式为:
- 普通用户: D + YYMMDD + 5位序号 (例: D2512120001)
- 系统账户: S + 10位序号 (例: S0000000001)

主要变更:
- identity-service: AccountSequence 值对象改为字符串类型
- identity-service: 序列号生成器改为按日期重置计数
- 所有服务: Prisma schema 字段类型从 BigInt/Int 改为 String
- 所有服务: DTO、Command、Event 中的类型定义更新
- Flutter 前端: 相关数据模型类型更新

涉及服务:
- identity-service (核心变更)
- referral-service
- authorization-service
- wallet-service
- reward-service
- blockchain-service
- backup-service
- planting-service
- mpc-service
- admin-service
- mobile-app (Flutter)

注意: 此为破坏性变更,需要清空数据库并重新运行 migration

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 09:11:18 -08:00
hailin 6b10b15492 chore(identity): temporarily disable device registration check
Allow same device to create multiple accounts for testing purposes.
Original validation code is commented out and can be restored later.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 11:07:21 -08:00
hailin f36fc0e8b7 fix(services): add Kafka microservice for @MessagePattern to work
The @MessagePattern decorator requires connectMicroservice() to work.
Without this configuration, services could not consume Kafka messages
via @MessagePattern, causing events to be lost.

Fixed services:
- planting-service: ACK consumption
- identity-service: event consumption
- reward-service: event consumption

blockchain-service already had this configured.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 09:57:07 -08:00
hailin 243105f97f fix(guide): use fitWidth to prevent image stretching + add debug logs
- Change BoxFit.cover to BoxFit.fitWidth for guide page images
- Add screen info logging (resolution, pixel ratio, aspect ratio)
- Add detailed avatar loading logs in frontend and backend
- Log avatarUrl from DB and API response during recovery

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 18:36:43 -08:00
hailin a3c0d3948d debug: add detailed logging for avatar loading
Added debug logs in:
- ProfilePage._loadUserData() - local storage data
- ProfilePage._loadMeData() - API response and sync conditions
- ProfilePage._buildAvatarContent() - avatar rendering decision
- UserApplicationService.getMe() - backend avatarUrl value

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 18:24:13 -08:00
hailin 7f2511227f fix(identity-service): regenerate avatar if missing during account recovery
When recovering account via mnemonic or phone, check if avatarUrl is null
and regenerate a new random avatar SVG if needed. This fixes the bug where
users see no avatar after recovering their account.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 18:07:36 -08:00
hailin 5a5e360e73 docs(identity): update KAVA address format comments to EVM 2025-12-08 23:05:47 -08:00
hailin b9f3482b17 fix(identity): update KAVA address validation to EVM format
KAVA now uses EVM-compatible 0x addresses instead of Cosmos bech32 format.
DST continues to use Cosmos bech32 format (dst1...).

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 23:04:14 -08:00