Commit Graph

668 Commits

Author SHA1 Message Date
hailin b705c6aa91 feat(wallet-service): 新增分享权益池账户S0000000005
- 新增 S0000000005 分享权益池系统账户 (user_id = -5)
- 修改 reward-service: 无推荐人的分享权益(500 USDT/棵)进入分享权益池
- 与总部社区账户(S0000000001)分离,便于单独追踪无推荐人的分享权益

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 18:53:21 -08:00
hailin 947e81b58d chore(wallet-service): 确保 @nestjs/schedule 依赖正确配置
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 17:13:21 -08:00
hailin 2af44e5854 feat(authorization-service): 实现社区权益月度考核及级联激活/停用功能
- 新增 benefitValidUntil、lastAssessmentMonth、monthlyTreesAdded 字段追踪月度考核
- 实现级联激活:当社区权益激活时,自动激活所有上级社区的权益
- 实现级联停用:当月度考核不达标时,级联停用该社区及所有上级社区
- 新增定时任务:每天凌晨3点检查过期社区权益,每月1号凌晨重置月度树数
- 权益有效期为当前月+下月末

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 07:23:46 -08:00
hailin 846915badc fix(wallet-service): 使用事务确保 settleUserPendingRewards 原子性
- 将 pending_rewards 状态更新和 wallet_accounts 余额更新包装在 Prisma $transaction 中
- 修复 Bug 4: pending_rewards 被标记为 SETTLED 但 settleable_usdt 未更新的问题
- 添加 PrismaService 依赖注入
- 同时减少 pendingUsdt/pendingHashpower,增加 settleableUsdt/settleableHashpower
- 记录 REWARD_TO_SETTLEABLE 类型的流水

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 06:58:07 -08:00
hailin c93f43546e fix(planting-service): PlantingOrderPaidEvent 添加 accountSequence 字段
Bug 3 修复: wallet-service 结算待领取奖励时需要 accountSequence

- PlantingOrderPaidEvent 事件 data 添加 accountSequence 字段
- markAsPaid(accountSequence) 方法接收并传递 accountSequence
- payOrder 调用 markAsPaid 时传入 accountSequence
- 更新相关单元测试

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 06:13:59 -08:00
hailin 28864e6160 fix(wallet-service): 修复待领取奖励显示和结算触发问题
Bug 1: allocateToUserWallet 同步更新 wallet_accounts.pending_usdt
- 写入 pending_rewards 表时同步调用 wallet.addPendingReward()
- 修复前端待领取金额显示为 0 的问题

Bug 2: Kafka 事件类型匹配兼容 planting-service 格式
- 支持 eventName 字段解析 (planting-service 使用)
- 支持 data 字段解析 (planting-service 使用)
- 新增 PlantingOrderPaid 事件类型支持
- 修复用户认种后待领取无法转换为可结算的问题

其他: 定时任务频率改为每分钟一次 (测试用途)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 05:51:28 -08:00
hailin e4389a5733 fix(wallet-service): 优化资金分配逻辑 - 区分直接到账和待领取
- SHARE_RIGHT (分享权益): 写入 pending_rewards 表,24小时待领取
- PROVINCE_TEAM_RIGHT/PROVINCE_AREA_RIGHT/CITY_TEAM_RIGHT/CITY_AREA_RIGHT: 直接到账
- COMMUNITY_RIGHT (社区权益): 进入总部社区账户 S0000000001,直接到账

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 04:51:34 -08:00
hailin 737fc3bb3c fix(wallet-service): allocateToUserWallet 改用 pending_rewards 表
- 移除 wallet.addPendingReward() 调用(旧方案,更新 wallet_accounts.pending_usdt)
- 改用 PendingReward.create() + pendingRewardRepo.save() 写入 pending_rewards 表
- 支持 7+省代码(省团队)和 6+市代码(市团队)账户格式

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 03:53:23 -08:00
hailin 8f81c46d75 feat: 省市团队账户及待领取奖励逐笔追踪
1. authorization-service:
   - 省团队权益分配改用系统省团队账户 (7+provinceCode)
   - 市团队权益分配改用系统市团队账户 (6+cityCode)
   - 无推荐链时不再进总部,而是进对应团队账户

