Commit Graph

28 Commits

Author SHA1 Message Date
hailin a549768de4 feat(kyc): 实现实名认证和更换手机号功能
主要变更:
- 注册流程: 添加跳过短信验证选项(3分钟后显示)
- KYC功能: 手机号验证 + 身份证实名认证(阿里云二要素)
- 更换手机号: 四步验证流程(旧手机验证→输入新号→新手机验证→确认)
- 独立管控: phoneVerified, emailVerified, kycStatus 三个状态分别管理

后端:
- 新增 KYC 控制器和服务
- 新增更换手机号 API 端点
- Schema 添加 KYC 和验证状态字段
- 集成阿里云身份二要素验证

前端:
- 新增 KYC 入口页、手机验证页、身份证验证页
- 新增更换手机号页面
- Profile 页面添加实名认证入口

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 06:38:39 -08:00
hailin a38aac5581 feat(email): 实现邮箱绑定/解绑功能
后端:
- 新增 EmailService 邮件发送服务,支持 Gmail SMTP
- 新增 EmailCode 数据模型用于存储邮箱验证码
- UserAccount 添加 email 字段
- 新增 API 接口:
  - GET /user/email-status 获取邮箱绑定状态
  - POST /user/send-email-code 发送邮箱验证码
  - POST /user/bind-email 绑定邮箱
  - POST /user/unbind-email 解绑邮箱
- 新增 DTOs: SendEmailCodeDto, BindEmailDto, UnbindEmailDto
- 新增 Commands: SendEmailCodeCommand, BindEmailCommand, UnbindEmailCommand

前端:
- account_service 新增邮箱相关方法和 EmailStatus 类
- bind_email_page 更新为使用真实 API:
  - 绑定/更换邮箱功能
  - 独立的解绑验证码输入和倒计时
  - 解绑确认对话框

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 20:53:20 -08:00
hailin 69fa43ebee feat(auth): 实现修改密码API和Token过期自动跳转登录
后端:
- 新增 ChangePasswordCommand 和 ChangePasswordDto
- 新增 POST /user/change-password 接口
- 实现 changePassword() 方法,验证旧密码后更新新密码

前端:
- 新增 AuthEventService 认证事件服务,处理 token 过期事件
- api_client 在 token 刷新失败时发送过期事件
- App 监听认证事件,token 过期时清除账号状态并跳转登录页
- splash_page 优化路由逻辑:退出登录后跳转手机登录页而非向导页
- change_password_page 调用真实 API 修改密码
- account_service 新增 changePassword() 方法
- multi_account_service 退出登录时清除 phoneNumber 和 isPasswordSet

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 20:25:56 -08:00
hailin cb0f10af34 feat: 多项业务功能增强
- 动态提取手续费配置:支持固定/百分比两种费率类型,默认2绿积分/笔
- 找回密码功能:新增手机号+短信验证码重置密码流程
- 授权申请优化:自助申请时验证团队链授权状态
- UI文案调整:登录账号、监控页待开启等

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 19:00:02 -08:00
hailin 2897a0c74c feat: 添加 register-by-phone API 实现手机号一步注册
- 后端: 添加 POST /user/register-by-phone 接口
  - 验证短信验证码、创建账户、绑定手机号、设置密码、触发钱包生成
  - 添加 RegisterByPhoneCommand 和 RegisterByPhoneDto
- 前端: 修改注册流程使用新 API
  - SmsVerifyPage 直接跳转到密码页面传递验证码
  - SetPasswordPage 调用 registerByPhoneWithPassword 一步完成
  - AccountService 添加 registerByPhoneWithPassword 方法

修复手机号注册流程中手机号和密码未正确保存的问题

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 20:19:46 -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 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 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 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 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 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 5d671bf5ec feat(referral): integrate referral system with identity-service and mobile-app
## Backend Changes

