Commit Graph

27 Commits

Author SHA1 Message Date
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 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 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 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 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 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 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 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 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 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 747e4ae8ef refactor(mpc-system): migrate to party-driven architecture with PartyID-based routing
- Remove Address field from PartyEndpoint (parties connect to router themselves)
- Update K8s Discovery to only manage PartyID and Role labels
- Add Party registration and SessionEvent protobuf definitions
- Implement PartyRegistry and SessionEventBroadcaster domain logic
- Add RegisterParty and SubscribeSessionEvents gRPC handlers
- Prepare infrastructure for party-driven MPC coordination

This is the first phase of migrating from coordinator-driven to party-driven
architecture following international MPC system design patterns.
2025-12-05 08:11:28 -08:00
Developer 9769012795 feat(reward-service): Implement complete reward service with DDD architecture
## Core Features
- 6 types of reward calculation (Share Right 500U, Province Team 20U,
  Province Area 15U+1% hashpower, City Team 40U, City Area 35U+2% hashpower,
  Community Right 80U)
- 24-hour countdown mechanism for pending rewards
- Reward settlement with multi-currency support (BNB/OG/USDT/DST)
- Automatic reward expiration with scheduled tasks

## Domain Layer
- RewardLedgerEntry aggregate root with state machine
  (PENDING -> SETTLEABLE -> SETTLED, PENDING -> EXPIRED)
- RewardSummary aggregate for user reward overview
- Value objects: Money, Hashpower, RewardSource, RewardStatus, RightType
- Domain events: RewardCreated, RewardClaimed, RewardSettled, RewardExpired
- Domain services: RewardCalculationService, RewardExpirationService

## Application Layer
- RewardApplicationService for orchestrating business workflows
- RewardExpirationScheduler for automatic expiration processing

## Infrastructure Layer
- PostgreSQL persistence with Prisma ORM
- Redis caching integration
- Kafka event publishing/consuming
- External service clients (Referral, Authorization, Wallet)

## API Layer
- REST endpoints: /health, /rewards/summary, /rewards/details,
  /rewards/pending, /rewards/settle
- JWT authentication with Passport.js
- Swagger/OpenAPI documentation

## Testing (77 tests, 100% pass rate)
- 43 unit tests for domain logic (Money, Hashpower, aggregates)
- 20 integration tests for application services
- 14 E2E tests for API endpoints
- Docker Compose test infrastructure (PostgreSQL, Redis, Kafka)

## Documentation
- docs/ARCHITECTURE.md - DDD architecture overview
- docs/API.md - REST API documentation
- docs/DEVELOPMENT.md - Developer guide
- docs/TESTING.md - Testing guide
- docs/DEPLOYMENT.md - Deployment guide

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 01:57:40 -08:00