Commit Graph

72 Commits

Author SHA1 Message Date
hailin ed6b48562a feat(pricing): 认种树动态定价涨价系统(总部运营成本压力涨价)
基础价 15831 USDT/棵不变,新增 HQ_PRICE_SUPPLEMENT 加价项全额归总部(S0000000001)。
支持手动调价+自动周期涨价,所有变更可审计,移动端动态展示价格及涨价预告。

- admin-service: TreePricingConfig/ChangeLog 表 + Service + Controller + 定时任务
- planting-service: 正式认种和预种订单快照 priceSupplement,动态价格校验
- reward-service: HQ_PRICE_SUPPLEMENT 分配类型,涨价金额直接入总部账户
- admin-web: Settings 页面新增定价配置区间(手动调价/自动涨价/变更历史)
- mobile-app: TreePricingService + 动态价格加载 + 涨价预告展示

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 03:02:56 -08:00
hailin d29454fc74 feat(admin-web): 省团队收益汇总明细增加来源用户列并修复账户名称显示
问题描述:
1. 省团队收益汇总的详细明细中缺少收益来源用户信息
2. 账户类型显示为数字(如7440000)而不是省名称

修改内容:

1. 后端 reward-service (reward-application.service.ts)
   - getRewardEntriesByType 方法返回值新增 sourceAccountSequence 字段
   - 该字段表示触发此收益的用户账户序列号(来自认种用户)

2. 后端 reporting-service (reward-service.client.ts)
   - RewardEntryDTO 接口新增 sourceAccountSequence 字段

3. 前端 admin-web
   - system-account.types.ts: RewardEntryDTO 新增 sourceAccountSequence 字段
   - system-account.types.ts: getAccountDisplayName 函数支持7开头的省团队账户
     示例:7440000 → "广东省团队 (7440000)"
   - SystemAccountsTab.tsx: 详细明细表格新增"来源用户"列

效果:
- 省团队收益明细现在显示:时间、账户(省名称)、来源用户、订单号、金额、状态
- 账户列显示格式:"{省名}省团队 ({账户序列号})"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 17:35:22 -08:00
hailin 95cb3510aa fix(reward-service): 修复 getExpiredRewardsEntries 的 userId 类型转换
将 bigint 类型的 userId 转换为 number 类型以匹配返回类型定义

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 22:38:50 -08:00
hailin e9c0196d68 feat(admin-web): 添加过期收益明细查询功能
- reward-service: 添加 getExpiredRewardsEntries API 查询过期收益明细
- reporting-service: 添加过期收益明细转发接口和类型定义
- admin-web: 过期收益统计区域新增"查看明细"按钮
  - 支持分页浏览过期收益记录
  - 支持按权益类型筛选
  - 显示过期时间、用户ID、账户、权益类型、金额、订单号

回滚方式:删除各服务中标注 [2026-01-07] 的代码块

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 22:36:31 -08:00
hailin 4df9895863 feat(admin-web): 完善系统账户报表收益统计显示
- 分享引荐收益汇总:显示所有状态(PENDING/SETTLEABLE/SETTLED/EXPIRED)的完整数据
- 面对面结算:改为从 wallet_ledger_entries 表查询 SPECIAL_DEDUCTION 类型
- 新增按状态分组统计表格和详细分类卡片

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 20:11:09 -08:00
hailin 84fb6b8500 fix(reward-service): 修复字段名错误 sourceOrderId → sourceOrderNo
数据库中的字段名是 sourceOrderNo,修复 getRewardEntriesByType 和
getFeeEntriesDetailed 方法中的字段映射错误。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 09:27:25 -08:00
hailin 4b5270f130 feat(admin-web): 添加系统账户收益类型详细明细列表功能
为系统账户报表中的5个收益类型汇总Tab添加详细明细查看功能:
- 手续费账户汇总:点击"查看详细明细"展开手续费记录列表
- 省团队收益汇总:展开省团队权益记录列表
- 市团队收益汇总:展开市团队权益记录列表
- 分享引荐收益汇总:展开分享权益记录列表
- 社区收益汇总:展开社区权益记录列表

后端变更:
- reward-service: 添加 getRewardEntriesByType、getFeeEntriesDetailed 方法
- reward-service: 添加 /statistics/reward-entries-by-type、/statistics/fee-entries-detailed 接口
- reporting-service: 添加对应的聚合接口