### referral-service
- Add accountSequence field to ReferralRelationship aggregate for cross-service user identification
- Add findByAccountSequence() method to repository interface and implementation
- Update CreateReferralRelationshipCommand to accept accountSequence and inviterAccountSequence
- Modify ReferralService to support looking up inviter by accountSequence
- Update event handler to listen to identity.UserAccountAutoCreated and identity.UserAccountCreated topics
- Add initial database migration with all tables including accountSequence field
- Update DTO and controller to support new parameters

### identity-service
- Add inviterSequence field to MeResult interface
- Update getMe() method to return inviterSequence from user account
- Update MeResponseDto to include inviterSequence field

## Frontend Changes (mobile-app)

### API & Storage
- Add /me endpoint constant in api_endpoints.dart
- Add inviterSequence key in storage_keys.dart
- Add MeResponse and WalletAddressInfo classes in account_service.dart
- Add getMe() method to fetch complete user info including inviter
- Add getInviterSequence() method to retrieve from local storage

### Profile Page
- Update profile_page.dart to load referrer info from API
- Add _loadMeData() method to call getMe() API
- Display inviterSequence (referrer serial number) dynamically

## Flow Summary
1. User creates account with optional inviterReferralCode
2. identity-service validates and saves inviterSequence
3. identity-service publishes UserAccountAutoCreated/UserAccountCreated event
4. referral-service listens and creates referral relationship using inviterAccountSequence
5. Mobile app calls GET /me to display inviter info in profile page

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 22:37:06 -08:00
hailin 78304801f5 feat(identity): change username format to '榴莲女皇x号'
- Replace random username generation with fixed format
- Username now uses accountSequence: '榴莲女皇{序列号}号'
- Keep random durian-themed SVG avatar generation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 20:16:11 -08:00
hailin e95dc4ca57 refactor(mnemonic): move recovery_mnemonics to blockchain-service (DDD)
- Add RecoveryMnemonic model to blockchain-service with accountSequence
- Add MnemonicVerificationService for mnemonic verification logic
- Update verify-mnemonic-hash endpoint to accept accountSequence
- Remove PrismaService dependency from identity-service handler
- identity-service now calls blockchain-service for mnemonic verification

This follows DDD principles: blockchain-service owns all mnemonic-related
data and operations, identity-service only handles account identity.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 00:54:25 -08:00
hailin 0311ecf498 fix(mnemonic): use hash verification instead of address derivation for account recovery
The mnemonic recovery now uses stored hash comparison via blockchain-service
instead of trying to derive addresses from mnemonic (which never matched
because MPC wallet addresses are not derived from mnemonics).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 00:44:47 -08:00
hailin c1670d2439 feat(mnemonic): add recovery mnemonic generation and backup confirmation
Backend (blockchain-service):
- Add RecoveryMnemonicAdapter to generate 12-word BIP39 mnemonic
- Generate mnemonic when wallet addresses are derived (linked to public key)
- Include mnemonic in WalletAddressCreated event

Backend (identity-service):
- Add RecoveryMnemonic table with revocation/replacement support
- Save encrypted mnemonic to database on WalletAddressCreated event
- Add PUT /user/mnemonic/backup API to mark mnemonic as backed up
- Clear plaintext mnemonic from Redis after backup confirmation

Frontend (mobile-app):
- Update markMnemonicBackedUp() to call backend API
- Fix verify_mnemonic_page validation logic:
  - Checkbox checked → pass directly
  - Not checked → must select correct word

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 12:32:10 -08:00
hailin 2705812826 refactor(identity): remove province/city/address fields
- Remove provinceCode, cityCode, address from UserAccount aggregate
- Remove ProvinceCode, CityCode value objects
- Remove UserLocationUpdatedEvent domain event
- Update Prisma schema to drop province/city/address columns
- Update repository, mapper, handlers, services and DTOs
- Clean up tests and factory files

Province/city should belong to adoption-service as transaction data,
not identity-service user data.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 11:23:26 -08:00
hailin fbec0b9112 feat(identity): store complete deviceInfo JSON from frontend
- Add deviceInfo JSON field to UserDevice table (Prisma schema)
- Update DeviceInfo value object to use deviceInfo instead of HardwareInfo
- Update repository to save complete JSON with redundant fields for queries
- Update mapper to read deviceInfo from database
- Update aggregate and handlers to pass deviceInfo through
- Allow any fields in DeviceNameInput interface with index signature

