Commit Graph

565 Commits

Author SHA1 Message Date
hailin ad82e3ee44 fix(referral-service): 从领域层修复 usedReferralCode 存储错误
问题:
- 创建推荐关系时,used_referral_code 字段错误地存储了用户自己的推荐码
- 而不是用户使用的推荐人的推荐码

根本修复(从领域层):
1. ReferralRelationshipProps: 添加 usedReferralCode 字段
2. ReferralRelationship.create(): 新增 referrerReferralCode 参数
3. ReferralRelationship: 添加 _usedReferralCode 私有属性和 getter
4. toPersistence(): 输出 usedReferralCode
5. reconstitute(): 正确重建 usedReferralCode

调用链路修复:
- referral.service.ts: 在查询推荐人时获取其 referralCode,
  并在调用 ReferralRelationship.create() 时传入
- repository: 直接使用 data.usedReferralCode 而不是额外查询

测试更新:
- 更新单元测试和集成测试以支持新的 create() 签名
- 新增 usedReferralCode 相关测试用例

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 19:49:11 -08:00
hailin e557b00c24 fix(reward-service): 修复 targetType 类型断言 2025-12-12 19:16:15 -08:00
hailin 96f031da35 fix(wallet-service): 修复 allocateToUserWallet 使用 accountSequence 查找钱包
- targetId 现在是 accountSequence (如 D2512120001),不再是 userId
- 移除无效的 BigInt(targetId) 转换
- 从 wallet 对象获取 userId 用于流水记录和缓存失效

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 19:15:47 -08:00
hailin 518667e88e fix(reward-service): 修复与 wallet-service 的接口字段不匹配
修复 allocateFunds 接口:
- targetType: 使用 USER/SYSTEM 而不是 rightType
- targetId: 使用 accountSequence 而不是 userId
- allocationType: 新增字段,存储 rightType
- hashpowerPercent: 新增字段,传递算力百分比

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 19:10:39 -08:00
hailin d94badfa53 fix(wallet-service): 修复 account_sequence 类型从 BIGINT 改为 VARCHAR(20)
与其他服务保持一致,accountSequence 格式为 D + YYMMDD + 5位序号
- wallet_accounts.account_sequence
- wallet_ledger_entries.account_sequence
- deposit_orders.account_sequence
- withdrawal_orders.account_sequence

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 18:46:37 -08:00
hailin a5089db288 fix: 修复授权唯一性验证不检查地区的bug
授权验证规则:一条推荐线上同一类型授权只能有一个人,不管地区是什么
- 使用 findByUserIdAndRoleType 替代 findByUserIdRoleTypeAndRegion
- 错误信息中显示已存在授权的地区名称

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 13:20:53 -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 8148d1d127 fix: 修复权益分配竞态条件和统计数据bug
1. 事件流重构:将 planting.order.paid 事件从 planting-service 移至 referral-service 发送
   - 确保统计数据更新后再触发奖励计算,避免竞态条件
   - planting-service 只发送 planting.planting.created 事件(包含订单信息)
   - referral-service 处理完统计更新后转发 planting.order.paid 给 reward-service

2. 修复 addPersonalPlanting 方法:
   - 原代码错误地更新 _totalTeamCount(团队人数)而非 _teamPlantingCount(团队认种数)
   - 导致 subordinateTeamPlantingCount 计算错误,权益无法正确分配

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 05:35:31 -08:00
hailin 16f891b743 fix(authorization): include target-reaching tree in user's reward
修复达标时收益分配错误:达标的那一棵应该归被授权用户所有。

之前逻辑:目标10棵,当前0棵,本次种10棵
- remaining = 10 - 0 = 10
- 上级得到10棵,用户得到0棵 

修复后:
- remaining = max(0, 10 - 0 - 1) = 9(不包括达标那一棵)
- 上级得到9棵,用户得到1棵 

影响:社区、省团队、市团队、省区域、市区域

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 03:53:59 -08:00
hailin a54e9743ef fix(authorization): correctly distribute rewards when assessment target is exactly reached
修复当认种恰好达标时的收益分配错误:
- 之前:恰好达标时全部收益给上级/总部,被授权用户无法获得任何收益
- 现在:达标时的那一棵收益归被授权用户所有

影响的分配方法:
- getCommunityRewardDistribution (社区)
- getProvinceTeamRewardDistribution (省团队)
- getCityTeamRewardDistribution (市团队)
- getProvinceAreaRewardDistribution (省区域)
- getCityAreaRewardDistribution (市区域)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 03:19:09 -08:00
hailin f60d4eac87 feat(authorization): remove region matching requirement for team rewards
省团队(AUTH_PROVINCE_COMPANY)和市团队(AUTH_CITY_COMPANY)收益分配不再要求
认种者选择的省市与被授权用户的省市一致,只要在推荐链上有授权即可获得收益。

省区域(PROVINCE_COMPANY)和市区域(CITY_COMPANY)收益仍保持省市匹配要求。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 03:04:55 -08:00
hailin 4bf4efb1f4 feat(authorization): add assessment rules for province/city area roles
- Province area (PROVINCE_COMPANY): 50,000 trees initial target
- City area (CITY_COMPANY): 10,000 trees initial target
- Apply consistent assessment logic: pre-target rewards go to system account, post-target rewards go to company
- Auto-activate benefit when target is reached

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 21:57:00 -08:00
hailin 905725fc2d feat(authorization): add admin APIs for auth-province and auth-city company
- Add POST /admin/authorizations/auth-province-company for 省团队授权
- Add POST /admin/authorizations/auth-city-company for 市团队授权
- Add team uniqueness validation for all province/city authorization types
- Add domain events: AuthProvinceCompanyGrantedEvent, AuthCityCompanyGrantedEvent
- Add factory methods: createAuthProvinceCompanyByAdmin, createAuthCityCompanyByAdmin

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 21:46:44 -08:00
hailin 582828b8be fix(authorization): activate benefit when assessment target is exactly reached
When tree count + current team count equals initial target exactly,
the benefit was not being activated. Now properly handles three cases:
- afterPlantingCount < target: still in assessment, no activation
- afterPlantingCount === target: reached target, activate benefit
- afterPlantingCount > target: exceeded target, split rewards & activate

Applied to community, province team, and city team reward distribution.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 20:29:15 -08:00
hailin 9819130f98 fix(authorization): use subordinate team count for assessment and auto-activate benefit
1. Assessment calculation now uses subordinate team count (excluding self planting)
   - Added selfPlantingCount to referral-service API response
   - Added subordinateTeamPlantingCount getter to TeamStatistics interface
   - Updated all assessment checks to use subordinateTeamPlantingCount

2. Auto-activate benefit when assessment target is reached
   - Added tryActivateBenefit helper method
   - Community, province team, and city team reward distribution methods
     now automatically activate benefit when target is reached

3. Fixed event consumer to support AUTHORIZED status (admin grants)
   - Previously only checked PENDING status for activation

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 19:33:39 -08:00
hailin f94e7283d5 fix(authorization): fix race condition in reward distribution calculation
When calculating reward distribution for community/province/city benefits,
the totalTeamPlantingCount was being read after referral-service had already
updated it with the current planting. This caused incorrect distribution
where benefits were given to the community holder before they completed
their assessment target.

Fix: Subtract treeCount from rawTeamCount to restore the "before planting"
team count, ensuring correct assessment calculation.

Affected methods:
- getCommunityRewardDistribution
- getProvinceTeamRewardDistribution
- getCityTeamRewardDistribution

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 19:01:11 -08:00
hailin fc55afb7b9 fix(authorization): show parent community without requiring benefitActive
Changed findActiveCommunityByAccountSequences to not require benefitActive=true.
This allows communities that haven't passed assessment to still be shown as
parent communities in the UI, while reward distribution logic remains unchanged.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 18:39:22 -08:00
hailin 9378bf7570 feat(authorization): add skipAssessment option to admin grant APIs
Admin grant APIs now default to requiring assessment (benefitActive=false).
Added optional skipAssessment parameter to bypass assessment when needed.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 17:48:49 -08:00
hailin 4d01bc5faa chore(reward-service): add detailed debug logs to reward calculation
Add comprehensive logging to RewardCalculationService for easier debugging:
- Log start/end of calculateRewards with order info
- Log each benefit calculation with input parameters
- Log distribution results from authorization-service calls
- Log share right decisions (settleable vs pending)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 07:59:01 -08:00
hailin 16d95999de feat(backend): implement assessment rules for reward distribution
Add proper assessment/考核 logic for all 5 benefit types:
- Community (80 USDT): 10-tree initial assessment, splits rewards between
  current community and parent/headquarters based on progress
- Province Team (20 USDT): 500-tree initial assessment for AUTH_PROVINCE_COMPANY
- Province Area (15 USDT + 1%): 50000-tree target for PROVINCE_COMPANY,
  routes to system account until target reached
- City Team (40 USDT): 100-tree initial assessment for AUTH_CITY_COMPANY
- City Area (35 USDT + 2%): 10000-tree target for CITY_COMPANY,
  routes to system account until target reached

Changes:
- authorization-service: Add 4 new distribution API endpoints and application
  service methods for province/city team/area reward distribution
- authorization-service: Add repository methods for querying authorizations
  including benefitActive=false records
- reward-service: Update client to call new distribution APIs
- reward-service: Modify calculation methods to return multiple reward entries
  based on assessment distribution plan

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 07:54:55 -08:00
hailin c162ccced9 fix(reward): correct response parsing for authorization-service API
The authorization-service uses TransformInterceptor which wraps all API
responses in a standard format: { success, data, timestamp }

Before this fix, the AuthorizationServiceClient was reading:
  data.accountSequence (undefined - wrong level)

After this fix, it correctly reads:
  result.data.accountSequence

This ensures that COMMUNITY_RIGHT is allocated to the correct authorized
community user (e.g., accountSequence=6) instead of falling back to
HEADQUARTERS (accountSequence=1).

Changes in reward-service:
- Added AuthorizationServiceResponse<T> interface
- Added NearestAuthorizationResult interface
- Updated findNearestAuthorizedProvince() to parse wrapped response
- Updated findNearestAuthorizedCity() to parse wrapped response
- Updated findNearestCommunity() to parse wrapped response
- Added debug logging for findNearestCommunity

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 03:33:10 -08:00
hailin d1a7c44f23 fix(referral): correct response parsing for authorization-service API
The authorization-service uses TransformInterceptor which wraps all API
responses in a standard format: { success, data, timestamp }

Before this fix, the AuthorizationServiceClient was reading:
  response.data.accountSequence (undefined)

After this fix, it correctly reads:
  response.data.data.accountSequence

This ensures that nearestCommunity, nearestProvinceAuth, and nearestCityAuth
are properly extracted from the wrapped response, allowing community benefits
to be correctly allocated to authorized users instead of falling back to
SYSTEM_HEADQUARTERS_COMMUNITY.