前端变更:
- 添加 RewardEntryDTO、RewardEntriesResponse 类型定义
- 添加 getRewardEntriesByType、getFeeEntriesDetailed API 方法
- FeeAccountSection、RewardTypeSummarySection 组件添加详细明细列表展开功能
- 添加分页支持(每页20条)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 09:19:15 -08:00
hailin 99b725db0a feat(admin-web): 添加系统账户收益类型汇总统计功能
在数据统计-系统账户中新增5个统计Tab:
- 手续费账户汇总:统计成本费、运营费、总部社区基础费、RWAD底池注入
- 省团队收益汇总:统计省团队权益收益
- 市团队收益汇总:统计市团队权益收益
- 分享引荐收益汇总:统计分享权益收益
- 社区收益汇总:统计社区权益收益

后端变更:
- reward-service: 添加 getRewardsSummaryByType、getAllRewardTypeSummaries 方法
- reporting-service: 聚合收益类型汇总统计接口

前端变更:
- 添加 RewardTypeSummary、FeeAccountSummary 类型定义
- 添加 getRewardTypeSummaries API 方法
- 添加 FeeAccountSection、RewardTypeSummarySection 组件

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 08:54:35 -08:00
hailin ec71121907 fix(reward-service): 修复 WalletServiceClient 未正确解析 wallet-service 响应格式的 Bug
问题原因:
wallet-service 使用全局 TransformInterceptor 拦截器,会将所有响应包装成:
{ success: true, data: { success: boolean, ... }, timestamp: "..." }

原代码直接读取外层的 success 字段(始终为 true),导致即使业务失败
(内层 data.success = false)也被误判为成功。

具体案例:
用户 D25122700024 点击结算时,wallet-service 因余额不足返回:
{ success: true, data: { success: false, error: "Insufficient..." }, ... }
reward-service 误读为成功,导致奖励被标记为 SETTLED 但钱包余额未变更。

修复内容:
1. settleToBalance: 解析 response_data.data 获取真实业务结果
2. confirmPlantingDeduction: 同上
3. allocateFunds: 同上

所有方法现在会:
- 使用 response_data.data || response_data 兼容包装和非包装格式
- 严格检查 data.success !== true 来判断业务是否成功
- 失败时记录详细错误日志

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 03:38:00 -08:00
hailin 6e395ce58c feat(reporting): add system account report aggregation feature
## Changes
- Add system account report aggregation APIs in reporting-service
- Add internal statistics APIs in wallet-service, reward-service, authorization-service
- Add system accounts tab in admin-web statistics page
- Enhanced metadata in reward entries for traceability

## Backend Changes
- wallet-service: Add offline settlement summary and system accounts balances APIs
- reward-service: Add expired rewards summary API
- authorization-service: Add fixed accounts list, region accounts summary APIs
- reporting-service: Add HTTP clients and aggregation service for system account reports

## Frontend Changes
- admin-web: Add SystemAccountsTab component with fixed accounts, region summaries,
  offline settlement stats, and expired rewards display

## Rollback Instructions
Each file includes rollback comments with [2026-01-04] tag marking new additions.
To rollback: delete files marked as new, remove code sections marked with date comments.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 22:06:58 -08:00
hailin 17b9c09381 feat(ledger): add detailed ledger entry views with source tracking
实现账本流水详情功能,支持点击查看各类型流水的详细信息。

## reward-service 后端

### 数据库
- 新增 `source_account_sequence` 字段到 `reward_ledger_entries` 表
- 添加索引 `idx_source_account_seq` 提升查询性能
- 字段可空,兼容历史数据

### 领域层
- `RewardSource` 值对象新增 `sourceAccountSequence` 属性
- `RewardCalculationService` 传递 `sourceAccountSequence`

### 应用层
- 新增 `getSettlementHistory` 方法查询结算历史
- 新增 `SettlementRecordRepository` 仓储实现

### API层
- 新增 `GET /settlements/history` 接口
- 新增 `SettlementHistoryQueryDTO` 和 `SettlementHistoryDTO`

## mobile-app 前端

### 服务层
- `RewardService` 新增结算历史相关模型和方法:
  - `SettlementHistoryItem` 结算记录模型
  - `SettlementRewardEntry` 关联奖励条目模型
  - `getSettlementHistory()` 获取结算历史

- `WalletService` 新增:
  - `LedgerEntry.payloadJson` 字段及辅助方法
  - `counterpartyAccountSequence` 获取转账对手方ID
  - `counterpartyUserId` 获取转账对手方用户ID
  - `transferFee` 获取转账手续费

### 账本详情页
- 结算流水详情:显示结算金额、币种、涉及奖励明细(含来源用户)
- 提现流水详情:显示提现订单信息、状态、手续费等
- 转账流水详情:显示转入来源/转出目标用户信息

### 交互优化
- REWARD_SETTLED、WITHDRAWAL、TRANSFER_IN、TRANSFER_OUT 类型可点击
- 使用底部弹窗展示详情,支持滚动查看长列表

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 20:09:17 -08:00
hailin 036696878f feat(settlement): implement settle-to-balance with detailed source tracking
Add complete settlement-to-balance feature that transfers settleable
earnings directly to wallet USDT balance (no currency swap). Key changes:

Backend (wallet-service):
- Add SettleToBalanceCommand for settlement operations
- Add settleToBalance method to WalletAccountAggregate
- Add settleToBalance application service with ledger recording
- Add internal API endpoint POST /api/v1/wallets/settle-to-balance

Backend (reward-service):
- Add settleToBalance client method for wallet-service communication
- Add settleRewardsToBalance application service method
- Add user-facing API endpoint POST /rewards/settle-to-balance
- Build detailed settlement memo with source user tracking per reward

Frontend (mobile-app):
- Add SettleToBalanceResult model class
- Add settleToBalance() method to RewardService
- Update pending_actions_page to handle SETTLE_REWARDS action
- Add completion detection via settleableUsdt balance check

Settlement memo now includes detailed breakdown by right type with
source user accountSequence for each reward entry, e.g.:
  结算 1000.00 绿积分到钱包余额
  涉及 5 笔奖励
    - SHARE_RIGHT: 500.00 绿积分
        来自 D2512120001: 288.00 绿积分
        来自 D2512120002: 212.00 绿积分

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 04:29:38 -08:00
hailin 3d42c3602d fix(reward-service): 权益分配memo显示触发用户ID
所有权益类型的memo现在统一显示"来自用户xxx的认种"格式:
- 省团队权益:来自用户xxx的认种
- 省区域权益:来自用户xxx的认种
- 市团队权益:来自用户xxx的认种
- 市区域权益:来自用户xxx的认种
- 社区权益:来自用户xxx的认种

修改前只显示"xx权益已激活",现在与分享权益格式保持一致

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 04:18:35 -08:00
hailin f711d54eed chore(reward-service): 调整系统费用分配 - 成本费+80, 总部基础费-80 2025-12-26 04:07:41 -08:00
hailin e95ac15605 fix(reward-service): 添加奖励分配幂等性检查
- distributeRewards 方法添加幂等性检查,防止同一订单重复分配奖励
- distributeRewardsForExpiredContract 方法同样添加幂等性检查
- 通过 findBySourceOrderNo 检查订单是否已分配过奖励

修复问题:recovery job 重复触发导致同一订单奖励被多次分配

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 10:42:01 -08:00
hailin 714ce42e4f feat(contract-signing): 添加电子合同签署功能及单点配置优化
- planting-service: 添加合同签署任务管理和超时检测
  - 新增 ContractSigningTask 领域模型
  - 添加 24 小时合同签署超时定时任务
  - 支付后资金保持冻结,由 referral-service 统一确认扣款

- referral-service: 单点配置 CONTRACT_SIGNING_ENABLED
  - 新增 ContractSigningHandler 处理合同签署/超时事件
  - 新增 WalletServiceClient 调用钱包服务确认扣款
  - planting.created 处理后根据配置决定是否等待合同签署

- reward-service: 移除 CONTRACT_SIGNING_ENABLED 配置
  - 扣款确认由 referral-service 在发送事件前完成
  - 保持奖励分配逻辑不变

配置说明:
- CONTRACT_SIGNING_ENABLED=true (默认): 等待合同签署后分配奖励
- CONTRACT_SIGNING_ENABLED=false: 立即分配奖励(原有流程)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 20:12:12 -08:00
hailin b4f685e25f fix(reward-service): 添加 BatchMonthlyEarningsRequest DTO 的 class-validator 装饰器
修复 authorization-service 调用 /internal/monthly-earnings/batch 接口时返回 400 错误的问题。
原因是 reward-service 使用了 ValidationPipe,但 DTO 类缺少必要的验证装饰器。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 05:22:34 -08:00
hailin 2f5ca85106 feat(authorization/reward): 实现火柴人排名本月收益显示功能
- reward-service: 添加批量查询月度收益内部接口
  - 新增 InternalController 提供 /internal/monthly-earnings/batch 端点
  - 在 RewardApplicationService 添加 batchGetMonthlyEarnings 方法
  - 支持按账户序列号、月份、权益类型批量查询可结算收益
  - 统计分享权益(SHARE_RIGHT)、省团队权益(PROVINCE_TEAM_RIGHT)、市团队权益(CITY_TEAM_RIGHT)