2. wallet-service:
   - 新增 pending_rewards 表支持逐笔追踪待领取奖励
   - ensureRegionAccounts 同时创建区域账户和团队账户
   - 新增 getPendingRewards API 查询待领取列表
   - 新增 settleUserPendingRewards 用户认种后结算
   - 新增 processExpiredRewards 定时处理过期奖励
   - PlantingCreatedHandler 监听认种事件触发结算
   - ExpiredRewardsScheduler 每小时处理过期奖励

账户格式:
- 省区域: 9+provinceCode (如 9440000)
- 市区域: 8+cityCode (如 8440100)
- 省团队: 7+provinceCode (如 7440000)
- 市团队: 6+cityCode (如 6440100)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 03:32:47 -08:00
hailin 4d3290f029 fix(wallet-service): 修复系统账户资金分配功能
问题:
- 认种订单支付后,系统账户(成本费、运营费、总部社区、RWA底池)余额始终为0
- reward-service 正确计算分配,但 wallet-service 未实际执行系统账户的资金转移

根本原因:
1. allocateToSystemAccount() 方法只打印日志,未执行任何数据库操作(遗留的 TODO)
2. UserId 值对象不允许负数,而系统账户 user_id 为负数(-1 到 -4)

修复内容:

1. wallet-application.service.ts - allocateToSystemAccount()
   - 实现完整的系统账户资金分配逻辑
   - 通过 findByAccountSequence() 获取系统账户
   - 调用 addAvailableBalance() 直接增加可用余额
   - 创建 SYSTEM_ALLOCATION 类型的流水记录

2. wallet-account.aggregate.ts
   - 新增 addAvailableBalance(amount: Money) 方法
   - 用于系统账户直接增加余额(无需待领取/过期机制)

3. ledger-entry-type.enum.ts
   - 新增 SYSTEM_ALLOCATION 枚举值,用于系统账户分配流水

4. user-id.vo.ts
   - 移除负数校验,允许系统账户使用负数 user_id
   - 系统账户约定:-1(总部社区)、-2(成本费)、-3(运营费)、-4(RWA底池)

验证结果(认种1棵树=2199 USDT):
- S0000000001 总部社区: 9 USDT ✓
- S0000000002 成本费账户: 400 USDT ✓
- S0000000003 运营费账户: 300 USDT ✓
- S0000000004 RWA底池: 800 USDT ✓

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

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

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

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 01:14:56 -08:00
hailin ebbf2d971a feat: 跨服务使用 accountSequence 查询推荐链 + 系统账户动态创建
1. reward-service 使用 accountSequence 查询推荐链
   - event-consumer.controller.ts: 优先使用 accountSequence 作为用户标识
   - reward-calculation.service.ts: 使用 accountSequence 查询推荐关系
   - referral-service.client.ts: 参数从 userId 改为 accountSequence

2. referral-service 支持 accountSequence 格式的推荐链查询
   - referral.controller.ts: /chain/:identifier 同时支持 userId 和 accountSequence

3. wallet-service 系统账户动态创建
   - wallet-application.service.ts: allocateToUserWallet 使用 getOrCreate
   - 支持省区域(9+code)和市区域(8+code)账户自动创建
   - 新增 migration seed: 4个固定系统账户 (S0000000001-S0000000004)

4. planting-service 事件增强
   - 事件中添加 accountSequence 字段用于跨服务关联

系统账户格式:
- S0000000001: 总部社区 (基础费9U + 兜底权益)
- S0000000002: 成本费账户 (400U)
- S0000000003: 运营费账户 (300U)
- S0000000004: RWAD底池账户 (800U)
- 9+provinceCode: 省区域系统账户 (动态创建)
- 8+cityCode: 市区域系统账户 (动态创建)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 23:22:01 -08:00
hailin d20ff9e9b5 fix: 修复 wallet-service 支持 accountSequence 格式及订单状态机
1. wallet-service/internal-wallet.controller.ts:
   - getBalance: 支持 accountSequence (D开头) 和 userId (纯数字) 两种格式