Changes:
- Added AuthorizationServiceResponse<T> interface to model wrapped response
- Updated findNearestCommunity() to use wrapped response type
- Updated findNearestProvince() to use wrapped response type
- Updated findNearestCity() to use wrapped response type
- Updated catchError handlers to return properly structured fallback data

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 03:08:50 -08:00
hailin ee9265f357 fix(docker): remove cyclic dependency between referral-service and authorization-service
两个服务互相调用,形成循环依赖。移除 depends_on 约束,使用 fallback 机制处理服务暂时不可用的情况。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 02:50:04 -08:00
hailin 1a5925494e feat(referral): integrate authorization-service for community/province/city rights allocation
## Problem
社区/省/市权益分配一直返回 null,导致所有权益都分配给系统账户而非正确的授权用户。
原因:referral-service 的 getReferralContext 接口中 nearestCommunity、nearestProvinceAuth、
nearestCityAuth 三个字段硬编码为 null,注释说"需要后续实现"但一直未实现。

## Solution
1. 新建 AuthorizationServiceClient 调用 authorization-service 的内部 API
   - /api/v1/authorization/nearest-community
   - /api/v1/authorization/nearest-province
   - /api/v1/authorization/nearest-city
2. 修改 InternalReferralController 使用并行查询获取授权信息
3. 添加 fallback 机制:authorization-service 不可用时返回 null(保持现有行为)
4. docker-compose.yml 添加 AUTHORIZATION_SERVICE_URL 环境变量

## Files Changed
- backend/services/referral-service/src/infrastructure/external/authorization-service.client.ts (new)
- backend/services/referral-service/src/api/controllers/referral.controller.ts
- backend/services/referral-service/src/modules/infrastructure.module.ts
- backend/services/docker-compose.yml

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 02:10:33 -08:00
hailin 7d9837fc22 refactor(reward): 前端直接从 reward-service 查询奖励数据
移除 reward-service 和 wallet-service 之间的 Kafka 同步机制:
- 屏蔽 reward-service 的 outbox 发布逻辑
- 屏蔽 wallet-service 的 RewardEventConsumerController 订阅

Flutter 前端改为直接调用 reward-service API:
- 新增 RewardService 调用 /rewards/summary
- profile_page 改用 rewardService.getMyRewardSummary()

这样简化了架构,数据从源头获取,避免同步问题。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 00:36:53 -08:00
hailin a1ca490ff4 fix(wallet): fix message format parsing in RewardEventConsumerController
The OutboxPublisherService sends payload fields directly at the message
root level, not nested under a 'payload' property. Update the consumer
to read fields directly from message instead of message.payload.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 23:49:07 -08:00
hailin 1acb314e7b feat(reward): add outbox event publishing for reward summary updates
Add publishSummaryUpdatesToOutbox method to write reward.summary.updated
events to outbox table for synchronization to wallet-service.

Events are published after:
- distributeRewards: when rewards are distributed to users
- claimPendingRewardsForUser: when pending rewards are claimed
- settleRewards: when rewards are settled
- expireOverdueRewards: when rewards expire

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 23:40:35 -08:00
hailin 538aae4ef0 feat(sync): implement Outbox Pattern for reward-service to wallet-service sync
Add event synchronization infrastructure between reward-service and wallet-service:

reward-service changes:
- Add OutboxEvent model to prisma schema for reliable event publishing
- Add outbox.repository.ts for outbox table CRUD operations
- Add outbox-publisher.service.ts for polling and publishing events to Kafka
- Add event-ack.controller.ts to receive consumer confirmations

wallet-service changes:
- Add ProcessedEvent model to prisma schema for idempotency checking
- Add reward-event-consumer.controller.ts to consume reward.summary.updated events
- Add event-ack.publisher.ts to send ACK to reward-service
- Update kafka.module.ts with Kafka client configuration
- Update main.ts to connect Kafka microservice on startup

Event flow: reward-service -> Kafka (reward.summary.updated) -> wallet-service -> Kafka (reward.events.ack) -> reward-service

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 23:26:49 -08:00
hailin e2b3f25dbc fix(reward): add /api/v1 prefix to internal service API calls
Both referral-service and authorization-service use global prefix /api/v1,
so the client calls need to include this prefix.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 22:42:14 -08:00
hailin 9a823e8871 fix(referral): convert BigInt to string for JSON serialization
BigInt cannot be serialized by JSON.stringify, convert to string
before returning from the API endpoint.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 22:29:17 -08:00
hailin 1afdc2ce17 refactor(reward): remove unused transferExpiredRewardToOperationAccount method
Expired referral rewards are transferred to headquarters community (seq=1),
not operation account. Remove the unused method to avoid confusion.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 21:55:18 -08:00
hailin 6f46a8633f feat(reward): add internal APIs for reward distribution
- Add /referral/chain/{userId} API in referral-service for getting referral chain with hasPlanted status
- Add internal authorization APIs in authorization-service:
  - GET /authorization/nearest-community: find nearest community in referral chain
  - GET /authorization/nearest-province: find nearest province company in referral chain
  - GET /authorization/nearest-city: find nearest city company in referral chain
- Add repository methods for finding active authorizations by accountSequence
- Update reward-service client to use accountSequence parameter

These APIs enable reward-service to correctly distribute:
- 分享权益 (share benefit): to referrer with hasPlanted=true
- 社区权益 (community benefit): to nearest community leader
- 省团队权益 (province team benefit): to nearest province company
- 市团队权益 (city team benefit): to nearest city company

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 21:49:13 -08:00
hailin 9cf8b5305b feat(authorization): add community hierarchy API
- Add internal referral-chain API in referral-service for getting ancestor path and team members
- Extend ReferralServiceClient to call referral-chain API
- Add findActiveCommunityByAccountSequences repository method
- Add getCommunityHierarchy application service method
- Add GET /authorizations/my/community-hierarchy endpoint
- Update frontend with CommunityHierarchy model and getMyCommunityHierarchy method

API returns:
- myCommunity: user's own community authorization (if any)
- parentCommunity: nearest parent community (defaults to 总部社区 if none)
- childCommunities: nearest child communities in user's team

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 18:18:49 -08:00
hailin f8cfb5e597 feat(authorization): add admin API for community authorization
Add new endpoint POST /api/v1/admin/authorizations/community
that allows administrators to directly authorize users as community
managers without requiring the user to self-apply first.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 17:03:34 -08:00
hailin 003bef1c76 fix(reward): add REFERRAL_SERVICE_URL and AUTHORIZATION_SERVICE_URL
reward-service was trying to connect to localhost instead of Docker
network service names, causing connection refused errors.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 16:48:47 -08:00
hailin b1e6cb5041 chore(authorization): add axios dependency for referral-service HTTP client
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 16:37:01 -08:00
hailin ccef23f5b0 feat(authorization): integrate with referral-service for team statistics
- Add InternalTeamStatisticsController in referral-service for service-to-service API
- Create ReferralServiceClient in authorization-service to fetch real team statistics
- Replace MockTeamStatisticsRepository with real HTTP client implementation
- Configure docker-compose with REFERRAL_SERVICE_URL for authorization-service

This enables authorization-service to get real team planting counts from
referral-service for authorization assessment and activation logic.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 16:30:35 -08:00
hailin 05545dea59 fix(authorization): add missing findByAccountSequence to MockTeamStatisticsRepository
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 16:18:12 -08:00
hailin b6bc10d680 debug(backup-service): log allowed services on init
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 16:00:29 -08:00
hailin 5ecb13974f fix(backup-service): add mpc-service to allowed services
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 15:42:40 -08:00
hailin 660e5ea3a0 fix(mpc-service): add backup service environment variables
Add BACKUP_SERVICE_URL, BACKUP_SERVICE_ENABLED, and SERVICE_JWT_SECRET
to mpc-service configuration to enable backup share storage.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 15:39:52 -08:00
hailin 41af5ef3a3 fix(mpc/backup): add accountSequence to backup share storage
- mpc-service: add accountSequence param to StoreBackupShareParams
- mpc-service: pass accountSequence when calling backup-service
- backup-service: add logging for store request success/failure

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 15:06:00 -08:00
hailin 300fe211c8 fix: add accountSequence to all services and fix compilation errors
- reward-service: add accountSequence to aggregates, services, tests
- authorization-service: fix UserId/AdminUserId to accept accountSequence, add findByAccountSequence to repositories
- referral-service: fix test files for accountSequence changes
- Add migration files for reward-service and authorization-service

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 14:14:06 -08:00
hailin 034fb53674 refactor: use accountSequence as unified user identifier across all services
- planting-service: extract accountSequence from JWT, pass to referral-service
- referral-service: query by accountSequence instead of userId
- reward-service: add accountSequence field to schema and all layers
- wallet-service: prioritize accountSequence lookup over userId
- authorization-service: change userId from String to BigInt, add accountSequence

This change ensures consistent cross-service user identification using
accountSequence (8-digit unique business ID) instead of internal database IDs.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 13:55:03 -08:00
hailin 62a21b73a5 fix(referral): use accountSequence instead of userId for user registration events
identity-service sends userId=0 in events (temp value before DB save),
use accountSequence as the unique identifier instead
2025-12-10 13:29:36 -08:00
hailin 31c3c24a12 fix(reward-service): correct healthcheck endpoint path to /api/v1/health 2025-12-10 12:48:26 -08:00
hailin 8532bf6945 fix(blockchain): use amountFormatted to rebuild TokenAmount from DB
Previously used amount (raw) with hardcoded 18 decimals, which caused
incorrect formatting for USDT (6 decimals). Now uses amountFormatted
which is already correctly formatted during deposit detection.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 12:22:32 -08:00
hailin db3e0ba1bd fix(blockchain): fix deposit stuck in CONFIRMING status
The updateConfirmations logic only checked for DETECTED status
when confirming, so deposits that transitioned to CONFIRMING
would never be confirmed even with enough confirmations.

Changed condition to accept both DETECTED and CONFIRMING status.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 12:19:29 -08:00
hailin 5e670e64b3 fix(blockchain): read token decimals from contract for deposit detection
Previously decimals were hardcoded to 18, causing incorrect amount parsing
for USDT which uses 6 decimals. Now reads decimals() from ERC20 contract
when processing deposits.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 11:57:34 -08:00
hailin 8cea0e7998 fix(reward): change sourceOrderId to sourceOrderNo string type
Fixes BigInt conversion error when consuming planting.order.paid events.
The orderId from planting-service is a string format like PLT1765391584505Q0Q6QD,
not a numeric value.

Changes:
- reward-source.vo.ts: sourceOrderId (bigint) → sourceOrderNo (string)
- reward-calculation.service.ts: updated all method signatures
- reward-application.service.ts: updated distributeRewards params
- event-consumer.controller.ts: removed BigInt() conversion
- prisma schema: changed column type to VarChar(50)
- mapper/repository: updated field names accordingly
- Removed incompatible prisma.config.ts (Prisma 7.x format)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 11:12:58 -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 9e6fc04344 fix(reward): register EventConsumerController to enable Kafka consumption
EventConsumerController was not registered in KafkaModule, causing
@MessagePattern('planting.order.paid') to never be subscribed.
This resulted in reward-service having empty memberAssignment.

Also added forwardRef to resolve circular dependency between
ApplicationModule and InfrastructureModule.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 10:36:55 -08:00
hailin 4972e56ad2 fix(reward): correct health check path to /api/v1/health
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 10:16:57 -08:00
hailin adc063eb7a fix(authorization): add Kafka microservice for @EventPattern to work
authorization-service uses @EventPattern('planting-events') to consume
planting events but was missing connectMicroservice() configuration.
Without this, the service could not receive planting events, causing:
- Province team benefits (20 USDT) not distributed
- City team benefits (40 USDT) not distributed
- Community benefits (80 USDT) not distributed
- Monthly assessment data not updated

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 10:08:55 -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 70d1a8bfb8 fix(referral): add idempotency check for Kafka event processing
- Add processed_events table to track handled events
- Check eventId before processing planting.created events
- Skip duplicate events and still send ACK to stop retries