- authorization-service: 集成 reward-service 获取月度收益
  - 新增 RewardServiceClient 用于调用 reward-service 内部接口
  - 修改 getStickmanRanking 方法,调用 reward-service 获取月度收益
  - 省团队查询省团队权益+分享权益,市团队查询市团队权益+分享权益
  - monthlyEarnings 字段现在显示真实的月度可结算收益

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 05:04:55 -08:00
hailin 86d3a3f6a2 perf(docker): 优化Dockerfile构建,避免最后chown整个目录
- 在build阶段提前创建用户和设置目录权限
- 使用--chown=nestjs:nodejs复制文件
- 删除chown -R nestjs:nodejs /app

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 19:31:58 -08:00
hailin 701deb1e27 fix(test): 修复测试文件 TypeScript 类型错误
authorization-service:
- UserId.create 第二个参数 accountSequence 由 BigInt 改为 string
- mockAuthorizationRoleRepository 添加缺失的方法
- TeamStatistics mock 对象添加 selfPlantingCount 和 subordinateTeamPlantingCount

reward-service:
- accountSequence 由 BigInt 改为 string 类型
- 方法调用参数名由 userId 改为 accountSequence

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 06:44:28 -08:00
hailin 943fd9efe9 chore: 提交所有未提交的修改
包括:
- admin-service: 系统配置功能
- authorization-service: 自助授权申请功能
- planting-service: 资金分配服务
- reward-service: 奖励计算服务
- admin-web: 用户管理和设置页面
- mobile-app: 授权、认证、路由等功能

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 06:09:43 -08:00
hailin cf27e55c45 fix: 修正 sourceOrderNo 属性访问路径 2025-12-17 06:58:21 -08:00
hailin 36074948d7 feat(reward): 可结算列表改为从 reward-service 读取
将前端可结算奖励列表的数据源从 wallet-service 改为 reward-service:
- 后端:在 reward-service 添加 GET /rewards/settleable 接口
- 前端:修改 getSettleableRewards() 调用 /rewards/settleable
- 前端:更新 SettleableRewardItem 字段映射 (rightType, claimedAt, sourceOrderNo, memo)

解决权益收益(社区权益、市区域权益)无法在可结算列表显示的问题。
遵循单一数据源原则,reward-service 是奖励的权威数据源。

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

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

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 01:43:47 -08:00
hailin 090c8b747e fix(reward): 修复 accountSequence 转 userId 时字母前缀导致的 BigInt 转换失败
问题描述:
- 社区权益激活后,用户收不到奖励
- 错误: SyntaxError: Cannot convert D25121400002 to a BigInt
- 原因: accountSequence 格式为 D25121400002 (D+日期+序号),直接 BigInt() 转换失败

修改方案:
- 新增 parseAccountSequenceToUserId() 辅助方法
- 如果 accountSequence 以字母开头,去掉第一个字符后再转 BigInt
- 影响 5 个方法: calculateProvinceTeamRight, calculateProvinceAreaRight,
  calculateCityTeamRight, calculateCityAreaRight, calculateCommunityRight

技术背景:
- accountSequence 格式: D25121400002 (用户) / S0000000001 (固定系统账户) / 9440000 (省系统)
- 省市系统账户在 authorization-service 动态创建,identity-service 中不存在
- reward-service 的 userId 字段实际业务中不被使用 (查询用 accountSequence)

潜在隐患:
1. userId 字段存储的不是 identity-service 中的真实 userId
   - D25121400002 -> 25121400002 (不是真实的自增 userId)
   - S0000000001 -> 1 (恰好匹配固定系统账户)
   - 9440000 -> 9440000 (省系统账户,本无字母前缀)
2. 如果未来 reward-service 需要与 identity-service 关联查询,可能出现问题
3. 建议后续考虑: 将 userId 改为可选字段,或完全移除该字段依赖

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 08:18:23 -08:00
hailin c7d54da49f fix(reward): 修复调用 authorization-service 时传递 userId 而非 accountSequence 的问题
- IAuthorizationServiceClient 接口参数类型从 userId: bigint 改为 accountSequence: string
- authorization-service.client.ts 调用时使用正确的 accountSequence 格式
- calculateCommunityRight/calculateProvinceTeamRight/calculateCityTeamRight 方法增加 sourceAccountSequence 参数

此修复确保 reward-service 调用 authorization-service 时传递正确的用户标识格式(如 D25121400006),
而不是数字形式的 userId(如 7),使 authorization-service 能正确查找社区授权记录。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 06:48:58 -08:00
hailin 367e34f3a6 fix(reward): 待领取奖励转可结算使用accountSequence
- 添加 claimPendingRewardsForAccountSequence 方法
- event-consumer 改用 accountSequence 查找待领取奖励
- 修复上家认种后待领取奖励不能转为可结算的问题

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 05:58:19 -08:00
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 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 e557b00c24 fix(reward-service): 修复 targetType 类型断言 2025-12-12 19:16:15 -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 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 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 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 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 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 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 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 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 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 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 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