100% preserve original device info JSON from frontend without extraction

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 11:08:37 -08:00
hailin 852073ae11 refactor: move mnemonic verification from identity-service to blockchain-service
- Add /internal/verify-mnemonic API to blockchain-service
- Add /internal/derive-from-mnemonic API to blockchain-service
- Create MnemonicDerivationAdapter for BIP39 mnemonic address derivation
- Create BlockchainClientService in identity-service to call blockchain-service
- Remove WalletGeneratorService from identity-service
- Update recover-by-mnemonic handler to use blockchain-service API

This enforces proper domain boundaries - all blockchain/crypto operations
are now handled by blockchain-service.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 00:11:06 -08:00
hailin 2e815cec6e feat: move address derivation from identity-service to blockchain-service
- Add Cosmos address derivation (bech32) to blockchain-service
  - KAVA: kava1... format
  - DST: dst1... format
  - BSC: 0x... EVM format

- Create MpcEventConsumerService in blockchain-service to consume mpc.KeygenCompleted events

- Create BlockchainEventConsumerService in identity-service to consume blockchain.WalletAddressCreated events

- Simplify identity-service MpcKeygenCompletedHandler to only manage status updates

- Add CosmosAddress value object for Cosmos chain addresses

Event flow:
1. identity-service -> mpc.KeygenRequested
2. mpc-service -> mpc.KeygenCompleted (with publicKey)
3. blockchain-service consumes mpc.KeygenCompleted, derives addresses
4. blockchain-service -> blockchain.WalletAddressCreated (with all chain addresses)
5. identity-service consumes blockchain.WalletAddressCreated, saves to user account

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 21:08:21 -08:00
hailin 289691dc3c fix: align mpc-service migration with schema and fix identity-service compile errors
- Update mpc-service migration to match new gateway mode schema (mpc_wallets, mpc_shares)
- Remove old MySQL migrations (party_shares, session_states, share_backups)
- Fix MpcSignature type to use string format (64 bytes hex: R + S)
- Add persistence layer conversion functions for DB compatibility
- Fix method names in domain services (checkDeviceNotRegistered, generateNextUserSequence)
- Update wallet generator interface to use delegateShare instead of clientShareData

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 18:42:48 -08:00
hailin 17fd663fe3 refactor: improve auto-create API semantics and use real device ID
Frontend (account_service.dart):
- Use Android ID instead of random UUID for deviceId
- Add DeviceHardwareInfo class with full hardware details
- Remove provinceCode/cityCode from CreateAccountRequest
- Simplify to: deviceId (required), deviceName (optional JSON), inviterReferralCode (optional)

Backend (identity-service):
- Rename validateDeviceId() to checkDeviceNotRegistered() for clarity
- Rename generateNext() to generateNextUserSequence() for semantics
- Update error message: "该设备已创建过账户"

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 18:05:11 -08:00
hailin 747e4ae8ef refactor(mpc-system): migrate to party-driven architecture with PartyID-based routing
- Remove Address field from PartyEndpoint (parties connect to router themselves)
- Update K8s Discovery to only manage PartyID and Role labels
- Add Party registration and SessionEvent protobuf definitions
- Implement PartyRegistry and SessionEventBroadcaster domain logic
- Add RegisterParty and SubscribeSessionEvents gRPC handlers
- Prepare infrastructure for party-driven MPC coordination

This is the first phase of migrating from coordinator-driven to party-driven
architecture following international MPC system design patterns.
2025-12-05 08:11:28 -08:00
Developer a966d71fa0 . 2025-11-30 06:44:57 -08:00
Developer 083db83c96 . 2025-11-29 19:22:42 -08:00
hailin 3aaac6af6f . 2025-11-24 02:50:45 -08:00
hailin 44d2e2ad80 . 2025-11-24 06:58:46 +00:00
hailin c29c185a03 identity_service_context first commit 2025-11-24 06:09:06 +00:00