This prevents data accumulation when Kafka events are redelivered
due to ACK failures or consumer timeouts.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 09:38:13 -08:00
hailin 3714edb30b feat(wallet): add detailed logging for freeze-for-planting API
Added comprehensive logging to track:
- Request parameters (userId, amount, orderId)
- Wallet balance information
- Balance check results
- Freeze operation status

This helps debug the 400 error when planting-service calls wallet-service.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 08:38:36 -08:00
hailin 22c32031af feat(authorization): add community assessment progress to profile page
Backend:
- Add initialTargetTreeCount, currentTreeCount, monthlyTargetTreeCount
  fields to AuthorizationDTO and AuthorizationResponse
- Query TeamStatistics to populate current tree count in getUserAuthorizations

Frontend:
- Update AuthorizationResponse to parse new progress fields
- Replace hardcoded community assessment values with real API data
- Show authorization status: red (unauthorized), orange (pending), green (active)
- Display progress bar and target requirements based on benefit status

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 06:44:13 -08:00
hailin e5e2793337 feat(planting): add payment reliability improvements
## wallet-service
- Add freeze/confirm/unfreeze API endpoints for planting deduction
- Add deductFrozen method to wallet-account aggregate
- Add PLANT_FREEZE and PLANT_UNFREEZE ledger entry types
- Add idempotency check in deductForPlanting
- Fix test files to include accountSequence parameter

## planting-service
- Add PaymentCompensation model and migration
- Add payment-compensation.repository.ts
- Add payment-compensation.service.ts (background job for retry)
- Add HTTP retry mechanism with exponential backoff
- Refactor payOrder to use freeze → transaction → confirm flow
- Create compensation record on unfreeze failure

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 06:31:54 -08:00
hailin 68182fd0a3 feat(referral): add personal/team planting counts to direct referral list
- Backend: batch query TeamStatistics to get each direct referral's
  personalPlantingCount and teamPlantingCount
- Updated DTO and query interfaces with new fields
- Frontend: parse and display "个人/团队" counts in profile page

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 05:57:46 -08:00
hailin 13f670e9dd fix(referral): fix direct referral list display and count issues
1. Return accountSequence instead of userId for direct referral list display
2. Create missing team statistics record when referrer doesn't have one

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 04:58:16 -08:00
hailin 12116ff164 feat(blockchain): add deposit repair service and controller
Add internal APIs to diagnose and repair historical deposit issues:
- GET /internal/deposit-repair/diagnose - Query unnotified deposits
- POST /internal/deposit-repair/repair/:depositId - Repair single deposit
- POST /internal/deposit-repair/repair-all - Batch repair all pending deposits
- POST /internal/deposit-repair/reset-failed-outbox - Reset failed outbox events

The repair service creates new outbox events for CONFIRMED deposits
that were never notified to wallet-service.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 02:19:46 -08:00
hailin 30aa11c6c6 fix(referral): fix EventAckMessage type casting
Cast ackMessage to Record<string, unknown> for KafkaService compatibility.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 22:31:12 -08:00
hailin 807dc8705d fix(referral): add EventAckPublisher to InfrastructureModule
- Refactor EventAckPublisher to use KafkaService instead of ClientKafka
- Add kafka/index.ts export file
- Register EventAckPublisher in InfrastructureModule providers and exports

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 22:29:54 -08:00
hailin dfa21c0280 feat(mobile): integrate PlantingService with real API
- Add PlantingService for planting order management
  - createOrder: Create new planting order
  - selectProvinceCity: Select province and city
  - confirmProvinceCity: Confirm province/city selection
  - payOrder: Pay for order
  - getOrder/getMyOrders: Query orders
  - cancelOrder: Cancel unpaid orders
- Register PlantingService in DI container
- Update planting_quantity_page to create order before navigation
- Update planting_location_page to call real API endpoints
- Fix referral-service event-ack.publisher to use KafkaService

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 22:28:36 -08:00
hailin ba5b6141a3 fix(planting-service): improve outbox event confirmation accuracy
- markAsConfirmed now uses aggregateId + eventType for precise matching
- Prevents accidentally confirming multiple events for the same order
- EventAckController passes eventType to markAsConfirmed

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 22:16:23 -08:00
hailin 8de7a668f0 fix(referral): remove LeaderboardCacheService dependency
Leaderboard functionality has been moved to leaderboard-service.
Remove the dependency and set leaderboardRank to null.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 22:13:57 -08:00
hailin 49fc68297b fix(blockchain): fix TypeScript compilation errors
- Fix brokers type narrowing issue in deposit-ack-consumer.service.ts
- Add Prisma.InputJsonValue type cast for payload in outbox-event.repository.impl.ts

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 22:11:28 -08:00
hailin 2bf5ca933e refactor(referral): remove legacy leaderboard code
Remove duplicate leaderboard functionality from referral-service.
All leaderboard features should now go through leaderboard-service.

Removed files:
- api/controllers/leaderboard.controller.ts
- api/dto/leaderboard.dto.ts
- application/queries/get-leaderboard.query.ts
- infrastructure/cache/leaderboard-cache.service.ts
- Related test files

Modified:
- TeamStatisticsService: removed getLeaderboard() and getUserRank()
- Module registrations updated

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 22:05:48 -08:00
hailin 181eeafb2c fix(authorization-service): fix KafkaModule dependency injection
- Add ClientsModule with KAFKA_SERVICE registration
- Add EventAckPublisher to KafkaModule providers/exports
- Move EventConsumerController to AppModule (has access to repositories)

Resolves: Nest can't resolve dependencies of EventConsumerController

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 21:55:10 -08:00
hailin 52ddad1000 fix(api-gateway): correct Kong routes and add missing globalPrefix
- Kong: change /api/v1/plantings to /api/v1/planting (match controller)
- reward-service: add missing app.setGlobalPrefix('api/v1')

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 21:51:58 -08:00
hailin 075c9aaa48 feat(blockchain): implement Outbox Pattern for reliable event delivery
Implement Outbox Pattern with consumer ACK to ensure 100% reliable event
delivery between blockchain-service and wallet-service:

blockchain-service:
- Add OutboxEvent model to Prisma schema with status tracking
- Create outbox repository interface and implementation
- Modify deposit-detection.service to write events to outbox
- Add outbox-publisher.service with cron jobs for publishing/retry
- Add deposit-ack-consumer.service to receive ACK from wallet-service
- Add publishRaw method to event-publisher.service

wallet-service:
- Modify deposit-confirmed.handler to send ACK after successful processing
- Add wallet.deposit.credited topic mapping for ACK events

Event flow:
1. Deposit detected → written to outbox (status: PENDING)
2. Outbox publisher sends to Kafka → status: SENT
3. wallet-service processes and sends ACK → status: ACKED
4. Events without ACK are retried with exponential backoff

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 21:47:31 -08:00
hailin f04f8ed6ce chore(prisma): add missing migration_lock.toml files
Added migration_lock.toml for planting-service, reward-service,
referral-service, and authorization-service to ensure Prisma
can properly track migration provider.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 21:39:20 -08:00
hailin 014ad9d19f feat(planting): implement Outbox Pattern with consumer acknowledgment (B方案)
Implement reliable event delivery using Outbox Pattern with consumer confirmation:

## planting-service (Producer)
- Add OutboxEvent table with status: PENDING → SENT → CONFIRMED
- Add OutboxRepository with transaction support and timeout handling
- Add OutboxPublisherService with polling, timeout check, and retry
- Add EventAckController to receive consumer confirmations
- Update UnitOfWork to save outbox events atomically with business data
- Update PlantingApplicationService to use outbox pattern
- Update PoolInjectionService to use outbox pattern

## Consumer Services
- Add EventAckPublisher to reward-service, referral-service, authorization-service
- Update event handlers to send acknowledgment after successful processing

## Event Flow
1. Business data + outbox events saved in same transaction
2. OutboxPublisher polls and sends to Kafka, marks as SENT
3. Consumer processes event and sends ack to planting.events.ack
4. EventAckController receives ack and marks as CONFIRMED
5. Timeout check resets SENT→PENDING for retry (max 5 times)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 21:32:16 -08:00
hailin b98844abe4 feat(db): add Prisma migrations for wallet-service and planting-service
- Add initial migration for wallet-service (wallet_accounts, ledger_entries, deposit/settlement/withdrawal orders)
- Add initial migration for planting-service (planting_orders, fund_allocations, positions, batches, events)
- Both services now have migrations that will be automatically applied on container startup via `prisma migrate deploy`

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 20:30:23 -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 2ed1658c16 fix(admin-service): exclude /downloads from API prefix
Downloads route was getting /api/v1 prefix, making it inaccessible at /downloads

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 07:44:53 -08:00
hailin 4b4b09f046 fix(docker): add BASE_URL env for admin-service
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 07:31:32 -08:00
hailin 424fa3514f fix(admin-service): add BASE_URL for APK download URLs
Set BASE_URL to public API gateway address so mobile app can download
APK files from correct URL instead of localhost.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 07:30:16 -08:00
hailin eceb927d54 fix(admin-service): relax changelog and minOsVersion validation
- Changelog: allow empty value, return default "No changelog provided"
- MinOsVersion: allow empty value and single number format (e.g., "24" -> "24.0")

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 07:09:03 -08:00
hailin 58a359d9b3 fix: changelog default value and referrals map syntax
- admin-service: provide default empty string for optional changelog
- profile page: fix map literal syntax for referrals list

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 07:00:02 -08:00
hailin 586dfda8f7 fix(admin): support 4-segment version in domain layer & make changelog optional
- VersionName value object now accepts x.y.z.w format
- changelog field is now optional in upload version DTO
- profile page: ensure expired section has full width

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 06:54:55 -08:00
hailin 4307d1eb91 fix(admin): support 4-segment version number format (x.y.z.w)
Allow version names like 1.0.0.4 in addition to the standard x.y.z format.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 06:41:46 -08:00
hailin 2e6f22e9d8 fix(blockchain): read token decimals from contract instead of hardcoding
The balance display was incorrect because decimals were hardcoded to 18,
but USDT uses 6 decimals. Now reads decimals() from the ERC20 contract.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 06:10:36 -08:00
hailin addcfa56e4 feat(blockchain): switch to testnet mode 2025-12-09 04:05:24 -08:00
hailin 3f2922cca6 fix(mpc-service): reduce rebalanceTimeout from 5min to 1min
sessionTimeout remains at 5 minutes (needed for long MPC operations),
but rebalanceTimeout only affects joining consumer group, not processing.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 03:40:14 -08:00
hailin 6ab3f92813 fix(mpc-service): don't block HTTP server startup during Kafka rebalance 2025-12-09 03:31:26 -08:00
hailin 0546cff708 revert: restore Kafka session timeout to 5 minutes 2025-12-09 03:28:28 -08:00
hailin 429f8d5991 Revert "fix(mpc-service): don't block startup on Kafka consumer rebalance"
This reverts commit c924d3aad2.
2025-12-09 03:26:05 -08:00
hailin c924d3aad2 fix(mpc-service): don't block startup on Kafka consumer rebalance 2025-12-09 03:25:07 -08:00
hailin 1eca8b3af8 fix(mpc-service): reduce Kafka session timeout from 5min to 30s 2025-12-09 03:24:00 -08:00
hailin c05722bbb3 fix(mpc-service): enable shutdown hooks for graceful Kafka disconnect
Root cause: When mpc-service restarts, the old Kafka consumer doesn't
properly disconnect, causing the broker to wait for sessionTimeout
(~5 minutes) before completing rebalance. This blocks app startup.