2. wallet-service/wallet-application.service.ts:
   - freezeForPlanting: 修复 BigInt 转换错误,优先按 accountSequence 查找钱包
   - confirmPlantingDeduction: 同上
   - unfreezeForPlanting: 同上
   - getMyWallet: 支持 userId='0' 的情况(仅通过 accountSequence 查询)

3. planting-service/planting-order.aggregate.ts:
   - schedulePoolInjection: 状态检查从 FUND_ALLOCATED 改为 PAID
   - 原因: 资金分配已移至 reward-service 异步处理

修复问题: "Cannot convert D25121300006 to a BigInt"

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 22:35:18 -08:00
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 552b15e26b fix(mobile): 修复序列号类型转换错误
accountSequence 格式已从数字改为字符串 (D + YYMMDD + 5位序号)
- profile_page.dart: `as int?` → `as String?`
- mining_page.dart: `as int?` → `as String?`

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 14:22:59 -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 3eeef11197 fix(mobile): filter out revoked authorizations in profile display
Previously, revoked authorizations were still shown in the profile page
because UserAuthorizationSummary.fromList() did not filter by status.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 04:35:30 -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 26427443fe feat(mobile): add auth-province and auth-city company display in profile page
- Add authProvinceCompany and authCityCompany to RoleType enum
- Update UserAuthorizationSummary to support all role types
- Update profile page to display all authorization types

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 22:20:25 -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 033268deb9 feat(mobile): improve UX with QR scanning and Huawei compatibility fixes
- Disable Impeller rendering engine to fix video playback on Huawei devices
- Update splash screen text from "榴莲女皇" to "榴莲皇后" and use app logo
- Make referral code input scan-only (disable manual input) on guide page 5
- Add "import mnemonic" entry on guide page 5 for account recovery
- Replace paste button with QR scanner in USDT withdraw address input
- Add camera and gallery QR scanning support for wallet addresses

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 05:39:58 -08:00
hailin 62b6714760 chore(mobile): add splash video asset
Add splash.mp4 video file for the splash screen

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 04:27:51 -08:00
hailin 7bf88cd6a8 feat(mobile): replace splash screen with video player
- Add video_player dependency for video playback
- Create assets/videos directory for splash video
- Implement video splash screen with:
  - Full-screen video playback (splash.mp4)
  - Skip button appears after 1 second
  - Fallback to logo view if video fails to load
  - Auto-navigate when video completes
- Video file should be placed at: assets/videos/splash.mp4

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 04:23:04 -08:00
hailin 3644c04521 fix(mobile): auto-show confirm dialog when planting location is saved
When user has previously saved province/city selection:
- Automatically show confirm dialog on page load
- Skip the 5-second countdown timer
- Hide countdown text in dialog when skipCountdown is true
- User can directly confirm and proceed with planting

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 04:08:57 -08:00
hailin ca5e903724 feat(mobile): add USDT withdraw feature with Google Authenticator verification
1. Trading page:
   - Add withdraw/transfer button below DST balance section
   - Display USDT balance from wallet-service
   - Navigate to withdraw page on button tap

2. Withdraw USDT page (new):
   - Network selection (KAVA / BSC)
   - Wallet address input with paste support
   - Amount input with max button
   - Fee calculation (0.1%) and actual amount preview
   - Input validation and notice section

3. Withdraw confirm page (new):
   - Transaction details summary
   - Google Authenticator 6-digit code verification
   - Success dialog with navigation back to trading

4. Routes:
   - Add /withdraw/usdt and /withdraw/confirm routes
   - Configure route parameters for WithdrawUsdtParams

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 03:47:22 -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 7320900289 fix(mobile): sync trading page settleable data with profile page
Trading page now fetches settleableUsdt from reward-service instead
of wallet-service to ensure data consistency with profile page.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 03:28:02 -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