Solution: Enable NestJS shutdown hooks with app.enableShutdownHooks().
This ensures onModuleDestroy() is called on SIGTERM/SIGINT, which calls
consumer.disconnect() and allows immediate rebalance on next startup.

Also reverted the "don't await consumer.run()" workaround since the
proper fix is graceful shutdown.

Sources:
- https://github.com/tulios/kafkajs/issues/807
- https://kafka.js.org/docs/consuming

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 03:12:33 -08:00
hailin af896db36c fix(mpc-service): don't await consumer.run() to prevent app startup blocking
consumer.run() never resolves as it runs continuously. Awaiting it
blocks onApplicationBootstrap which prevents app.listen() from being
called, causing the service to never start listening on port 3006.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 03:04:48 -08:00
hailin 40c78a471d fix(mpc-service): use docker-entrypoint.sh instead of inline script
- Restore Dockerfile to use external docker-entrypoint.sh file
- The inline echo script caused issues on Linux (start.sh not created properly)
- Change from prisma migrate deploy to prisma db push for schema flexibility

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 02:54:11 -08:00
hailin 781721a659 feat(withdrawal): implement withdrawal order and fund allocation system
- Add SystemAccount domain in authorization-service for managing regional/company accounts
- Implement fund allocation service in planting-service with multi-tier distribution
- Add WithdrawalOrder aggregate in wallet-service with full lifecycle management
- Create internal wallet controller for cross-service fund allocation
- Add Kafka event publishing for withdrawal requests
- Implement unit-of-work pattern for transactional consistency
- Update Prisma schemas with withdrawal order and system account tables

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 02:35:27 -08:00
hailin 001b6501a0 feat(deposit): add deposit balance API and Kafka consumer for deposit events
Blockchain Service:
- Add /api/v1/deposit/balances endpoint to query on-chain USDT balances
- Add JWT authentication (passport, passport-jwt)
- Add JwtStrategy, JwtAuthGuard, Public decorator

Wallet Service:
- Add Kafka consumer for blockchain.deposits topic
- Add DepositConfirmedHandler to process deposit events and update wallet balance

Infrastructure:
- Add JWT_SECRET env var to blockchain-service in docker-compose.yml
- Add blockchain-service routes to Kong API Gateway

Frontend:
- Fix deposit_service.dart API path (remove duplicate /api prefix)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 02:29:31 -08:00
hailin d0487c4a7e feat(profile): integrate referral and authorization APIs for profile page
- Add Kong routes for identity-service /me, referral-service, and authorization-service
- Create AuthorizationService in Flutter for fetching user authorizations
- Extend ReferralService with getMyReferralInfo() and getDirectReferrals() methods
- Update profile_page.dart to display real team stats from APIs
- Fix authorization-service JWT strategy to accept identity-service token format
- Add decimal.js dependency to authorization-service
- Add prisma migration file for authorization-service

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 01:57:39 -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
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 cf7230457f feat(blockchain-service): KAVA EVM address derivation and system accounts support
## Address Derivation Changes
- Change KAVA from Cosmos bech32 (kava1...) to EVM format (0x...)
- KAVA now uses same EVM address as BSC for deposit monitoring
- Add KAVA to evmChains set for automatic monitoring registration

## Database Schema Updates (Migration: 20241208000000)
- MonitoredAddress: add address_type, account_sequence, system_account_type,
  system_account_id, region_code columns
- DepositTransaction: add address_type, account_sequence, system_account_type,
  system_account_id columns
- Make user_id nullable for system account support
- Create recovery_mnemonics table for account recovery
- Add indexes: idx_account_sequence, idx_type_active, idx_system_account_type,
  idx_deposit_account, and recovery_mnemonics indexes

## New Features
- Withdrawal request handler and Kafka consumer
- Test USDT deployment scripts for KAVA and BSC
- Smart contracts for TestUSDT token

## Infrastructure Updates
- Update mappers for new schema fields
- Update application and infrastructure modules

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 21:45:34 -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 3c2144ad7c feat(deposit): add accountSequence correlation and testnet support
blockchain-service:
- Add accountSequence to monitored_addresses and deposit_transactions
- Support BSC/KAVA testnet via NETWORK_MODE environment variable
- Add chain config service with testnet RPC endpoints
- Update deposit detection with accountSequence propagation

wallet-service:
- Add accountSequence to wallet_accounts and ledger_entries
- Fix JWT strategy to match identity-service token format
- Update deposit handling with accountSequence correlation
- Add repository methods for accountSequence-based queries

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 10:26:01 -08:00
hailin 6b85401d5c fix(mnemonic): fix recovery-by-mnemonic using hash verification instead of address matching
## Problem
MPC wallet addresses have no cryptographic relationship with recovery mnemonics,
so address-based verification always failed for account recovery.

## Solution
Changed mnemonic verification from address matching to hash-based verification:
- Mnemonic acts as identity credential, verified by hash stored in blockchain-service
- Uses accountSequence to lookup stored mnemonic hash for verification

## Changes

### blockchain-service
- recovery-mnemonic.adapter.ts:
  - generateMnemonic() now async, uses bcrypt (rounds=12) for secure hashing
  - verifyMnemonic() now async, supports both bcrypt and legacy SHA256 hashes
  - Added backward compatibility for existing SHA256 hashed mnemonics
- mnemonic-verification.service.ts:
  - await verifyMnemonic() for async bcrypt comparison
- address-derivation.service.ts:
  - await generateMnemonic() for async bcrypt hashing
- package.json: added bcrypt dependency

### identity-service
- user-application.service.ts:
  - Changed recoverByMnemonic() to use verifyMnemonicByAccount (hash verification)
  - Added rate limiting: 5 failed attempts per hour per accountSequence
  - Uses Redis to track failed verification attempts
- redis.service.ts:
  - Added incr() and expire() methods for rate limiting
  - Added updateKeygenStatusAtomic() with Lua script for atomic state transitions
- mpc-keygen-completed.handler.ts:
  - Uses atomic Redis update to prevent race conditions
- blockchain-wallet.handler.ts:
  - Uses atomic Redis update for completed status

## Security Improvements
- bcrypt with 12 rounds for mnemonic hashing (anti-brute-force)
- Rate limiting prevents brute force attacks on mnemonic recovery
- Atomic Redis operations prevent race conditions in wallet creation flow

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 09:02:24 -08:00
hailin d983525aa5 fix(wallet): resolve account creation and wallet status query issues
This commit fixes three critical bugs that prevented the wallet creation
flow from completing successfully:

1. mpc-service: extraPayload not included in Kafka messages
   - KeygenCompletedEvent's extraPayload (containing userId, accountSequence,
     username, derivedAddresses) was being set dynamically but not serialized
   - identity-service received events without userId and skipped processing
   - Fix: Merge extraPayload into the published payload in event-publisher

2. mpc-service: KAFKA_BROKERS hostname mismatch
   - mpc-service used KAFKA_BROKERS=rwa-kafka:29092
   - Kafka advertises itself as kafka:29092 in cluster metadata
   - During consumer group rebalance, mpc-service couldn't connect to
     the coordinator address returned by Kafka
   - Fix: Use kafka:29092 to match Kafka's advertised listener

3. blockchain-service: recovery_mnemonics table missing
   - RecoveryMnemonic model exists in schema.prisma but not in migration
   - prisma migrate deploy found no pending migrations
   - Address derivation failed with "table does not exist" error
   - Fix: Use prisma db push instead of migrate deploy to sync schema

Tested: E2E flow now completes successfully
- POST /user/auto-create creates account
- MPC keygen completes and publishes event with extraPayload
- blockchain-service derives addresses and saves recovery mnemonic
- GET /user/wallet returns status=ready with 3 addresses and mnemonic

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 07:57:17 -08:00
hailin 43016e9ee8 fix(prisma): remove redundant migrations and duplicate indexes
- mpc-service: remove duplicate index idx_ms_username on mpc_shares.username
  (keep only unique index uq_ms_username since username is unique)
- identity-service: remove redundant migration 20241206000000_add_device_hardware_info
  (fields already exist in initial migration 20241204000000_init)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 07:08:24 -08:00
hailin 1bfbaa06f1 feat(mnemonic): propagate accountSequence through MPC keygen flow (DDD)
Changes across all three services to properly associate recovery mnemonics
with account sequence numbers instead of user IDs, following DDD principles:

identity-service:
- Add accountSequence to MpcKeygenRequestedEvent payload
- Pass accountSequence when publishing keygen request
- Remove direct access to recoveryMnemonic table (now in blockchain-service)
- Call blockchain-service for mnemonic backup marking
- BlockchainWalletHandler no longer saves mnemonic (stored in blockchain-service)

mpc-service:
- Add accountSequence to KeygenRequestedPayload interface
- Pass accountSequence through to blockchain-service when deriving addresses
- Include accountSequence in KeygenCompleted event extraPayload

blockchain-service:
- Add accountSequence to derive-address API and internal interfaces
- Add accountSequence to KeygenCompletedPayload extraPayload
- Add PUT /internal/mnemonic/backup API for marking mnemonic as backed up
- Store recovery mnemonic with accountSequence association

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 01:08:27 -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 1a5bafec1a fix: add api/v1 prefix to BLOCKCHAIN_SERVICE_URL 2025-12-08 00:09:54 -08:00
hailin 3df55fcd6a fix: add BLOCKCHAIN_SERVICE_URL=http://blockchain-service:3012 for mnemonic verification 2025-12-08 00:04:39 -08:00
hailin 56de1bff83 revert: remove BLOCKCHAIN_SERVICE_URL override, use default port 3000 2025-12-07 23:57:59 -08:00
hailin a7a7b6b8f6 fix(services): add BLOCKCHAIN_SERVICE_URL to identity-service
Fix mnemonic verification by connecting to blockchain-service on port 3012

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 23:50:55 -08:00
hailin 2613a601b4 chore: update MinIO credentials in .env.example files
Sync MINIO_SECRET_KEY default value with MinIO server config

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 23:22:45 -08:00
hailin b1e51bd73b fix: change MINIO_PUBLIC_URL from cdn to minio.szaiai.com
CDN domain has nginx host header issue, use minio.szaiai.com directly

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 22:26:30 -08:00
hailin 91c8bba80d fix(identity-service): configure MinIO to connect to external server
- Update MINIO_ENDPOINT from localhost to 192.168.1.100 (Server A)
- Add MinIO environment variables to docker-compose.yml
- Set MINIO_PUBLIC_URL to https://cdn.szaiai.com for CDN access
- Add MinIO config section to backend/services/.env.example

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 22:22:55 -08:00
hailin 81cd90eae0 fix(identity): add StorageService to InfrastructureModule in app.module.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 21:53:06 -08:00
hailin 0989d914de chore(identity): update package-lock.json for minio and multer
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 21:42:16 -08:00
hailin 550a3dba06 feat(identity): add avatar upload with MinIO storage
- Add StorageService for MinIO object storage operations
- Add upload-avatar API endpoint with file validation
- Support jpg, png, gif, webp formats (max 5MB)
- Auto-update user profile after avatar upload

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 21:38:35 -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 8e9eb0ef19 fix(identity): add device_info columns to user_devices migration
- Add device_info JSONB column for storing complete device info
- Add platform, device_model, os_version, app_version columns
- Add screen_width, screen_height, locale, timezone columns
- Add idx_platform index

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 11:42:55 -08:00
hailin 29f2dc0524 fix(identity): remove address from updateProfile and fix deviceInfo type
- Remove dto.address parameter from updateProfile controller
- Remove address property from updateProfile service
- Fix deviceInfo JSON serialization for Prisma InputJsonValue type

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 11:29:51 -08:00
hailin 79345a20cf fix(identity): update migration to TEXT avatar and remove province/city/address
- Change avatar_url column from VARCHAR(500) to TEXT
- Remove province_code, city_code, address columns from user_accounts
- Remove idx_province_city index

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 11:28:09 -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 592f13e939 refactor(identity-service): 简化DeviceNameDto为接收任意JSON对象
- 将DeviceNameDto从class改为interface
- 使用@IsObject()验证,允许前端传递任意设备信息字段
- 添加index signature允许扩展字段
- 后端只提取需要的字段存储到数据库

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 10:59:45 -08:00
hailin 0c7f9b6da9 feat(identity-service): 扩展DeviceNameDto支持更多设备信息字段
添加以下可选字段:
- brand: 品牌
- manufacturer: 厂商
- device: 设备名
- product: 产品名
- hardware: 硬件名
- sdkInt: SDK版本(Android)
- isPhysicalDevice: 是否真机

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 10:58:47 -08:00
hailin 657b66c9e5 fix: 修复钱包API路径和avatarUrl字段长度问题
- identity-service: avatarUrl字段从VarChar(2000)改为Text类型
- mobile-app: 修复getWalletInfo API路径从/user/$id/wallet改为/user/wallet
- mobile-app: 添加userWallet端点常量

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 10:53:40 -08:00
hailin 51be55d315 feat(reward): 补全10种认种奖励分配规则
新增4种系统费用类权益:
- COST_FEE: 成本费 400 USDT → 成本账户(userId=2)
- OPERATION_FEE: 运营费 300 USDT → 运营账户(userId=3)
- HEADQUARTERS_BASE_FEE: 总部社区基础费 9 USDT → 总部社区(userId=1)
- RWAD_POOL_INJECTION: RWAD底池注入 800 USDT → 底池账户(userId=4)

原有6种用户权益类保持不变:
- SHARE_RIGHT: 分享权益 500 USDT
- PROVINCE_AREA_RIGHT: 省区域权益 15 USDT + 1%算力
- PROVINCE_TEAM_RIGHT: 省团队权益 20 USDT
- CITY_AREA_RIGHT: 市区域权益 35 USDT + 2%算力
- CITY_TEAM_RIGHT: 市团队权益 40 USDT
- COMMUNITY_RIGHT: 社区权益 80 USDT

总计: 400 + 300 + 9 + 800 + 500 + 15 + 20 + 35 + 40 + 80 = 2199 USDT

同时更新seed脚本创建4个系统账户

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 09:19:20 -08:00
hailin 667ca1527a feat(blockchain-service): add Prisma migration files
Add initial migration 20241207000000_init with all database tables:
- monitored_addresses
- deposit_transactions
- block_checkpoints
- transaction_requests
- blockchain_events

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 09:08:31 -08:00
hailin 54d3533c18 feat(services): add infra-clean and infra-reset commands
- infra-clean: Remove infrastructure containers and volumes (DELETES DATA)
- infra-reset: Clean and reinstall infrastructure (DELETES DATA)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 08:56:36 -08:00
hailin bfddd203ca feat(services): add --no-cache option to rebuild-svc command
Usage: ./deploy.sh rebuild-svc <name> --no-cache

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 08:46:00 -08:00
hailin fdb3c132de feat(services): add infrastructure management commands to deploy.sh
Add commands for managing infrastructure services separately:
- infra-up: Start postgres, redis, zookeeper, kafka
- infra-down: Stop infrastructure services
- infra-restart: Restart infrastructure
- infra-status: Show infrastructure status with health checks
- infra-logs: View infrastructure service logs

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 08:32:30 -08:00
hailin 3dc0fb15d8 feat(blockchain-service): add Prisma migration for init schema
- Create migration 20241207000000_init with all 5 tables
- Tables: monitored_addresses, deposit_transactions, block_checkpoints, transaction_requests, blockchain_events
- Mark migration as applied to existing database

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 08:23:14 -08:00
hailin 0c00382a98 fix: convert deploy.sh CRLF to LF and add executable permission
- Convert Windows CRLF line endings to Unix LF for all deploy.sh files
- Add executable permission to all deploy.sh scripts

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 07:01:13 -08:00
hailin b25a893d37 docs(config): update .env.example files for production deployment
- Update all .env.example files with production topology documentation
- Add network configuration for Server A (119.145.15.38/192.168.1.100) and Server B (192.168.1.111)
- Document service ports and connection URLs for all microservices
- Add architecture diagrams in comments for easy reference
- Include security notes and key generation commands

Files updated:
- backend/services/.env.example (main config)
- backend/services/identity-service/.env.example
- backend/services/mpc-service/.env.example
- backend/services/blockchain-service/.env.example
- backend/mpc-system/.env.example
- backend/api-gateway/.env.example
- backend/infrastructure/.env.example

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 04:55:21 -08:00
hailin ab8852907d fix(mpc-service): increase Kafka consumer session timeout
- Increase sessionTimeout from 30s to 5 minutes
- Increase heartbeatInterval from 3s to 10s
- Add rebalanceTimeout of 5 minutes
- This prevents consumer from being kicked out during long MPC keygen operations

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 03:58:40 -08:00
hailin 493a76117a fix(identity-service): ensure BlockchainWalletHandler is initialized
- Add BlockchainEventConsumerService to InfrastructureModule
- Add BlockchainWalletHandler and MpcKeygenCompletedHandler to ApplicationModule
- Inject event handlers into UserApplicationService to force NestJS initialization
- This ensures onModuleInit is called for event handlers, enabling Kafka event consumption

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 03:46:55 -08:00
hailin 106137224a fix(identity-service): add BlockchainEventConsumerService to InfrastructureModule
The consumer was not being initialized because it was not registered in the module.
2025-12-07 03:30:26 -08:00
hailin bad6ba2232 fix(mpc-service): use @unique on username field for Prisma upsert compatibility 2025-12-07 02:19:17 -08:00
hailin 84e653d284 fix(mpc-service): add /api/v1 prefix to blockchain-service calls
blockchain-service uses global API prefix, need to include it in URLs.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 02:11:57 -08:00
hailin 845dd857b0 fix(mpc-service): add BLOCKCHAIN_SERVICE_URL config
Configure correct blockchain-service URL (port 3012) for address derivation.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 02:08:43 -08:00
hailin 3925b19229 fix(mpc-service): use JWT auth instead of X-API-Key
mpc-account-service expects JWT Bearer tokens, not X-API-Key header.
Added JWT token generation and use MPC_JWT_SECRET env var.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 02:02:17 -08:00
hailin 7588c9efb7 fix(mpc-service): use explicit container names for rwa services
When mpc-service joins mpc-system network, 'postgres' resolves to mpc-postgres.
Use explicit names (rwa-postgres, rwa-redis, rwa-kafka) to avoid conflicts.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 01:55:52 -08:00
hailin 63e543933f fix(mpc-service): connect to mpc-system network
- Changed MPC URLs from 192.168.1.111 to Docker internal names
- Added mpc-system_mpc-network to mpc-service for cross-network communication

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 01:52:25 -08:00
hailin 2ae174692e fix(mpc-service): use correct env var name MPC_ACCOUNT_SERVICE_URL
Changed from MPC_SYSTEM_URL to MPC_ACCOUNT_SERVICE_URL to match docker-compose config.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 01:48:02 -08:00
hailin 3332124250 fix(identity-service): change dynamic import to static import
Dynamic imports with path aliases (@/domain/events) don't work at runtime.
Changed to static import to fix module resolution error.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 01:40:46 -08:00
hailin 742cc21395 fix(identity-service): extend avatar_url column to 2000 chars
SVG avatars can be up to 745+ characters, exceeding the previous 500 char limit.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 01:31:44 -08:00
hailin 34fc008f9d fix(blockchain-service): add global API prefix and increase healthcheck start_period
- Add app.setGlobalPrefix('api/v1') to main.ts so health endpoint
  is at /api/v1/health consistent with other services
- Increase healthcheck start_period to 60s to allow time for
  Prisma migrations on first startup

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 01:20:35 -08:00
hailin be6abd3034 fix(blockchain-service): standardize Dockerfile with other services
- Use node:20-slim instead of alpine for OpenSSL compatibility
- Add startup script with prisma migrate/push
- Increase healthcheck start-period to 60s
- Add non-root user for security

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 01:17:55 -08:00
hailin 1125dd98ef fix(blockchain-service): auto-create database and run migrations on startup
- Add rwa_blockchain to init-databases.sh script
- Change Dockerfile CMD to run prisma db push before starting app

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 01:14:50 -08:00
hailin e20e3cb7af fix(blockchain-service): add openssl and curl for Prisma and healthcheck 2025-12-07 01:09:25 -08:00
hailin 9eb2d5a206 fix(blockchain-service): import DomainModule for ConfirmationPolicyService 2025-12-07 01:06:45 -08:00
hailin 3af4234c89 feat: add blockchain-service to root docker-compose.yml 2025-12-07 00:58:23 -08:00
hailin dba9d16074 . 2025-12-07 00:40:19 -08:00
hailin 6451cd6fc3 refactor: unify docker-compose configs to use shared infrastructure
All microservices now use the shared rwa-network and connect to:
- rwa-postgres: Shared PostgreSQL database server
- rwa-redis: Shared Redis cache
- rwa-kafka: Shared Kafka message broker

Each service's docker-compose.yml now only defines the application
container and uses `networks: external: true` to connect to the
shared infrastructure defined in the root docker-compose.yml.

This prevents duplicate infrastructure containers and ensures all
services can communicate via Kafka and share the same Redis/PostgreSQL.

Services updated:
- admin-service
- backup-service
- blockchain-service
- identity-service
- leaderboard-service
- mpc-service
- presence-service

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 00:35:56 -08:00
hailin ce281b0657 fix(blockchain-service): install @scure/bip39 dependency
Add @scure/bip39 package for mnemonic-based address derivation.
Package.json already had the dependency listed but node_modules was missing it.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 00:25:27 -08:00
hailin bbd8a701a8 fix(blockchain-service): add @scure/bip39 dependency 2025-12-07 00:20:49 -08:00
hailin fcb949c799 fix(identity-service): remove WalletGeneratorService from app.module.ts 2025-12-07 00:15:08 -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 a181fd0d2d fix(mpc-service): change healthcheck from wget to curl
Docker compose healthcheck was using wget which is not installed in the
node:20-slim image. Changed to use curl and corrected endpoint path.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 23:42:48 -08:00
hailin 5e93bbac33 fix(mpc-service): convert docker-entrypoint.sh line endings from CRLF to LF 2025-12-06 23:34:40 -08:00
hailin 54b9a66041 fix(backup-service): convert deploy.sh line endings from CRLF to LF 2025-12-06 23:29:58 -08:00
hailin 0ab1bf0dcc feat(mpc-service): add blockchain-service client for address derivation
- Add BlockchainClientService to call blockchain-service /internal/derive-address
- Call derive addresses after keygen completes with MPC public key
- Include derived addresses (BSC, KAVA, DST) in keygen completed event

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 23:27:30 -08:00
hailin cf308efecf refactor(identity-service): remove deposit/blockchain code, belongs to wallet-service
- Remove DepositController, DepositService, BlockchainQueryService
- Deposit address and balance queries should be in wallet-service
- identity-service now only handles user identity

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 23:22:06 -08:00
hailin 9ae26d0f1f refactor(identity-service): replace direct RPC with blockchain-service API calls
- Remove ethers.js direct RPC connection to blockchain
- Add HTTP client to call blockchain-service /balance API
- Add ConfigService for BLOCKCHAIN_SERVICE_URL configuration
- Enforce proper microservice boundaries

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 23:07:46 -08:00
hailin 383a9540a0 refactor: move backup-service client from identity-service to mpc-service
Architecture change: delegate share storage is now handled by mpc-service.
- identity-service no longer calls backup-service directly
- mpc-service calls backup-service after keygen completion
- This follows proper domain boundaries (MPC domain handles share storage)

Flow:
1. identity-service publishes mpc.KeygenRequested
2. mpc-service calls mpc-system for keygen
3. mpc-service stores delegate share to backup-service
4. mpc-service publishes mpc.KeygenCompleted
5. identity-service updates user wallet address

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 22:56:35 -08:00
hailin f4f0466616 fix(mpc-service): convert deploy.sh line endings from CRLF to LF
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 22:45:35 -08:00
hailin 32c806b90c fix(identity-service): add MpcEventConsumerService to app.module.ts
The InfrastructureModule was defined inline in app.module.ts, not using
the separate infrastructure.module.ts file. Added MpcEventConsumerService
to the inline module definition.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 22:36:01 -08:00
hailin 417f580df8 fix(identity-service): add MpcEventConsumerService to InfrastructureModule
Add missing MpcEventConsumerService provider to fix NestJS dependency injection error.
MpcClientService requires MpcEventConsumerService but it was not registered in the module.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 22:15:35 -08:00
hailin 10e4fa4a5f fix(identity-service): convert deploy.sh line endings from CRLF to LF
Fix bash interpreter error caused by Windows-style CRLF line endings

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 22:03:46 -08:00
hailin 39804aa981 fix(mobile-app): update share link domain to rwaapi.szaiai.com
Changed invite share URLs from rwa-durian.app to rwaapi.szaiai.com

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 21:15:55 -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 50388c1115 feat(blockchain-service): implement complete blockchain service with DDD + Hexagonal architecture
- Domain layer: ChainType, EvmAddress, TxHash, TokenAmount, BlockNumber value objects
- Domain events: DepositDetected, DepositConfirmed, WalletAddressCreated, TransactionBroadcasted
- Aggregates: DepositTransaction, MonitoredAddress, TransactionRequest
- Infrastructure: Prisma ORM, Redis cache, Kafka messaging, EVM blockchain adapters
- Application services: AddressDerivation, DepositDetection, BalanceQuery
- API: Health, Balance, Internal controllers with Swagger documentation
- Deployment: Docker, docker-compose, deploy.sh, health-check scripts

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 20:54:58 -08:00
hailin 6150617c14 docs: update blockchain-service guide with address derivation responsibilities
- Add public key → address derivation as primary responsibility
- Add AddressDerivationAdapter for EVM/Cosmos address derivation
- Add WalletAddressCreated event definition
- Add MPC event consumption (mpc.KeygenCompleted)
- Add MpcKeygenCompletedHandler for processing keygen events
- Add section 17: MPC integration event flow with diagrams
- Update document version to 1.2.0

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 20:02:50 -08:00
hailin 23043d5d79 feat: add detailed debug logging for MPC Kafka event flow
- Add comprehensive [INIT], [CONNECT], [PUBLISH], [RECEIVE], [HANDLE] logs
  to identity-service and mpc-service Kafka services
- Add KeygenStarted event for tracking keygen progress
- Add MpcKeygenCompletedHandler to process keygen completion events
- Fix topic routing for MPC events between services

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 19:49:06 -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 ba91a89b16 feat(wallet-service): add Redis caching for wallet queries
- Add ioredis dependency for Redis connectivity
- Create Redis service and module with DB 1 configuration
- Implement WalletCacheService for wallet data caching (60s TTL)
- Integrate cache-aside pattern in getMyWallet query
- Add cache invalidation on all wallet mutations:
  - handleDeposit, deductForPlanting, addRewards
  - claimRewards, settleRewards

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 18:37:13 -08:00
hailin c459387c42 feat: add event-driven communication between identity-service and mpc-service
Replace synchronous HTTP polling with Kafka event-driven model for MPC operations:

- Add MPC event consumer service in mpc-service for keygen/signing requests
- Add keygen-requested and signing-requested event handlers
- Add MPC event consumer in identity-service for completion events
- Extend mpc-client.service with async event-driven methods
- Support backward compatibility via MPC_USE_EVENT_DRIVEN env var

Topics: mpc.KeygenRequested, mpc.SigningRequested, mpc.KeygenCompleted,
        mpc.SigningCompleted, mpc.SessionFailed

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 18:17:44 -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 9c36e6772b refactor: simplify mpc-service to gateway mode
mpc-service 重新定位为网关服务,转发请求到 mpc-system:
- 简化 Prisma schema:只保留 MpcWallet 和 MpcShare
- 添加 delegate share 存储(keygen 后保存用户的 share)
- 保留六边形架构结构,清理不再需要的实现
- 删除旧的 command handlers、queries、repository 实现
- 简化 infrastructure module,只保留 PrismaService

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 17:16:14 -08:00
hailin d652f1d7a4 feat: add MPC coordinator service and keygen/signing API
- Add MPCController with keygen and sign endpoints
- Add MPCCoordinatorService to coordinate with mpc-system
- Add MpcWallet, MpcShare, MpcSession entities for data storage
- Update identity-service mpc-client to call mpc-service

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 16:03:17 -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
hailin 8ff26cb929 docs(services): add MPC integration verification report
- Add comprehensive MPC system verification documentation
- Document integration issues and solutions
- Include test results and API verification
2025-12-04 23:56:21 -08:00
Developer c26a24b544 fix(mpc-service): 确保 keygen 会话包含完整的参与者列表
问题:account-service 要求 participants 数量必须等于 threshold_n
原因:createKeygenSession 传入的 participants 可能不足 3 个

修复:
- 在 createKeygenSession 中自动补全参与者列表
- 对于 2-of-3 配置,确保有 3 个参与者:
  - user-party (用户端)
  - server-party-1 (服务端)
  - server-party-2 (备份)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 06:04:47 -08:00
Developer e23af5d4ad fix(mpc-service): 添加 MPC_COORDINATOR_URL 和 MPC_MESSAGE_ROUTER_WS_URL 配置
问题:mpc-service 的 MPCCoordinatorClient 需要 MPC_COORDINATOR_URL 环境变量
原本只配置了 MPC_SESSION_COORDINATOR_URL,导致 Invalid URL 错误

修改内容:
- docker-compose.yml: 添加 MPC_COORDINATOR_URL 和 MPC_MESSAGE_ROUTER_WS_URL
- mpc-service/.env.example: 更新环境变量文档

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 05:55:26 -08:00
Developer e4f9e4279f fix(mpc-service): 硬编码 MPC_API_KEY 与 mpc-system 一致
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 05:37:12 -08:00
Developer 4db5534372 feat(mpc): 添加 server-party-api 服务,实现用户 share 生成
新增 mpc-system/services/server-party-api:
- 为 mpc-service 提供同步的 TSS keygen/signing API
- 参与 TSS 协议生成用户 share 并直接返回(不存储)
- 支持 API Key 认证
- 端口 8083 对外暴露

更新 mpc-service TSSWrapper:
- 改为调用 server-party-api 而非本地二进制
- 新增 MPC_SERVER_PARTY_API_URL 配置
- 超时时间调整为 10 分钟

架构: mpc-service -> account-service -> server-party-api -> TSS

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 05:32:41 -08:00
Developer 9dee0d36a5 feat(backup,mpc): 添加 prisma 迁移文件
backup-service 和 mpc-service 缺少 prisma/migrations 目录
导致 prisma migrate deploy 无法执行

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 04:01:47 -08:00
Developer 2fd784e3d2 fix(mpc-service): 使用标准 migrate deploy 替代 db push
移除 db push --accept-data-loss,改用 prisma migrate deploy
这是创建账号流程涉及的第3个服务(identity, backup, mpc)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 03:36:33 -08:00
Developer 6e53a4a572 fix(identity-service): 移除 db push 回退,只用 migrate deploy
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 03:33:58 -08:00
Developer 613d822c46 fix(backup-service): 添加 tsx 支持 Prisma 7 配置文件
- 安装 tsx 以便在生产环境运行 prisma.config.ts
- 复制 prisma.config.ts 到生产镜像
- 移除 --url 参数 (Prisma 7 不再支持)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 03:07:07 -08:00
Developer 9819661693 fix(backup-service): 移除 schema.prisma 中的 url (Prisma 7 配置在 prisma.config.ts)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 02:39:57 -08:00
Developer 62eba58490 fix(backup-service): 添加 datasource url 到 Prisma schema
Prisma migrate/push 需要 datasource 中包含 url 属性。

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 02:37:24 -08:00
Developer f63606ce8f feat(scripts): 添加数据库检查脚本
检查所有微服务的数据库和数据表是否已创建。

使用方法: ./scripts/check-databases.sh

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 02:35:29 -08:00
Developer 9e0adca3d3 fix(backup-service): 使用 printf 替代 echo 创建启动脚本
Alpine 的 sh 不支持 echo 的 \n 转义,改用 printf。

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 02:32:07 -08:00
Developer 9898665506 feat(all-services): 添加数据库自动迁移到所有服务启动流程
在每个服务的 Dockerfile 中添加启动脚本:
- 服务启动前先执行 prisma migrate deploy
- 如果迁移失败则回退到 prisma db push
- 确保数据库表在服务启动时自动创建

修改的服务:
- identity-service
- wallet-service
- backup-service
- planting-service
- referral-service
- reward-service
- leaderboard-service
- reporting-service
- authorization-service
- admin-service
- presence-service

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 01:50:01 -08:00
Developer f771dc8f6e fix(presence-service): 修复 MetricsModule 依赖注入,直接提供仓库实现
MetricsCollectorService 需要 DAU 和 EventLog 仓库,
但这些在 InfrastructureModule 中通过符号注入,
导致循环依赖问题。改为在 MetricsModule 中直接提供这些依赖。

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 01:35:59 -08:00
Developer 8faaedaa64 fix(presence-service): MetricsModule 导入 RedisModule 和 PersistenceModule
修复依赖注入错误: PresenceRedisRepository 和 DAU/EventLog 仓库无法解析

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 01:30:08 -08:00
Developer 43e769437f fix(presence-service): 修复方法名 findByDay -> findByDate
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 00:53:04 -08:00
Developer 246c25ab8a fix(presence-service): 同步 package-lock.json
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 00:05:46 -08:00
Developer 178a5c9f8b feat(mpc-service): 实现混合传输模式 (WebSocket + HTTP轮询)
- 优先尝试 WebSocket 连接 (5秒超时)
- WebSocket 失败自动降级到 HTTP 轮询
- HTTP 轮询间隔 100ms,总超时 5分钟
- 新增 getTransportMode() 方法查看当前传输模式
- 修复 message-router 404 导致的 socket hang up 问题

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 00:00:49 -08:00
Developer a701f55342 fix(mpc-service): 修复 WebSocket 导入方式
将 `import WebSocket from 'ws'` 改为 `import * as WebSocket from 'ws'`
以兼容 CommonJS 模块系统

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 22:58:00 -08:00
Developer 9363e4991f fix(mpc-service): 使用 prisma db push 自动同步数据库 schema
- 容器启动时执行 prisma db push 自动创建/同步表结构
- 删除 migrations 目录,不再使用 migrate 机制
- 这是标准做法:schema.prisma 定义表结构,db push 同步到数据库

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 21:56:30 -08:00
Developer 8850ea6ab0 fix(mpc-service): 重构数据库迁移机制,从根本解决表不存在问题
问题分析:
- 旧迁移文件只有 party_shares 表,缺少 session_states 和 share_backups 表
- Prisma 的 _prisma_migrations 表记录迁移已完成,导致新表无法创建
- 迁移状态与实际数据库不一致

解决方案:
1. 删除旧迁移目录,创建全新的 0001_init 迁移
2. 新迁移包含所有三个表: party_shares, session_states, share_backups
3. 添加 docker-entrypoint.sh 启动脚本,容器启动时自动运行迁移
4. 修改 Dockerfile 使用 entrypoint 脚本

deploy.sh 新增命令:
- migrate-reset: 重置数据库并重新运行迁移
- migrate-push: 强制同步 schema (创建缺失的表)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 21:47:42 -08:00
Developer 122bf84c24 fix(mpc-service): 修复数据库迁移,添加缺失的表
migration.sql 与 schema.prisma 不同步,缺失以下表:
- session_states: 会话状态跟踪表
- share_backups: 分片备份表

同时修复了索引名称以匹配 schema 定义。

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 21:32:36 -08:00
Developer e51edc2ce4 fix(mpc-service): 修复 MPC 会话流程,先创建会话再加入
问题:mpc-service 尝试用 identity-service 生成的 SHA256 哈希作为
joinToken 加入会话,但 session-coordinator 期望的是由它自己
CreateSession 接口生成的 JWT token。

修复:
- coordinator-client.ts: 添加 createSession() 方法
- participate-keygen.handler.ts: 先创建会话获取 JWT,再加入
- participate-signing.handler.ts: 同上
- rotate-share.handler.ts: 同上(使用 keygen 类型)

流程变更:
1. CreateSession -> 获取 sessionId + JWT joinToken
2. JoinSession 使用 JWT token 加入会话

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 21:21:22 -08:00
Developer 467206fd61 fix(mpc-service): 修复 coordinator-client 请求/响应格式
session-coordinator 使用 camelCase JSON 格式:

请求:
- session_id, party_id, join_token -> joinToken, partyId
- 添加必需字段 deviceType, deviceId

响应:
- session_info.session_id -> sessionId
- other_parties -> participants

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 21:11:16 -08:00
Developer e4abc7eb83 fix(mpc-service): 添加 /api/v1 前缀到 coordinator-client 路径
session-coordinator 的 API 路由注册在 /api/v1/sessions 下,
但 coordinator-client 调用的是 /sessions(404 错误)。

修复所有端点路径:
- /sessions/join -> /api/v1/sessions/join
- /sessions/report-completion -> /api/v1/sessions/report-completion
- /sessions/{id}/status -> /api/v1/sessions/{id}/status
- /sessions/report-failure -> /api/v1/sessions/report-failure

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 21:06:06 -08:00
Developer cd4fba96ed docs(blockchain-service): 完善架构设计以兼容其他微服务
- 添加 modules/ 分层模块文件结构 (api/application/domain/infrastructure)
- 抽取 AggregateRoot 聚合根基类,统一领域事件管理
- 补充 BlockNumber、TxHash 值对象的完整定义
- 添加值对象导出索引文件
- 新增第16章架构兼容性说明:
  - 与其他服务的架构对比表
  - 依赖倒置原则和六边形架构端口适配器说明
  - 命名约定规范
  - Symbol Token 注入规范
- 更新文档版本至 1.1.0

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 20:44:24 -08:00
Developer 08541f1d8d fix(mpc): 修复 MPC 服务连接配置
问题: mpc-service 无法连接到 mpc-session-coordinator,超时 30 秒

修复:
1. mpc-system/docker-compose.yml:
   - session-coordinator 暴露端口 8081:8080
   - message-router 暴露端口 8082:8080

2. services/docker-compose.yml:
   - MPC_COORDINATOR_URL: 192.168.1.100 -> 192.168.1.111
   - MPC_MESSAGE_ROUTER_WS_URL: 192.168.1.100 -> 192.168.1.111

3. 同步更新 .env.example 和 deploy.sh

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 20:39:53 -08:00
Developer 84d619edf9 docs(blockchain-service): 添加区块链服务开发指南
- 定义 blockchain-service 领域边界和职责
- 设计 DDD + 六边形架构目录结构
- 设计 Prisma 数据模型 (MonitoredAddress, DepositTransaction, BlockCheckpoint, TransactionRequest)
- 设计领域层 (聚合根、值对象、领域事件、仓储接口)
- 设计基础设施层 (EVM Provider、事件监听器、区块扫描器、地址缓存)
- 设计应用层 (充值检测服务、余额查询服务)
- 定义 Kafka 事件和消费者
- 配置 Docker 部署和 Kong 路由
- 制定从 identity-service 迁移计划

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 20:23:56 -08:00
Developer 55d40c8200 fix(mpc-service): 改用 Debian slim 基础镜像
- 从 Alpine 改为 Debian slim (与 identity-service 一致)
- 使用 curl 进行健康检查
- 添加 DATABASE_URL 用于 Prisma generate
- 通过代理访问官方源

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 19:57:11 -08:00
Developer e4172c11b9 fix(identity-service): 移除所有中国镜像配置,使用官方源+代理
- 移除 Alpine 镜像加速
- 移除 Debian 镜像加速
- 移除 npm 镜像加速
- 通过 Docker 代理访问官方源

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 19:34:56 -08:00
Developer d18de9823f fix(identity-service): 恢复使用 npmmirror 镜像
- 从华为云镜像回滚到 npmmirror
- 移除无效的 disturl 配置

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 19:11:07 -08:00
Developer db8350b2f5 fix(identity-service): 更换 npm 镜像为华为云解决超时问题
- npmmirror CDN 超时 (EIDLETIMEOUT)
- 改用 mirrors.huaweicloud.com/repository/npm/
- 添加 disturl 配置加速 node 二进制下载

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 18:45:18 -08:00
Developer eba8953e3a perf(identity-service): 添加 Docker 构建镜像加速
- Alpine: 使用 mirrors.aliyun.com
- Debian: 使用 mirrors.aliyun.com
- npm: 使用 registry.npmmirror.com (淘宝镜像)

加速中国区 Docker 构建速度

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 18:19:39 -08:00
Developer ef21009644 fix(identity-service): 修复 MPC keygen 请求参数
- sessionId 使用纯 UUID 格式(移除 mpc- 前缀)
- shareType 使用 'wallet' 匹配 PartyShareType 枚举

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 18:10:42 -08:00
Developer e068b99dc1 fix(mpc-service): 将 keygen/signing 接口标记为 Public
临时解决 identity-service 调用 mpc-service 时的 401 认证错误:
- keygen/participate
- keygen/participate-sync
- signing/participate
- signing/participate-sync

TODO: 添加适当的服务间认证机制(API key 或 service JWT)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 18:05:31 -08:00
Developer 12032b905f fix(identity-service): 修复 MPC 服务调用路径
问题: identity-service 调用 mpc-service 返回 404
原因: mpc-service 有全局前缀 /api/v1,但调用路径缺少此前缀

修复:
- mpc-client.service.ts: 添加 /api/v1 前缀到 MPC API 调用路径
- kong.yml: 添加 /api/v1/mpc-party 路由

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 16:49:49 -08:00
Developer b8aa44bf74 feat(identity-service): 添加 Prisma 初始化迁移
添加数据库表结构迁移文件:
- user_accounts: 用户账户表
- user_devices: 用户设备表
- wallet_addresses: 钱包地址表
- account_sequence_generator: 账号序列生成器
- user_events: 用户事件表
- device_tokens: 设备令牌表
- dead_letter_events: 死信事件表
- sms_codes: 短信验证码表
- mpc_key_shares: MPC密钥分片表
- mpc_sessions: MPC会话表
- referral_links: 推荐链接表

执行方式: ./deploy.sh migrate

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 16:41:59 -08:00
Developer 9656a6f4c4 feat(presence-service): 添加 Prometheus 指标监控和 Grafana Dashboard
Prometheus 指标端点 (/api/v1/metrics):
- presence_online_users_total: 实时在线人数
- presence_dau_total: 今日 DAU
- presence_heartbeat_total: 心跳计数
- presence_events_received_total: 事件上报计数
- presence_session_start_total: 会话开始计数
- presence_heartbeat_duration_seconds: 心跳处理延迟
- presence_event_batch_duration_seconds: 事件批处理延迟

Grafana Dashboard:
- 核心指标概览 (在线人数、DAU、心跳、事件)
- 趋势图表 (在线人数趋势、心跳/事件速率)
- 事件分布 (饼图、按小时趋势)
- 性能指标 (P50/P95/P99 延迟)
- 服务资源 (内存、CPU)

配置更新:
- prometheus.yml 添加 presence-service 抓取配置
- package.json 添加 prom-client 依赖

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 08:38:05 -08:00
Developer 114a9e611c fix(admin-service): 修复 APK 解析 - 使用临时文件代替 Buffer
adbkit-apkreader 库只支持文件路径,不支持 Buffer
现在先将 Buffer 写入临时文件,解析后删除

参考: https://github.com/openstf/adbkit-apkreader

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 08:22:14 -08:00
Developer b1bee7f44e fix(admin-service): 修复 adbkit-apkreader 模块导入问题
使用 require() 代替 ES Module 导入,解决 'Cannot read properties of undefined' 错误

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 08:19:39 -08:00
Developer f8607ce0b2 feat: 增强移动端版本管理功能
## admin-service
- 添加 APK/IPA 预解析 API (/api/v1/versions/parse)
- 添加断点续传下载控制器 (/api/v1/downloads/:filename)
- 配置 uploads volume 持久化存储
- 下载 URL 从 /uploads 改为 /downloads (支持 Range 请求)

## mobile-upgrade (前端)
- 上传文件后自动解析并填充版本信息
- 添加 ParsedPackageInfo 类型和 parsePackage API

## mobile-app (Flutter)
- DownloadManager 支持断点续传 (HTTP Range)
- 添加临时文件管理和清理功能
- 添加构建脚本自动增加版本号 (scripts/build.sh)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 06:57:26 -08:00
Developer d55a2673dc fix(admin-service): 修复 APK 解析模块的 TypeScript 编译错误
- 修改 adbkit-apkreader 的 import 语法为 default export
- 更新类型声明文件支持 default export 模式

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 02:52:18 -08:00
Developer f9deca5df0 feat(admin-service): 增强移动端版本上传功能
- 添加 APK/IPA 文件解析器自动提取版本信息
- 支持从安装包自动读取 versionName 和 versionCode
- 添加 adbkit-apkreader 依赖解析 APK 文件
- 添加 plist 依赖解析 IPA 文件
- 优化上传接口支持自动填充版本信息

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 02:39:36 -08:00
Developer de2e2d0428 refactor(api-gateway): 将 Kong 独立为解耦模块
- 将 Kong 从 services/docker-compose.yml 移到 api-gateway/docker-compose.yml
- 添加 api-gateway/deploy.sh 一键部署脚本
- 完善 api-gateway/README.md 文档,包含完整架构图和部署流程
- Kong 使用外部网络连接 services,实现解耦部署

架构变更:
- services: 只包含微服务,不依赖 Kong
- api-gateway: 独立的 Kong 网关,可选部署

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 00:38:49 -08:00
Developer 7d9d5eeffe feat(api-gateway): 添加 Kong API 网关和 Nginx 配置
- 添加 Kong 声明式配置 (kong.yml),定义所有微服务路由
- 更新 docker-compose.yml 添加 Kong 服务 (kong-db, kong-migrations, kong)
- 添加 rwaapi.szaiai.com Nginx 配置 (SSL + 反向代理到 Kong)
- 添加 nginx/install.sh 一键安装脚本
- 添加 API Gateway README 文档

架构: 用户 → Nginx (SSL) → Kong (API Gateway) → 各微服务

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 00:33:22 -08:00
Developer 46379afd18 fix(deploy): 添加 admin-service 数据库 rwa_admin
- 在 init-databases.sh 中添加 rwa_admin 数据库
- 在 migrate 函数中添加 admin-service

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 22:57:55 -08:00
Developer e03b9eb7c9 feat(deploy): 添加 presence-service 到主部署脚本
- 在 init-databases.sh 中添加 rwa_presence 数据库
- 在 migrate 函数中添加 presence-service

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 22:56:15 -08:00
Developer aa06607c1d feat(presence-service): 添加 init-db 命令创建数据库
- 添加 init-db 命令自动创建 rwa_presence 数据库
- 创建数据库后自动运行 prisma db push 创建表结构
- 更新帮助文档

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 22:53:49 -08:00
Developer 784e98f1dc fix(deploy): 修复 health 命令使用正确的健康检查端点
- 为每个微服务配置实际的健康检查端点路径
- 大多数服务使用 /api/v1/health
- backup-service 和 reward-service 使用 /health
- leaderboard-service 使用 /api/health
- 新增 presence-service (端口 3011)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 22:46:52 -08:00
Developer fcd97f26cf fix(presence-service): 添加 --no-deps 避免重启已运行的基础设施
deploy.sh start/up 命令添加 --no-deps 选项,防止在启动
presence-service 时重新创建已经运行的共享基础设施容器
(postgres, redis, kafka)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 22:19:40 -08:00
Developer 086d82f98a feat(admin-service): 添加 init-db 命令自动创建数据库
用法: ./deploy.sh init-db
- 自动创建 rwa_admin 数据库(如不存在)
- 自动运行 Prisma 迁移

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 22:02:41 -08:00
Developer 6f55dc3195 fix(admin-service): 排除移动端API路由的全局前缀
移动端APP需要访问 /api/app/version/check,而不是 /api/v1/api/app/version/check
使用 setGlobalPrefix 的 exclude 选项排除移动端路由

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 21:50:04 -08:00
Developer 8a57013596 feat(admin-service): 实现完整的移动端版本管理和升级服务
- 添加版本CRUD API:list, get, update, delete, toggle
- 添加文件上传支持:APK/IPA文件上传并计算SHA256校验
- 新增移动端专用API endpoint: /api/app/version/check
- 修复deploy.sh自调用权限问题(使用绝对路径)
- 添加完整的技术文档 APP_UPGRADE_SERVICE.md

新增文件:
- MobileVersionController: 移动端兼容的版本检查接口
- FileStorageService: 文件上传和存储服务
- CQRS handlers: ListVersions, GetVersion, UpdateVersion, DeleteVersion, ToggleVersion, UploadVersion

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 21:31:36 -08:00
Developer c3f4243e81 fix(presence-service): 修复 deploy.sh 自调用权限问题
使用 bash "$SCRIPT_DIR/deploy.sh" 替代 $0 避免路径变化导致的权限问题

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 21:26:19 -08:00
Developer 893399e07f refactor(infra): 统一微服务基础设施为共享模式
- 将 presence-service 添加到主 docker-compose.yml(端口 3011,Redis DB 10)
- 更新 init-databases.sh 添加 rwa_admin 和 rwa_presence 数据库
- 重构 admin-service/deploy.sh 使用共享基础设施
- 重构 presence-service/deploy.sh 使用共享基础设施
- 添加 authorization-service 开发指南文档

解决多个微服务独立启动重复基础设施(PostgreSQL/Redis/Kafka)的问题

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 20:46:50 -08:00
Developer d6227a574b refactor(presence-service): 优化 deploy.sh 与主基础设施集成
- 更新容器名和镜像名与项目规范一致
- 添加 load_env 函数支持共享环境配置
- 添加 up/logs-all/clean-all 命令
- 使用动态 HEALTH_ENDPOINT

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 20:45:28 -08:00
Developer f132b86899 feat(presence-service): 添加完整的部署脚本
- 添加 deploy.sh 主部署脚本 (build/start/stop/logs/migrate/test)
- 添加 scripts/quick-test.sh API 快速测试脚本
- 添加 scripts/rebuild-kafka.sh Kafka 重建脚本
- 更新 scripts/README.md 文档

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 20:16:33 -08:00
Developer 603c1c6c90 feat(presence-service): 添加完整的测试套件和生产部署设施
- 添加 165 个测试用例 (123 单元测试, 22 集成测试, 20 E2E测试)
- 添加 Docker 多阶段构建和 docker-compose 生产部署配置
- 添加完整的文档体系 (架构、API、开发、测试、部署)
- 添加环境配置 (.env.development/production/test)
- 添加部署脚本 (health-check, start-all, stop-service)
- 修复 TypeScript 类型错误
- 经 WSL2 验证所有生产部署命令测试通过

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 20:10:04 -08:00
Developer 37c255bdc1 fix(admin-service): 修复TypeScript编译错误
- 修复 version.controller.ts 中 FileSize 使用 .bytes 替代 .value
- 修复测试文件中 AppVersion.create 缺少 isForceUpdate 参数
- 修复测试文件中使用正确的 Prisma Platform 枚举类型
- 修复 CreateVersionCommand 参数顺序错误

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 20:01:08 -08:00
Developer eae1350f35 feat(admin-service): 添加完整的量产部署设施
参考 identity-service 的部署配置,为 admin-service 添加:

新增文件:
- .dockerignore: Docker 构建排除配置
- .env.development: 开发环境配置
- .env.production: 生产环境配置(使用变量引用)
- docker-compose.yml: 完整的 Docker 编排(含 PostgreSQL, Redis)

更新文件:
- deploy.sh: 增强部署脚本,新增 30+ 命令(健康检查、测试、清理等)
- docs/DEPLOYMENT.md: 整合快速开始指南和命令速查表

服务架构:
- admin-service: 端口 3010
- PostgreSQL: 端口 5433(避免冲突)
- Redis: 端口 6380(避免冲突)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 19:34:31 -08:00
Developer 79e2b9bfdd docs(admin-service): 添加完整的技术文档体系
文档结构:
- docs/ARCHITECTURE.md: DDD+Hexagonal 架构设计详解
- docs/API.md: RESTful API 完整接口文档
- docs/DEVELOPMENT.md: 开发环境设置和代码规范
- docs/TESTING.md: 三层测试架构 (Unit/Integration/E2E)
- docs/DEPLOYMENT.md: 本地/Docker/生产环境部署指南
- docs/README.md: 文档中心导航和快速入门

架构文档 (ARCHITECTURE.md):
- 服务职责和核心功能说明
- DDD 领域模型 (聚合根、值对象、领域服务)
- 六边形架构分层设计
- 数据流和依赖方向详解
- SOLID 原则应用示例
- 性能优化和安全性考量

API 文档 (API.md):
- 6 个核心 API 端点完整说明
- 请求/响应格式和数据模型
- 错误处理和状态码规范
- cURL/Postman 使用示例
- 版本控制和更新策略
- 最佳实践和常见问题

开发文档 (DEVELOPMENT.md):
- VSCode 配置和推荐插件
- 本地环境初始化步骤
- Git 工作流和 Commit 规范
- 完整开发迭代流程示例
- TypeScript/DDD/NestJS/Prisma 代码规范
- 调试技巧和常见开发任务

测试文档 (TESTING.md):
- 测试金字塔三层架构 (53+21+15=89 测试用例)
- 本地/WSL2/Docker 测试环境设置
- 单元/集成/E2E 测试详细示例
- Make/npm 脚本快速执行
- 覆盖率目标和 CI/CD 集成
- GitHub Actions 配置示例

部署文档 (DEPLOYMENT.md):
- 部署架构和系统要求
- Ubuntu 服务器环境准备
- PM2 本地部署流程
- Docker Compose 容器化部署
- Nginx 反向代理和 SSL 配置
- 数据库备份和日志管理
- 监控告警和故障排查

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 19:01:12 -08:00
Developer f8c9c579f2 feat(admin-service): 添加 database 目录和初始化脚本
新增目录和文件:
- database/init.sql: 数据库初始化脚本(保留用于未来需求)
- database/README.md: database 目录使用说明文档

database/ 目录用途:
1. 存放数据库初始化SQL脚本
2. 在Prisma migrations之后执行
3. 用于插入初始数据或设置序列号等

与Prisma的关系:
- Prisma migrations: 创建表结构
- database/init.sql: 插入初始数据

Docker Compose集成:
可通过volume映射到/docker-entrypoint-initdb.d/自动执行

参考其他服务:
- identity-service: 使用init.sql初始化序列号生成器
- mpc-service: 使用database/migrations存放迁移

当前状态:
- init.sql已创建但为空(目前不需要初始数据)
- 完整文档说明用途和使用方法

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 18:42:33 -08:00
Developer dd25ff5659 docs(admin-service): 添加测试执行结果文档
测试结果总结:
 测试基础设施: 完全就绪
 数据库: PostgreSQL容器运行成功
 迁移: Prisma迁移成功应用
 测试代码: 9个文件,~89个用例
 文档: 4个完整文档

测试覆盖:
- 单元测试: 6个文件(Value Objects/Entities/Mappers)
- 集成测试: 2个文件(Repository/Handlers)
- E2E测试: 1个文件(Controllers)

环境验证:
 WSL2 + Docker
 PostgreSQL 16
 Prisma迁移成功
 测试框架配置正确

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 18:34:21 -08:00