Commit Graph

1354 Commits

Author SHA1 Message Date
hailin 461b11b310 fix(kong): 修复contribution-service路由配置
- 将service URL从 /api/v2/contributions 改为根路径
- 设置 strip_path: false 直接透传请求路径
- 前端和后端现在都使用 /api/v2/contribution(单数)

前端请求: /api/v2/contribution/accounts/{id}
Kong转发: http://contribution-service:3020/api/v2/contribution/accounts/{id}

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:44:49 -08:00
hailin 849f346891 fix(contribution-service): 修复控制器路由路径与前端API不匹配
将控制器路由从 /contributions 改为 /contribution,
与前端 api_endpoints.dart 中定义的路径保持一致。

完整路径: /api/v2/contribution/accounts/{accountSequence}

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:42:10 -08:00
hailin ace1e8673b feat(deploy-mining): rebuild命令增加服务重启功能
rebuild命令现在会在构建完成后自动停止旧服务并启动新服务,
而不仅仅是编译镜像。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:18:25 -08:00
hailin a539b33dff fix(contribution-service): 优化账户查询API返回有意义的业务状态
- 新增 ContributionAccountStatus 枚举区分三种状态:
  - ACTIVE: 账户正常,有算力数据
  - INACTIVE: 用户存在但暂无认种记录
  - USER_NOT_FOUND: 账户不存在
- 移除 404 错误响应,统一返回 200 并通过 status 和 message 字段描述状态
- 为不同状态提供友好的中文提示信息

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:13:38 -08:00
hailin 5ee6caa190 fix(contribution-service): 修复Kafka消息BigInt序列化错误
JSON.stringify无法序列化BigInt,添加自定义replacer将BigInt转换为字符串

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:57:21 -08:00
hailin a40e314c94 fix(contribution-service): 修复adoption handler事务嵌套问题
将upsertSyncedAdoption和calculateForAdoption分离为两个独立操作,
避免嵌套事务导致内层事务看不到外层事务尚未提交的数据

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:52:00 -08:00
hailin 5006a5a170 fix(contribution-service): 修复synced_adoptions.status字段长度
1.0 planting_orders.status是VARCHAR(30),2.0需要匹配以避免数据截断错误

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:45:08 -08:00
hailin 5f76108579 fix(contribution-service): 修复CDC消息解析以支持Debezium扁平化格式
Debezium配置了ExtractNewRecordState转换,消息格式是扁平化的:
- 元数据字段使用__前缀(__op, __table, __source_ts_ms, __deleted)
- 业务数据字段直接在根级别
- 修改handleMessage方法正确解析扁平化格式
- 更新CDCEvent接口以匹配实际消息结构

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:39:09 -08:00
hailin 4b55c63e71 fix(contribution-service): 修复CDC同步字段映射,支持完整同步referral数据
主要更改:
1. synced_referrals表增加referrer_user_id和original_user_id字段
   - 1.0的referral_relationships表只有referrer_id(user_id),没有referrer_account_sequence
   - 保存原始user_id以便后续解析推荐人的account_sequence

2. 修复referral-synced.handler字段映射
   - 正确处理1.0的user_id、referrer_id、ancestor_path字段
   - ancestor_path从BigInt[]数组转换为逗号分隔的字符串

3. 修复cdc-event-dispatcher表名注册
   - 使用正确的表名: referral_relationships, planting_orders
   - 移除不需要的user_accounts注册

4. 更新docker-compose.2.0.yml
   - 添加CDC_TOPIC_REFERRALS配置
   - 移除未使用的CDC_TOPIC_PAYMENTS

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:27:01 -08:00
hailin 05a8168a31 fix(contribution-service): 修复CDC同步配置,使用正确的planting-service topic
- 修改CDC topic为cdc.planting.public.planting_orders
- 更新healthcheck使用api/v2
- 更新handler适配planting_orders表字段

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:18:37 -08:00
hailin a14daae222 fix: update mining-service package-lock.json
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:12:48 -08:00
hailin 0e05139c01 fix(contribution-service): 统一使用api/v2前缀
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:05:42 -08:00
hailin 73381a4376 fix: 修复contribution-service路由映射
- Kong: /api/v2/contribution -> /api/v1/contributions (strip_path)
- mining-app: 添加/accounts前缀匹配controller路径

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:04:21 -08:00
hailin 849fa77df0 fix(auth-service): 允许synced_legacy_users的phone和password_hash为空
- 修改schema让phone和passwordHash字段可为空
- 添加migration: 20260111083500_allow_nullable_phone_password
- CDC consumer使用null替代空字符串
- 支持同步没有手机号/密码的系统账户

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 08:37:02 -08:00
hailin 6caae7c860 fix(auth-service): 跳过无手机号/密码的系统账户CDC同步
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 08:33:39 -08:00
hailin a749a3b9e1 fix: 修复auth-service CDC配置和API路由
- 修复docker-compose.2.0.yml中CDC_TOPIC_USERS为正确的topic名称
- 添加CDC_ENABLED环境变量
- 更新Kong配置auth-service路由使用strip_path
- 更新mining-app API端点匹配v2服务路由
- 更新mining-app baseUrl指向Kong网关根路径

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 08:29:16 -08:00
hailin 36d7b7ebfe fix(docker-compose.2.0): 修复healthcheck路径为/api/v1/health并增加start_period到60s
docker-compose.yml里的healthcheck配置会覆盖Dockerfile里的配置

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 07:25:30 -08:00
hailin 1b425e09c9 fix(contribution-service): 添加@Public装饰器到HealthController以绕过JWT认证
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 07:02:17 -08:00
hailin 673e5ff772 fix(dockerfiles): 修复2.0服务健康检查路径
- 修正健康检查URL从 /health 到 /api/v1/health(因为设置了全局前缀)
- 增加 start-period 从 10s 到 60s,给服务更多启动时间

受影响服务:
- contribution-service
- mining-service
- mining-admin-service
- trading-service
- mining-wallet-service

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 06:45:44 -08:00
hailin f26a796244 fix(contribution-service): 修复migration为完整初始化脚本
将增量migration改为完整的初始化migration,包含所有表的CREATE TABLE语句。
原migration使用ALTER TABLE假设表已存在,但这是服务的第一个migration文件。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 06:31:24 -08:00
hailin 6261679f5a feat(contribution-service, mining-service): 添加18级待解锁算力字段和挖矿收益分配表
contribution-service:
- 添加15级层级待解锁字段 (level1-15Pending)
- 添加3档加成待解锁字段 (bonusTier1-3Pending)
- 添加解锁状态追踪字段 (hasAdopted, directReferralAdoptedCount等)
- 重构ContributionAccountAggregate支持新字段结构
- 更新repository和query处理effectiveContribution

mining-service:
- 添加MiningRewardAllocation表追踪每日挖矿收益分配明细
- 添加DailyMiningRewardSummary表汇总账户每日收益
- 添加HeadquartersPendingReward表记录未解锁算力收益归总部明细
- 创建初始migration文件

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 06:16:15 -08:00
hailin 4bb995f2c2 feat(auth-service,mining-app): 实现完整认证流程和CDC用户同步
auth-service:
- 添加DTO验证装饰器(IsString, IsNotEmpty, Matches, MinLength)
- 添加短信验证码登录(loginBySms)方法
- 修复CDC Consumer字段映射匹配1.0 user_accounts表
- 更新CDC topic为cdc.identity.public.user_accounts

mining-app (Flutter):
- 新增auth_remote_datasource实现真实API调用
- 新增登录页面(密码/短信切换)和注册页面
- 替换splash_page中的mock登录为真实状态检查
- 添加token自动注入拦截器到ApiClient
- 配置生产环境API指向Kong网关

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 05:29:48 -08:00
hailin 25ad627377 feat(mining-admin-service): 添加/auth/profile接口
前端dashboard layout需要获取当前用户信息,添加GET /auth/profile接口

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 01:01:49 -08:00
hailin 86f2c85f8d fix(mining-admin-service): 修复LoginDto验证装饰器缺失
添加 @IsString() 和 @IsNotEmpty() 装饰器到 LoginDto,
修复 ValidationPipe forbidNonWhitelisted 导致的400错误

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 00:54:37 -08:00
hailin fe7dda396f fix(kong): 修复mining-admin-service路由映射
使用strip_path:true并将url设为/api/v1,
使Kong路由 /api/v2/mining-admin/* -> 服务 /api/v1/*

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 00:50:29 -08:00
hailin 341e319fd3 feat(mining-admin-web): 配置生产环境API指向Kong网关
修改:
1. frontend/mining-admin-web/src/lib/api/client.ts
   - 使用环境变量 NEXT_PUBLIC_API_URL 配置 API baseURL
   - 开发环境默认使用 /api 代理

2. frontend/mining-admin-web/.env.production (新增)
   - NEXT_PUBLIC_API_URL=https://rwaapi.szaiai.com/api/v2/mining-admin

3. backend/api-gateway/kong.yml
   - CORS origins 添加 https://madmin.szaiai.com
   - CORS origins 添加 http://localhost:3100

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 00:28:17 -08:00
hailin 42e6b5c27c feat(gateway): 添加2.0服务路由到Kong和nginx配置
Kong网关:
- 添加contribution-service-v2 (3020)
- 添加mining-service-v2 (3021)
- 添加trading-service-v2 (3022)
- 添加mining-admin-service (3023)
- 添加auth-service-v2 (3024)
- 添加mining-wallet-service (3025)

Nginx (madmin.szaiai.com):
- 添加/api/代理到mining-admin-service:3023
- 支持CORS预检请求

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 00:22:23 -08:00
hailin 51456373a9 feat(2.0-services): 添加所有服务的初始Prisma migrations
使用 prisma migrate diff 生成初始数据库迁移脚本:
- mining-admin-service: 管理后台相关表及CDC同步表
- auth-service: 用户认证相关表
- trading-service: 交易相关表
- mining-wallet-service: 钱包相关表

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 00:06:46 -08:00
hailin 7f72c1e1ec fix(2.0-services): 修复InfrastructureModule导出PrismaService问题
NestJS不允许模块导出未在providers中声明的服务。
将exports中的PrismaService改为PrismaModule(因为PrismaModule已导出PrismaService)。

修复服务:
- mining-admin-service
- auth-service

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 00:00:50 -08:00
hailin c4ee8ed6a9 fix(2.0-services): 更新package-lock.json并添加bcrypt编译支持
- mining-admin-service: 更新package-lock.json以包含bcrypt依赖
- auth-service: Dockerfile添加python3 make g++用于编译bcrypt

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:53:11 -08:00
hailin c032f30f7b fix(mining-admin-service): 添加bcrypt依赖和编译工具
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:49:26 -08:00
hailin 319a787c43 fix(2.0-dockerfiles): 添加openssl解决Prisma兼容性问题
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:46:14 -08:00
hailin 576aad8691 fix(deploy-mining): rebuild默认不使用--no-cache,需显式指定
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:40:08 -08:00
hailin c1de1daea8 fix(2.0-dockerfiles): 使用printf替代echo解决alpine兼容性问题
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:37:29 -08:00
hailin 1c3e7809ad fix(docker-compose.2.0): 使用external连接1.0网络services_rwa-network
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:31:53 -08:00
hailin 86091097a6 fix(docker-compose.2.0): 使用bridge驱动自建网络而非external
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:28:41 -08:00
hailin d3fecc42c1 fix(2.0-services): 优化所有Dockerfile使用--chown避免chown -R
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:23:57 -08:00
hailin 81f8422758 fix(mining-admin-service): 优化Dockerfile使用--chown避免chown -R
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:22:34 -08:00
hailin 0467e17032 fix(docker-compose.2.0): 移除对外部基础设施服务的depends_on
2.0服务使用external network连接1.0的基础设施,不需要depends_on

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:18:20 -08:00
hailin 0a433eca40 . 2026-01-11 15:14:25 +08:00
hailin a36bdcdda5 fix(deploy-mining): 使用docker compose替代npm进行构建和部署
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 23:11:42 -08:00
hailin ca55a81263 feat(mining-wallet-service): 添加独立钱包管理微服务
- 新增 mining-wallet-service 完整实现,100% 与 1.0 系统隔离
- 支持系统账户:总部、运营、省公司、市公司、手续费、热钱包、冷钱包
- 支持池账户:份额池、黑洞池、流通池
- 支持用户钱包:算力钱包、代币存储钱包、绿积分钱包
- 实现用户-区域映射(独立于 1.0)
- 集成 KAVA 区块链:提现、充值、DEX Swap
- 所有交易记录包含交易对手信息(counterparty)
- 使用 Outbox 模式确保事件可靠发布

feat(mining-admin-service): 添加 mining-wallet-service CDC 同步

- 新增 13 个 Synced 同步表接收钱包服务数据
- 新增 wallet-sync.handlers.ts 处理钱包服务事件
- 更新 cdc-sync.service.ts 注册钱包服务事件处理器

chore(mining-service, trading-service): 为池账户添加 counterparty 跟踪字段

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 22:21:08 -08:00
hailin ee5f841034 fix(outbox): 实现指数退避重试策略,最大延迟3小时
修复Outbox事件发布的重试机制:

1. 更新Prisma Schema (mining-service, trading-service):
   - 添加OutboxStatus枚举 (PENDING, PUBLISHED, FAILED)
   - 添加topic、key、status、retryCount、maxRetries、lastError等字段
   - 添加publishedAt、nextRetryAt时间戳
   - 优化索引 (status, nextRetryAt, createdAt)

2. 更新OutboxRepository (mining-service, trading-service):
   - findPendingEvents(): 查询待处理且到达重试时间的事件
   - markAsPublished(): 标记事件已发布
   - markAsFailed(): 实现指数退避算法 (30s基础, 最大3小时)
   - deletePublished(): 清理已发布的旧事件

3. 更新OutboxScheduler (auth/mining/trading-service):
   - 使用指数退避: 30s, 60s, 120s, 240s, ... 最大10800s (3小时)
   - 记录重试次数和错误信息
   - 达到最大重试次数后标记为FAILED

指数退避公式: delay = min(30s * 2^(retryCount-1), 3h)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 21:08:57 -08:00
hailin 28ad8c2e2f feat(2.0-services): 为auth/mining/trading服务添加Outbox事件发布机制
- auth-service:
  - 添加Kafka生产者模块和服务
  - 添加Redis服务用于分布式锁
  - 添加OutboxScheduler定时发布Outbox事件到Kafka
  - 更新InfrastructureModule为全局模块

- mining-service:
  - 添加Kafka生产者服务
  - 添加OutboxRepository用于管理Outbox事件
  - 添加OutboxScheduler定时发布事件

- trading-service:
  - 添加Kafka生产者服务
  - 添加OutboxRepository用于管理Outbox事件
  - 添加OutboxScheduler定时发布事件

所有服务的Outbox调度器:
- 每30秒发布待处理的事件到Kafka
- 每天凌晨3点清理7天前已处理的事件
- 使用Redis分布式锁确保多实例部署时只有一个实例处理

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 20:54:37 -08:00
hailin 15a5fb6c14 feat(mining-admin-service): 添加CDC同步和完整用户管理API
## Prisma Schema 更新
- 添加 CDC 同步表:SyncedUser, SyncedContributionAccount, SyncedMiningAccount, SyncedTradingAccount
- 添加系统数据同步表:SyncedMiningConfig, SyncedDailyMiningStat, SyncedDayKLine, SyncedCirculationPool
- 添加 CDC 进度跟踪:CdcSyncProgress, ProcessedEvent

## CDC 消费者模块
- CdcConsumerService: Kafka 消费者,支持 Debezium CDC 和服务间事件
- CdcSyncService: 同步处理器,从 auth/contribution/mining/trading 服务同步数据

## 新增 API 端点
### 用户管理 (/api/v1/users)
- GET /users - 用户列表(分页、搜索、过滤)
- GET /users/:accountSequence - 用户详情
- GET /users/:accountSequence/contributions - 算力记录
- GET /users/:accountSequence/mining-records - 挖矿记录
- GET /users/:accountSequence/orders - 交易订单

### 系统账户 (/api/v1/system-accounts)
- GET /system-accounts - 系统账户列表
- GET /system-accounts/summary - 系统账户汇总

### 仪表盘增强 (/api/v1/dashboard)
- GET /dashboard - 统计数据(新增用户/算力/挖矿/交易统计)
- GET /dashboard/realtime - 实时数据
- GET /dashboard/stats - 统计数据(别名)

## Docker Compose 更新
- 添加 Kafka 依赖和 CDC topic 配置
- 添加与 auth-service 的依赖关系

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 20:36:21 -08:00
hailin 6ffde0f4c6 refactor(docker): 2.0系统共享1.0基础设施并保持完全隔离
- 网络: 使用共享的 rwa-network (external)
- 数据库: 连接 postgres:5432,使用独立数据库名
- Redis: 连接 redis:6379,使用 DB 10-14 分区隔离
- Kafka: 连接 kafka:29092,仅消费 CDC 事件(单向同步)
- 服务依赖: 添加 postgres/redis/kafka 健康检查依赖

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 20:01:15 -08:00
hailin 821c70bf38 feat(docker): 添加 2.0 系统 Docker 部署支持
为所有 2.0 服务添加 Dockerfile 和 docker-compose 配置:

后端服务:
- contribution-service (3020) - 算力服务
- mining-service (3021) - 挖矿服务
- trading-service (3022) - 交易服务
- mining-admin-service (3023) - 管理后台 API
- auth-service (3024) - 用户认证服务

前端服务:
- mining-admin-web (3100) - 管理后台前端

Docker 配置:
- docker-compose.2.0.yml: 独立的 2.0 系统编排文件
- 多阶段构建优化镜像大小
- 健康检查确保服务可用性
- 服务依赖顺序正确

部署脚本更新:
- deploy-mining.sh 使用 docker-compose.2.0.yml
- 添加 mining-admin-web 服务别名 (web, admin-web)
- 更新服务端口配置

使用方式:
  cd backend/services
  docker-compose -f docker-compose.2.0.yml up -d

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 19:31:02 -08:00
hailin f7278b6196 feat(auth-service): 添加用户认证服务2.0
实现完整的用户认证服务,支持1.0用户迁移和2.0新用户注册:

功能特性:
- 用户注册(生成V2格式accountSequence: 15位)
- 密码登录(支持V1迁移用户和V2用户)
- V1用户首次登录自动迁移到2.0系统
- 短信验证码发送/验证(注册/登录/重置密码/更换手机号)
- 密码管理(重置密码、修改密码)
- KYC实名认证(提交/审核资料)
- JWT认证(Access Token + Refresh Token)

技术架构:
- DDD六边形架构(Domain/Application/Infrastructure/API)
- Prisma ORM + PostgreSQL
- CDC消费者同步1.0用户数据
- Outbox模式发布领域事件
- NestJS ThrottlerModule限流

数据模型:
- User: 2.0用户表(含KYC字段)
- SyncedLegacyUser: CDC同步的1.0用户(只读)
- RefreshToken: 刷新令牌
- SmsVerification: 短信验证码
- DailySequenceCounter: 每日序号计数器
- OutboxEvent: 发件箱事件

AccountSequence格式:
- V1: D + YYMMDD + 5位序号 = 12字符
- V2: D + YYMMDD + 8位序号 = 15字符

服务端口:3024
数据库:rwa_auth

同时更新deploy-mining.sh添加auth-service支持。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 18:50:59 -08:00
hailin c8c2e63da6 feat(mining): 增强部署脚本支持单服务操作
## 新增功能

### 单服务操作
- `up [service]` - 启动全部或指定服务
- `down [service]` - 停止全部或指定服务
- `restart [service]` - 重启全部或指定服务
- `build [service] [--no-cache]` - 构建全部或指定服务
- `rebuild [service]` - 等同于 build --no-cache

### 服务别名
- `contrib`, `contribution` -> contribution-service
- `mining` -> mining-service
- `trading` -> trading-service
- `admin` -> mining-admin-service

### 单服务数据库操作
- `db-create [service]` - 创建全部或指定服务的数据库
- `db-migrate [service]` - 运行全部或指定服务的迁移
- `db-reset [service]` - 重置全部或指定服务的数据库

### 构建功能增强
- `--no-cache` 选项清除 dist/ 和 node_modules/.cache
- 自动运行 npm install
- 自动生成 Prisma client
- 编译 TypeScript

### 状态显示增强
- 显示服务 PID
- 通过端口检测运行状态
- 健康检查端点验证

## 使用示例

```bash
./deploy-mining.sh up mining          # 仅启动 mining-service
./deploy-mining.sh restart contrib    # 重启 contribution-service
./deploy-mining.sh build trading --no-cache  # 清除缓存重新构建
./deploy-mining.sh logs admin 200     # 查看最后200行日志
./deploy-mining.sh db-reset mining    # 仅重置 mining-service 数据库
```

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 18:12:38 -08:00
hailin 7c3bf4f068 feat(mining): 添加 2.0 挖矿系统独立部署管理脚本
添加 deploy-mining.sh 脚本用于管理 2.0 挖矿生态系统,
该系统与 1.0 完全隔离,可随时重置而不影响 1.0。

## 功能

### 服务管理
- up/down/restart - 启动/停止/重启 2.0 服务
- status - 查看服务状态
- logs [service] - 查看日志
- build - 构建服务

### 数据库管理
- db-create - 创建 2.0 数据库
- db-migrate - 运行 Prisma 迁移
- db-reset - 删除并重建数据库(危险操作)
- db-status - 查看数据库状态

### CDC 同步管理
- sync-reset - 重置 CDC 消费者偏移量到开始位置
- sync-status - 查看 CDC 消费者组状态

### 完整重置
- full-reset - 完整系统重置
  1. 停止所有 2.0 服务
  2. 删除所有 2.0 数据库
  3. 重建数据库
  4. 运行迁移
  5. 重置 CDC 偏移量
  6. 重启服务(从 1.0 重新同步)

### 健康监控
- health - 检查所有组件健康状态
- stats - 显示系统统计信息

## 2.0 服务
- contribution-service (3020)
- mining-service (3021)
- trading-service (3022)
- mining-admin-service (3023)

## 2.0 数据库
- rwa_contribution
- rwa_mining
- rwa_trading
- rwa_mining_admin

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 18:08:16 -08:00
hailin a17f408653 feat(mining-ecosystem): 添加挖矿生态系统完整微服务与前端
## 概述
为榴莲生态2.0添加完整的挖矿系统,包含3个后端微服务、1个管理后台和1个用户端App。

---

## 后端微服务

### 1. mining-service (挖矿服务) - Port 3021
**核心功能:**
- 积分股每日分配(基于算力快照)
- 每分钟定时销毁(进入黑洞)
- 价格计算:价格 = 积分股池 ÷ (100.02亿 - 黑洞 - 流通池)
- 全局状态管理(黑洞量、流通池、价格)

**关键文件:**
- src/application/services/mining-distribution.service.ts - 挖矿分配核心逻辑
- src/application/schedulers/mining.scheduler.ts - 定时任务调度
- src/domain/services/mining-calculator.service.ts - 分配计算
- src/infrastructure/persistence/repositories/black-hole.repository.ts - 黑洞管理

### 2. trading-service (交易服务) - Port 3022
**核心功能:**
- 积分股买卖撮合
- K线数据生成
- 手续费处理(10%买入/卖出)
- 流通池管理
- 卖出倍数计算:倍数 = (100亿 - 销毁量) ÷ (200万 - 流通池量)

**关键文件:**
- src/domain/services/matching-engine.service.ts - 撮合引擎
- src/application/services/order.service.ts - 订单处理
- src/application/services/transfer.service.ts - 划转服务
- src/domain/aggregates/order.aggregate.ts - 订单聚合根

### 3. mining-admin-service (挖矿管理服务) - Port 3023
**核心功能:**
- 系统配置管理(分配参数、手续费率等)
- 老用户数据初始化
- 系统监控仪表盘
- 审计日志

**关键文件:**
- src/application/services/config.service.ts - 配置管理
- src/application/services/initialization.service.ts - 数据初始化
- src/application/services/dashboard.service.ts - 仪表盘数据

---

## 前端应用

### 1. mining-admin-web (管理后台) - Next.js 14
**技术栈:**
- Next.js 14 + React 18
- TailwindCSS + Radix UI
- React Query + Zustand
- ECharts 图表

**功能模块:**
- 登录认证
- 仪表盘(实时数据、价格走势)
- 用户查询(算力详情、挖矿记录、交易订单)
- 系统配置管理
- 数据初始化任务
- 审计日志查看

### 2. mining-app (用户端App) - Flutter 3.x
**技术栈:**
- Flutter 3.x + Dart
- Riverpod 状态管理
- GoRouter 路由
- Clean Architecture (3层)

**功能模块:**
- 首页资产总览
- 实时收益显示(每秒更新)
- 贡献值展示(个人/团队)
- 积分股买卖交易
- K线图与价格显示
- 个人中心

---

## 架构文档
- docs/mining-ecosystem-architecture.md - 系统架构总览
  - 服务职责与端口分配
  - 数据流向图
  - Kafka Topics 定义
  - 跨服务关联(account_sequence)
  - 配置参数说明
  - 开发顺序建议

---

## .gitignore 更新
- 添加 Flutter/Dart 构建文件忽略
- 添加 iOS/Android 构建产物忽略
- 添加 Next.js 构建目录忽略
- 添加 TypeScript 缓存文件忽略

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 17:45:46 -08:00
hailin eaead7d4f3 feat(contribution-service): 添加算力管理微服务
## 概述
为榴莲生态2.0添加 contribution-service 微服务,负责算力计算、分配和快照管理。

## 架构设计
- 采用 DDD + Hexagonal Architecture (六边形架构)
- 使用 NestJS 框架 + Prisma ORM
- 通过 Kafka CDC (Debezium) 从 user-service 同步数据
- 使用 accountSequence (而非 userId) 进行跨服务关联

## 核心功能模块

### 1. Domain Layer (领域层)
- ContributionAccountAggregate: 算力账户聚合根
- ContributionRecordAggregate: 算力记录聚合根
- ContributionAmount: 算力金额值对象 (基于 Decimal.js)
- DistributionRate: 分配比例值对象
- ContributionSourceType: 算力来源类型枚举 (PERSONAL/TEAM_LEVEL/TEAM_BONUS)

### 2. Application Layer (应用层)
- ContributionCalculationService: 算力计算核心服务
  - 个人算力: 认种金额 × 10
  - 团队等级奖励: 基于直推有效认种人数
  - 团队极差奖励: 多级分销算法
- SnapshotService: 每日算力快照服务
- CDC Event Handlers: 处理用户、认种、引荐关系同步事件

### 3. Infrastructure Layer (基础设施层)
- Prisma Repositories:
  - ContributionAccountRepository
  - ContributionRecordRepository
  - SyncedDataRepository (同步数据)
  - OutboxRepository (发件箱模式)
  - SystemAccountRepository
  - UnallocatedContributionRepository
- Kafka CDC Consumer: 消费 Debezium CDC 事件
- Redis: 缓存支持
- UnitOfWork: 事务管理

### 4. API Layer (接口层)
- ContributionController: 算力查询接口
- SnapshotController: 快照管理接口
- HealthController: 健康检查

## 数据模型 (Prisma Schema)
- ContributionAccount: 算力账户
- ContributionRecord: 算力记录 (支持过期)
- DailyContributionSnapshot: 每日快照
- SyncedUser/SyncedAdoption/SyncedReferral: CDC 同步数据
- OutboxEvent: 发件箱事件
- SystemContributionAccount: 系统账户
- UnallocatedContribution: 未分配算力

## TypeScript 类型修复
- 修复所有 Repository 接口与实现的类型不匹配
- 修复 ContributionAmount.multiply() 返回值类型
- 修复 isZero getter vs method 问题
- 修复 bigint vs string 类型转换
- 统一使用 items/total 返回格式
- 修复 Prisma schema 字段名映射 (unallocType, contributionBalance 等)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 17:39:25 -08:00
hailin bc73b078bd fix(wallet-service): 将最小划转金额从100改为5
与前端配置保持一致

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 09:51:06 -08:00
hailin d79fd9273b fix(admin-service): 修复uploads目录权限问题 2026-01-09 02:14:37 -08:00
hailin 4d944b06e5 fix(admin-service): 添加uploads目录的volume持久化配置
问题:admin-service重新部署后,上传的APK文件会丢失
原因:主docker-compose.yml中admin-service未配置volume挂载,
      导致容器重建时/app/uploads目录数据丢失

修复:
- 添加admin_uploads_data volume挂载到/app/uploads
- 添加UPLOAD_DIR环境变量
- 在volumes部分声明admin_uploads_data

影响范围:仅影响admin-service的文件存储持久化

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 21:00:31 -08:00
hailin 45736c4daf fix(admin-service): 修复用户数据CDC同步使用userId导致的数据不一致问题
问题原因:
- 旧的Kafka事件消费者和CDC消费者同时运行
- 旧消费者写入的数据userId可能为0
- CDC消费者使用userId作为upsert条件,导致唯一键冲突失败
- 用户的nickname和kycStatus等信息没有正确同步

修复方案:
- upsert方法改用accountSequence作为唯一键
- CDC消费者的handleUpdate使用accountSequence检查和更新
- 更新时同时修复可能错误的userId
- 新增existsByAccountSequence和updateKycStatusByAccountSequence方法

影响范围:
- admin-web用户管理页面现在能正确显示用户昵称和KYC状态
- 新用户注册后数据能正确同步

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 20:35:30 -08:00
hailin 51114f265d fix(planting-service): 修复合同PDF签署日期显示为UTC时间的问题
合同生成时使用 new Date().toISOString().split('T')[0] 获取日期,
该方法返回UTC时间,导致北京时间凌晨签署的合同显示为前一天日期。

修复方案:新增 getBeijingDateString() 函数,将UTC时间转换为北京时间(UTC+8)

影响范围:仅影响PDF合同上显示的签署日期,不影响数据库时间戳或业务逻辑

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 11:42:16 -08:00
hailin 641612a5d0 fix(wallet-service): 修复提现订单查询使用 userId 的问题
将提现订单查询从 userId 改为使用 accountSequence:
- getWithdrawals: 使用 findByAccountSequence 替代 findByUserId
- getFiatWithdrawals: 使用 findByAccountSequence 替代 findByUserId
- 新增 withdrawal-order.repository 的 findByAccountSequence 方法

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 11:24:31 -08:00
hailin 217be89c43 fix(wallet-service): 修复流水查询使用 userId 导致记录丢失的问题
将所有流水查询从 userId 改为使用 accountSequence:
- getMyLedger: 使用 findByAccountSequence 替代 findByUserId
- getLedgerStatistics: 查询改为按 accountSequence
- getLedgerTrend: 查询改为按 accountSequence
- findByAccountSequence: 添加 HIDDEN_ENTRY_TYPES 过滤

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 11:16:04 -08:00
hailin 53df97839d fix(reporting-service): 修复 roleType 可能为 undefined 的类型错误
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 10:21:36 -08:00
hailin ee6a092a1a fix(authorization-service): 修复授权查询使用错误字段导致省市互斥验证失效
问题:数据库 user_id 列存储的是 accountSequence,但查询时使用 userId.value,
导致查询不到已有授权记录,省市互斥验证被绕过。

修复方法:所有基于 UserId 的查询改为使用 accountSequence 字段:
- findByUserIdAndRoleType
- findByUserIdRoleTypeAndRegion
- findByUserId
- findPendingByUserId
- findAllByUserIdIncludeDeleted

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 10:15:40 -08:00
hailin 347e5ce3de fix(reporting-service): 修复授权事件区域名称显示 undefined
不同授权事件使用不同的字段名:
- province 事件:provinceCode/provinceName
- city 事件:cityCode/cityName
- community 事件:communityName
- 通用:regionCode/regionName

现在正确处理所有变体,避免显示 "undefined undefined 完成授权"

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 09:51:11 -08:00
hailin 1676e82cc6 fix(admin-service): 认种汇总和分类账只显示已支付订单
过滤掉 CREATED、PROVINCE_CITY_CONFIRMED、CANCELLED 状态的订单,
只统计已支付及之后的订单(PAID, FUND_ALLOCATED, POOL_SCHEDULED, POOL_INJECTED, MINING_ENABLED)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 09:37:28 -08:00
hailin 2553d05902 chore(api-gateway): 提升速率限制100倍
- minute: 100 → 10000
- hour: 5000 → 500000

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 09:19:50 -08:00
hailin bc38ec6ec0 feat(wallet-service): 三层保护机制确保内部转账接收方钱包存在
新增三层保护机制:
1. 用户注册时:监听 identity.UserAccountCreated 事件自动创建钱包
2. 发起转账时:检测内部转账后调用 ensureWalletExists() 预创建钱包
3. 链上确认时:原有 upsert 逻辑兜底(保持不变)

新增文件:
- identity-event-consumer.service.ts: 消费 identity 用户注册事件
- user-account-created.handler.ts: 处理用户注册事件创建钱包

新增 API:
- POST /wallets/ensure-wallet: 确保单个钱包存在
- POST /wallets/ensure-wallets: 批量确保钱包存在

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 07:33:47 -08:00
hailin 68841abbf4 fix(reporting-service): 修复错误的 Kafka topic 订阅
- 充值事件:blockchain.deposit.credited → wallet.acks (过滤 wallet.deposit.credited)
- 权益事件:authorization.benefit.applied → 整合到 authorization-events (过滤 benefit.activated)

原来订阅的 topic 不存在,导致事件无法消费。现已修复为正确的 topic。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 06:01:08 -08:00
hailin 38fff077dd feat(reporting-service): 新增多种活动事件类型
扩展仪表板"最近活动"功能,新增以下活动类型:

活动类型新增:
- kyc_submitted: KYC认证提交
- kyc_approved: KYC认证通过
- kyc_rejected: KYC认证拒绝
- contract_signed: 合同签署
- deposit: 充值到账
- withdrawal: 提现成功
- benefit_applied: 权益申请

监听的 Kafka Topics:
- identity.KYCSubmitted
- identity.KYCApproved
- identity.KYCRejected
- contract.signed
- blockchain.deposit.credited
- wallet.withdrawals (仅处理 completed 事件)
- authorization.benefit.applied

所有新增事件处理器均使用幂等创建,防止重复记录。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 05:51:26 -08:00
hailin 65bd6a857f fix(reporting-service): 添加活动记录幂等性处理
问题:Kafka 消息重试或重复消费时,同一事件会被记录多次活动,
导致"最近活动"显示重复条目,统计数据也会被重复累加。

修复:
1. 仓储层新增 exists() 和 createIfNotExists() 方法
2. 所有事件消费者改用幂等创建,仅首次创建时累加统计
3. 添加数据库唯一约束 uk_sa_entity_activity 作为最后防线
4. 迁移脚本会自动清理历史重复数据

影响的事件:
- identity.UserAccountCreated
- identity.UserAccountAutoCreated
- authorization-events
- planting.order.paid
- reporting.report.generated

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 05:46:43 -08:00
hailin a86116fef4 fix(admin-service): 修复祖先节点数据获取依赖 user_query_view 的问题
问题:当祖先用户存在于 referral_query_view 但不存在于
user_query_view 时(CDC 同步延迟),祖先节点的
accountSequence 和统计数据无法正确获取。

修复:
- 改用 referralAccountSequences(从 referrals 获取)
  替代 userAccountSequences(从 users 获取)
- 确保即使用户基本信息未同步,仍能获取正确的认种统计

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 05:30:00 -08:00
hailin ca337bcdb7 fix(admin-service): 优先从 referralQueryView 获取祖先 accountSequence
修复祖先节点可能缺少 accountSequence 的问题

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 05:23:46 -08:00
hailin e2b2c17d38 feat(admin-web): 用户详情页引荐关系树优化
- 引荐关系节点显示团队认种量:本人认种 / 团队认种
- 无上级引荐人时显示"总部"节点
- 角色标签优化:社区权益→部门权益,区域→部门名称/城市名称
- 后端 ReferralNode 添加 teamAdoptionCount 字段

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 05:12:28 -08:00
hailin f55ac7e9cb feat(admin-web): 用户详情页显示权益考核记录
- 后端 admin-service 添加 getBenefitAssessments 查询方法
- 更新 AuthorizationDetailResponseDto 包含 benefitAssessments
- 前端用户详情页授权信息 Tab 新增权益考核记录表格
- 显示字段:考核月份、角色、区域、完成/需求、权益操作、
  权益状态变化、有效期至、结果
- 添加权益操作类型样式:已激活(绿)、已续期(蓝)、已停用(红)、无变化(灰)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 04:42:51 -08:00
hailin 178c484f04 feat(admin-service): 添加 BenefitAssessmentRecord CDC 同步
- 新增 BenefitAssessmentQueryView schema 和 migration
- 扩展 AuthorizationCdcConsumerService 处理 benefit_assessment_records 表
- 更新 Debezium authorization-connector 添加新表同步

CDC 同步字段:
- authorization_id, user_id, account_sequence
- role_type, region_code, region_name
- assessment_month, month_index
- monthly_target, cumulative_target
- trees_completed, trees_required
- benefit_action_taken, previous/new_benefit_status
- new_valid_until, result, remarks, assessed_at

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 04:22:37 -08:00
hailin 8f5b4df3d1 feat(authorization-service): 新增权益考核记录表 BenefitAssessmentRecord
新增独立的权益有效性考核记录表,与火柴人排名(MonthlyAssessment)分离:

Schema & Migration:
- 新增 BenefitAssessmentRecord 表存储权益考核历史
- 新增 BenefitActionType 枚举(ACTIVATED/RENEWED/DEACTIVATED/NO_CHANGE)
- 记录考核月份、目标、完成数、权益状态变化等信息

领域层:
- 新增 BenefitAssessmentRecord 聚合根
- 新增 IBenefitAssessmentRecordRepository 接口

应用层:
- 修改 processExpiredCommunityBenefits 保存考核记录
- 修改 processExpiredCityCompanyBenefits 保存考核记录
- 修改 processExpiredProvinceCompanyBenefits 保存考核记录
- 修改 processExpiredAuthCityBenefits 保存考核记录(新增,原无记录)
- 修改 processExpiredAuthProvinceBenefits 保存考核记录(新增,原无记录)

此改动 100% 不影响原有业务逻辑:
- 原有 MonthlyAssessment 表继续用于火柴人排名
- 仅在权益考核执行完成后追加保存记录到新表

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 04:15:07 -08:00
hailin d1e04152dc feat(admin-service): 实现团队本省/本市认种量实时统计
- getBatchUserStats 新增 provinceAdoptionCount 和 cityAdoptionCount
- 根据用户认种订单中的省市信息,统计团队成员同省/同市的认种量
- 百分比改为相对于该用户团队总认种量计算

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 23:07:33 -08:00
hailin 23994a23be feat(admin-service): 用户列表页使用实时统计数据
- 添加 getBatchUserStats 批量查询方法
- user.controller 注入 userDetailRepository
- listUsers 接口使用实时统计替代预计算字段

实时查询的字段:
- personalAdoptionCount: 个人认种量
- teamAddressCount: 团队地址数
- teamAdoptionCount: 团队认种量

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 22:56:07 -08:00
hailin 6a05150017 fix(admin-service): 用户详情页引荐人数改用实时查询
之前 directReferralCount 使用 CDC 同步的预计算字段(值为 0),
现在改为调用 getDirectReferralCount 实时查询

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 22:51:16 -08:00
hailin da5bb98cb7 fix(admin-service): 修复团队统计查询使用错误的 userId
user_query_view 和 referral_query_view 的 userId 不一致:
- user_query_view.user_id = 10 (identity-service CDC)
- referral_query_view.user_id = 25122700001 (referral-service CDC)

修复:
- getTeamStats 改为从 referralQueryView 获取 userId
- 直接用 accountSequence 查询团队认种量,避免再次关联

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 22:47:23 -08:00
hailin bab30dbeba refactor(admin-service): 团队认种量改用 PlantingOrderQueryView
统一使用 PlantingOrderQueryView 计算团队认种量,
与个人认种量保持一致的数据源,避免 CDC 同步不一致问题

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 22:42:30 -08:00
hailin 97bcaa2dfc fix(admin-service): 修复 referrerId 可能为 null 的 TypeScript 错误
- getAncestors 和 getDirectReferrals 中的 directReferralCounts
  groupBy 结果 referrerId 字段可能为 null
- 添加 filter 过滤 null 值,使用非空断言通过类型检查

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 22:34:17 -08:00
hailin d303cf076b fix(admin-service): 引荐关系树实时统计本人认种和直推数量
问题:
- 引荐节点的"本人认种"和"引荐"显示为0
- user_query_view.personal_adoption_count 和
  referral_query_view.direct_referral_count 没有被CDC更新

解决方案:
- getAncestors: 实时统计每个祖先的认种订单数和直推数
- getDirectReferrals: 实时统计每个下级的认种订单数和直推数
- getReferralTree API: 实时获取当前用户的统计数据
- 新增 getDirectReferralCount 方法

实时统计方式:
- 本人认种 = planting_order_query_view 中状态为 MINING_ENABLED 的订单数
- 直推数量 = referral_query_view 中 referrer_id 等于该用户的记录数

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 22:30:38 -08:00
hailin 2781ffccc1 fix(postgres): 增加 max_wal_senders 到 10 支持更多 CDC connector
- max_replication_slots: 4 -> 10
- max_wal_senders: 4 -> 10
- 修复 authorization-connector FAILED 的问题

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 21:53:25 -08:00
hailin 475acf71cc fix(admin-service): 修复钱包金额显示被除以10^8的问题
- decimalToString 改用 toString() 替代 toFixed(8)
- Prisma Decimal 的 toFixed 会导致精度错误
- 删除调试日志代码

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 21:46:29 -08:00
hailin 7176bbd5c2 feat(admin-service): 用户详情页统计数据改用真实数据
- 移除前端"活跃引荐"统计卡片
- 添加 getPersonalAdoptionCount 方法从 PlantingPositionQueryView 获取个人认种量
- 添加 getTeamStats 方法计算团队地址数和团队认种量
- 修改 getFullDetail 使用新方法获取真实统计数据
- 团队地址数通过 ancestorPath 查询所有下级用户
- 团队认种量汇总所有团队成员的 effectiveTreeCount

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 21:23:18 -08:00
hailin eccc637a02 fix(admin-service): 修复金额显示单位错误
移除错误的 1e8 乘除转换:
- 数据库存储的是实际金额 (Decimal(20,8)),不需要缩放
- decimalToBigint → decimalToString: 直接格式化为字符串
- 移除 controller 中不再需要的 formatDecimal 方法
- 更新接口类型: bigint → string (金额相关字段)

影响的接口:
- PlantingSummary.totalAmount
- PlantingLedgerItem.totalAmount
- WalletSummary 所有余额字段
- WalletLedgerItem.amount/balanceAfter
- SystemAccountLedger.amount/balanceAfter

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 21:15:28 -08:00
hailin 1c5fd9eaad fix(admin-service): 修复 BigInt 序列化错误
日志输出时不再使用 JSON.stringify 序列化包含 BigInt 的对象,
改为直接输出关键字段值,避免 "Do not know how to serialize a BigInt" 错误

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 21:03:41 -08:00
hailin 5f6ecf9670 fix(admin): 用户详情页 USDT 改为绿积分 + 添加调试日志
前端修改:
- 钱包汇总: USDT 可用/冻结 → 绿积分 可用/冻结
- 认种汇总: 总金额 (USDT) → 总金额 (绿积分)
- 资产类型标签: USDT → 绿积分

后端修改:
- UserDetailController: 添加认种/钱包查询日志
- UserDetailQueryRepositoryImpl: 添加数据库查询日志
- 日志包含 accountSequence、查询结果、数据条数等信息

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 20:53:30 -08:00
hailin f15bdeaef8 fix(admin-service): 用户详情查询改用 accountSequence
- 钱包/认种查询从 userId 改为 accountSequence 作为关联键
- 修复用户详情页钱包数据显示为0的问题
- accountSequence 是全局唯一业务标识,关联更可靠

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 20:43:36 -08:00
hailin b49776fadb fix(admin-service): 注册 CDC 消费者到 AppModule
CDC 数据无法同步的原因是消费者服务未在 AppModule 中注册。
添加以下 CDC 消费者:
- CdcConsumerService (identity 用户数据)
- ReferralCdcConsumerService (推荐关系)
- WalletCdcConsumerService (钱包账户和流水)
- PlantingCdcConsumerService (认种订单和持仓)
- AuthorizationCdcConsumerService (授权角色和考核)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 20:20:54 -08:00
hailin 3d31e8beb9 feat(admin): 实现用户详情页面
前端 (admin-web):
- 新增用户详情页面 /users/[id]
- 实现推荐关系树可视化,支持点击节点切换视角
- 添加认种分类账Tab,显示汇总和订单明细
- 添加钱包分类账Tab,显示余额汇总和流水明细
- 添加授权信息Tab,显示角色、月度考核和系统账户流水
- 用户列表"查看详情"改为 Link 导航到详情页

后端 (admin-service):
- 新增 UserDetailController 提供详情页API
- 新增 UserDetailQueryRepository 查询CDC同步的数据
- API: GET /admin/users/:seq/full-detail
- API: GET /admin/users/:seq/referral-tree
- API: GET /admin/users/:seq/planting-ledger
- API: GET /admin/users/:seq/wallet-ledger
- API: GET /admin/users/:seq/authorization-detail

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 20:10:01 -08:00
hailin 83f84b9d7c feat(admin-service): 添加 CDC 分类账流水同步
新增 wallet/planting/authorization 服务的 CDC 数据同步:

状态表同步:
- WalletAccountQueryView: 钱包账户余额状态
- WithdrawalOrderQueryView: 提现订单状态
- FiatWithdrawalOrderQueryView: 法币提现订单
- PlantingOrderQueryView: 认种订单状态
- PlantingPositionQueryView: 持仓状态
- ContractSigningTaskQueryView: 合同签约任务
- AuthorizationRoleQueryView: 授权角色
- MonthlyAssessmentQueryView: 月度考核
- SystemAccountQueryView: 系统账户余额

分类账流水同步:
- WalletLedgerEntryView: 钱包流水分类账
- FundAllocationView: 认种资金分配记录
- SystemAccountLedgerView: 系统账户流水

其他:
- Debezium Connect 端口改为 8084 避免冲突
- 更新连接器配置添加流水表

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 19:29:27 -08:00
hailin c4cec836d9 feat(admin-service): 添加 referral-service CDC 数据同步
- 新增 ReferralQueryView schema 和 migration
- 新增 ReferralCdcConsumerService 消费推荐关系变更
- 配置 referral-postgres-connector 用于 Debezium CDC
- 更新 deploy.sh 自动注册 referral connector
- 更新 init-databases.sh 配置 rwa_referral 逻辑复制权限

CDC 同步的字段:
- user_id, account_sequence, referrer_id
- my_referral_code, used_referral_code
- ancestor_path, depth
- direct_referral_count, active_direct_count

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 18:57:58 -08:00
hailin 6b55b69d0d fix(leaderboard-service): 修复健康检查 API 路径
将 Dockerfile 和 docker-compose.yml 中的健康检查路径从
/api/health 修改为 /api/v1/health,与实际 API 路由保持一致

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 18:48:34 -08:00
hailin 7d3483b565 fix(referral-service): 修复 Kafka 消费异常被吞掉的问题
- kafka.service.ts: 抛出异常让 KafkaJS 触发重试
- user-registered.handler.ts: 传播异常到 KafkaService

修复前处理失败的消息不会重试,导致推荐关系可能丢失

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 18:47:05 -08:00
hailin b5ebf8a615 feat(admin-service): 实现 Debezium CDC 数据同步
- 新增 CdcConsumerService 消费 PostgreSQL WAL 变更事件
- 配置 Debezium Connect 服务和 PostgreSQL 逻辑复制
- 更新 deploy.sh 支持 Debezium 启动和连接器管理
- 新增 identity-postgres-connector 配置同步 user_accounts 表
- 保留原有 Outbox 机制用于业务领域事件

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 18:35:53 -08:00
hailin 84aa8181a9 fix(reporting-service): 兼容 referral-service 的认种事件格式
- planting.order.paid 事件现在由 referral-service 发送
- 消息格式为 { eventName, data: {...} },与原 planting-service 格式不同
- 添加兼容逻辑,同时支持两种格式
- 修复今日认种统计为0的问题

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 06:58:33 -08:00
hailin c7c793f128 fix(reporting-service): 账户余额改为 累计收入 - 累计转出
- 所有固定账户:账户余额 = 累计收入 - 累计转出
- 总部储蓄(HQ_COMMUNITY):累计收入 = ledger收入 + 过期收益
- 统一计算公式,确保数据一致性

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 06:41:28 -08:00
hailin 842bc42579 fix(reporting-service): 总部储蓄账户余额也需累加过期收益
- 账户余额改为 usdtBalance + expiredRewardsTotal
- 与累计收入的计算方式保持一致
- 过期的分享权益会进入 S0000000001,余额和收入都应包含

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 06:40:20 -08:00
hailin a719294dda fix(blockchain-service): 添加系统账户转出事件主题订阅
- 消费者添加订阅 wallet.system-withdrawals 主题
- 解决系统账户转出订单一直处于 FROZEN 状态的问题
- 事件现在可以被 blockchain-service 消费并处理链上转账

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 06:17:57 -08:00
hailin c22ce4ecc4 fix(reporting-service): 将过期收益累加到总部储蓄账户统计
- 修改 assembleFixedAccounts 方法接受过期收益总额参数
- 将过期分享收益累加到 HQ_COMMUNITY (S0000000001) 的累计收入中
- 添加日志记录累加过程

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 05:53:51 -08:00
hailin db833fdf45 fix(wallet-service): 修复系统划转请求 DTO 验证错误
- 为 SystemWithdrawalRequestDTO 添加 class-validator 装饰器
- 添加 @ApiProperty 装饰器用于 Swagger 文档
- 使用 @Type(() => Number) 自动转换 amount 类型
- 简化验证逻辑,移除冗余的手动验证

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 05:52:36 -08:00
hailin 4f2f808484 feat(wallet-service): 实现 Outbox Pattern 保证系统划转事件发布的可靠性
实现内容:
- 添加 OutboxEvent 模型到 schema.prisma
- 创建 OutboxRepository 服务处理事件持久化
- 创建 OutboxPublisherService 后台轮询发布事件到 Kafka
- 修改 SystemWithdrawalApplicationService 将事件写入事务内
- 添加数据库迁移文件创建 outbox_events 表

技术细节:
- 业务数据和事件数据在同一个数据库事务中写入
- 后台任务每秒轮询 outbox_events 表,发布 PENDING 状态事件
- 事件发布后标记为 SENT,等待消费方确认后标记为 CONFIRMED
- 超时未确认的事件自动重试(指数退避策略)
- 保证事件不丢失,即使 Kafka 暂时不可用

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 05:15:07 -08:00
hailin d16ad81d62 fix(wallet-service): 完善系统账户转出分类账memo信息
- memo 格式更新为包含完整信息:
  - 接收方账户ID
  - 接收方姓名
  - 接收方钱包地址(缩略显示)
  - 操作员姓名/ID
  - 备注(如有)
- payloadJson 新增 toAddress 字段存储完整地址

示例: "转账至 D25010100001 (张三) | 地址: 0x1234...5678 | 操作员: 管理员A | 备注: 奖励发放"

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 04:52:00 -08:00
hailin 6350b36e1a feat(reporting, admin-web): 添加省/市区域账户累计转出统计
- 后端 reporting-service: RegionAccountInfo 和汇总接口添加 totalTransferred 字段
- 后端 wallet-service client: 更新 AllSystemAccountsResponse 类型定义
- 前端 admin-web: SystemAccountsTab 组件显示累计转出列
- 前端类型: RegionAccountsSummary 添加 totalTransferred 字段

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 04:45:56 -08:00
hailin 27e64819b7 feat(wallet-service): 省/市区域账户增加累计转出字段
- provinceAccounts 和 cityAccounts 返回结构增加 totalTransferred 字段
- 完善分类账统计,与固定系统账户保持一致

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 04:39:47 -08:00
hailin 78fa354117 fix(wallet-service): 修复系统账户余额统计不一致问题
- 账户余额改为 usdtAvailable + settleableUsdt,与累计收入统计保持一致
- 解决社区权益进入 settleableUsdt 导致的余额与累计收入不匹配问题

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 04:15:42 -08:00
hailin 5c7cb616a7 feat(wallet-service): 添加运营1和积分股池到系统划转账户列表
- 添加 S0000000002 (运营1) 和 S0000000004 (积分股池) 到允许转出白名单
- 更新系统账户名称映射与前端保持一致
- 为 S0000000006 手续费归集账户添加兼容逻辑,当余额为0时从提现订单表统计历史手续费
- 优化过期奖励处理,按分配类型分别记录流水便于明细查看

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 03:44:46 -08:00
hailin fa7b45ec2f fix(wallet-service, admin-web): 修复系统账户划转金额类型问题
- wallet-service: 支持 amount 为字符串或数字类型,添加类型转换
- admin-web: 改进错误处理,正确提取 Axios 错误消息

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 03:01:52 -08:00
hailin eb40b658f6 revert(wallet-service): 回滚 fixedAccountTypes 映射修改
撤销错误的账户类型映射修改,恢复原始映射:
- S0000000001 → HQ_COMMUNITY
- S0000000002 → COST_ACCOUNT
- S0000000003 → OPERATION_ACCOUNT

修改后端映射会影响 reward-service、authorization-service 等多个服务。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 23:22:22 -08:00
hailin d28723f141 fix(wallet-service): 修正固定账户类型映射顺序
修复 getAllSystemAccounts 中 fixedAccountTypes 映射错误:
- S0000000001 应为 COST_ACCOUNT (运营1),而非 HQ_COMMUNITY
- S0000000002 应为 OPERATION_ACCOUNT (运营2),而非 COST_ACCOUNT
- S0000000003 应为 HQ_COMMUNITY (总部储蓄),而非 OPERATION_ACCOUNT

此修复确保固定账户的余额、收入和分类账明细正确对应。
同时移除前端调试日志。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 23:20:41 -08:00
hailin 7744abf57d fix(reporting-service): 修复 DashboardController 的依赖注入问题
在 ApiModule 中导入 RedisModule,使 HotWalletBalanceCacheService
可以被 DashboardController 注入使用。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 23:12:24 -08:00
hailin 8dba325499 feat(dashboard): 添加热钱包余额实时显示(公共账户/因子)
- blockchain-service: 扩展调度器同时缓存 dUSDT 和 KAVA 原生代币余额到 Redis
  - Redis Key: hot_wallet:dusdt_balance:KAVA, hot_wallet:native_balance:KAVA
  - 每5秒更新,TTL 30秒

- reporting-service: 添加热钱包余额读取服务和 API
  - 新增 HotWalletBalanceCacheService 从 Redis 读取缓存
  - 新增 GET /v1/dashboard/hot-wallet-balance 接口

- admin-web: 仪表板添加热钱包余额显示
  - 公共账户显示 dUSDT 余额
  - 因子显示 KAVA 原生代币余额
  - 每15秒自动刷新

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 23:04:21 -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 8c29603f5a fix(reporting-service): use field-level @unique for statsDate in schema
Root cause: @@unique([field], name: "xxx") requires { xxx: { field } } syntax
in findUnique/upsert, but code used { field } directly.

Fix: Change to @unique(map: "uk_realtime_stats_date") on the field itself.
This keeps the same database index name while allowing { statsDate } syntax.

No migration needed - only Prisma client type generation changes.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 21:38:13 -08:00
hailin 4e201d3a66 fix(reporting-service): use findFirst + update instead of upsert for realtimeStats
Replace upsert with findFirst + create/update pattern to avoid Prisma
unique constraint syntax issues. The @@unique constraint with a custom
name doesn't allow direct field-based queries in findUnique/upsert.

This approach maintains the same behavior without schema changes.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 21:36:26 -08:00
hailin ce1d342269 fix(reporting-service): use named unique constraint for realtimeStats queries
Prisma requires using the named unique constraint (uk_realtime_stats_date)
in where clauses for findUnique and upsert operations. This fixes the
PrismaClientValidationError that was occurring when processing planting
order events.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 21:25:24 -08:00
hailin d400290652 fix(reporting-service): 修复统计 incrementPlanting 对 undefined 参数的处理
当 planting.order.paid 事件中 treeCount 为 undefined 时:
- GlobalStatsRepository: 使用 ?? 0 提供默认值
- RealtimeStatsRepository: 使用 ?? 0 提供默认值
- 避免 Prisma upsert 因 undefined increment 值而报错

问题原因:planting-service 发送的事件数据中 treeCount 可能为 undefined

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 21:18:26 -08:00
hailin 272b4ffdbf feat(wallet-service): 添加手续费归集统计的历史数据兼容
当 FEE_COLLECTION 流水为空时,自动从提现订单表查询历史手续费:
- getFeeCollectionSummary: 从 withdrawal_orders 和 fiat_withdrawal_orders 聚合统计
- getFeeCollectionEntries: 从两个订单表查询明细列表,支持分页和类型筛选
- 按月统计使用 UNION ALL 合并两种提现订单数据
- 明细记录添加备注说明区分来源(区块链/法币)

回滚方式:删除 fallback 代码块和两个私有方法

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 21:11:37 -08:00
hailin 4dcdfb8a3c fix(wallet/reporting): 修复手续费归集统计 API 的数据库表名和响应解包问题
- wallet-service: 修复 getFeeCollectionSummary 中原生 SQL 使用错误表名
  - 将 ledger_entries 改为 wallet_ledger_entries(Prisma 映射表名)
- reporting-service: 修复 getFeeCollectionSummary/Entries 响应解包
  - wallet-service 返回 { success, data, timestamp } 格式需要解包 data

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 21:04:02 -08:00
hailin 4e5d9685a1 feat(admin-web): 添加面对面结算明细列表功能
- wallet-service: 新增 getOfflineSettlementEntries 方法和 API
- reporting-service: 新增客户端方法和 API 转发
- admin-web: 添加明细列表组件和样式,支持展开/收起

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 20:40:12 -08:00
hailin 9953f0eee5 fix(reporting-service): 修复面对面结算数据解包问题
wallet-service 返回 { success, data, timestamp } 包装格式,
getOfflineSettlementSummary 需要用 response.data.data 解包才能获取真正的数据。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 20:23:54 -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 2c8263754f fix(wallet-service): fix system-withdrawal API route prefix to match Kong gateway
Changed controller route from 'system-withdrawal' to 'wallets/system-withdrawal'
to align with Kong's /api/v1/wallets/* routing

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 10:53:54 -08:00
hailin 305514b246 feat(admin-web): 仪表板改用 planting-service 源数据
统计卡片和趋势图不再使用 reporting-service,直接使用 planting-service 的源数据:

- 统计卡片:总认种量、总订单数、今日认种、本月认种
- 趋势图:支持 7天/30天/90天 切换
- 新增 usePlantingTrendForDashboard hook

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 10:47:44 -08:00
hailin fe8e9a9bb6 fix(planting-service): 修复趋势数据查询表名错误
表名应为 planting_orders(复数),不是 planting_order

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 10:26:36 -08:00
hailin 64bd82b77b feat(wallet/blockchain/identity): implement system account withdrawal feature
- Add SystemWithdrawalApplicationService to handle system account transfers
- Add SystemWithdrawalController with endpoints for request, query, and account listing
- Add SystemWithdrawalStatusHandler to process blockchain confirmation/failure events
- Add SystemWithdrawalRequestedHandler in blockchain-service to execute ERC20 transfers
- Add getUserByAccountSequence endpoint in identity-service for user lookup
- Support dynamic memo generation based on actual source account name
- Dual-sided ledger entries for system account transfers

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 10:22:15 -08:00
hailin fa1931b3b6 feat(planting-service, admin-web): 实现认种趋势图表功能
后端变更 (planting-service):
- 添加 getTrendData API 接口支持按时间维度(日/周/月/季度/年)查询趋势数据
- 添加 TrendPeriod 类型和 TrendDataPoint 接口
- 实现 repository 层的趋势数据聚合查询

前端变更 (admin-web):
- 添加趋势数据 API 端点和类型定义
- 使用 recharts 实现折线图展示认种棵数和订单数趋势
- 支持日/周/月/季度/年度时间维度切换
- 添加加载状态、错误状态和空数据状态处理

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 10:21:11 -08:00
hailin 4f3660f05e feat(statistics): 恢复榴莲树认种数量趋势图表
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 10:01:37 -08:00
hailin 24bcc45d5a refactor(statistics): 删除认种统计页面不相关的mock功能
删除以下mock数据和功能:
- 榴莲树认种数量趋势图表
- 龙虎榜与排名统计
- 区域认种数据统计
- 省/市公司运营统计
- 收益明细与来源

保留核心认种统计:
- 榴莲树认种总量(含积分)
- 今日认种数量(含积分)
- 本月认种数量(含积分)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 10:00:50 -08:00
hailin 36a83397a8 revert: 撤销对 authorization/identity/reporting 服务的修改
这些服务不需要同步手续费账户的定义,wallet-service 独立处理。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 09:48:42 -08:00
hailin 2be9a2d9c2 feat(statistics): 认种统计改为真实数据并显示积分
后端变更(planting-service):
- 添加 getMonthStats() 方法获取本月认种统计
- 更新 GlobalStatsResult 接口添加 monthStats 字段
- 添加 MonthStatsDto 响应类型

前端变更(admin-web):
- 更新 PlantingGlobalStats 类型定义
- statistics 页面调用真实 API 获取认种统计
- 显示认种总量、今日、本月的棵数和积分

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 09:36:46 -08:00
hailin 898521d236 fix: 同步手续费归集账户到所有相关服务
- identity-service: seed.ts 添加 S0000000005 和 S0000000006
- authorization-service: 枚举添加 SHARE_RIGHT_POOL 和 FEE_COLLECTION
- authorization-service: 初始化固定账户列表添加新账户
- reporting-service: 修复账户类型映射 (PLATFORM_FEE -> FEE_COLLECTION)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 09:30:45 -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 283553a474 fix(wallet-service): 统一系统账户 seed migration
- 将 S0000000005 和 S0000000006 添加到初始 seed migration
- 简化 S0000000006 migration 格式与其他账户保持一致
- 新环境初始化时所有系统账户一次性创建

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 09:12:17 -08:00
hailin b9911ab460 feat(wallet-service): 实现手续费归集账户功能
- 新增系统账户 S0000000006 (user_id=-6) 用于归集提现手续费
- 新增 FEE_COLLECTION 流水类型记录手续费归集
- 区块链提现完成时使用 UnitOfWork 事务归集手续费
- 法币提现完成时在事务中归集手续费
- WithdrawalOrderRepository 添加事务支持
- 所有手续费归集操作使用乐观锁保护

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 09:10:41 -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 bbafe58e86 fix(wallet-service): update init migration memo column to TEXT
Ensure new database installations use TEXT type for memo column from the start.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 08:30:07 -08:00
hailin 069c549bc4 feat(wallet-service): add migration for memo column type change to TEXT
Change wallet_ledger_entries.memo from VARCHAR(500) to TEXT to support longer settlement memos.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 08:27:12 -08:00
hailin bf1c8d2228 feat(wallet-service): 实现 Unit of Work 模式保证 settleToBalance 事务原子性
- 新增 UnitOfWork 接口和实现,使用 Prisma Interactive Transaction
- 修改 IWalletAccountRepository 和 ILedgerEntryRepository 接口支持可选事务参数
- 修改仓库实现,支持在事务中执行数据库操作
- 修改 settleToBalance 方法使用 UnitOfWork,确保钱包更新和流水记录原子性
- 注册 UnitOfWorkService 到 InfrastructureModule

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 07:50:02 -08:00
hailin 7dc25b75d2 revert: 回滚 settleToBalance 的直接 Prisma 实现,准备用 Unit of Work 模式重新实现 2026-01-06 07:07:27 -08:00
hailin 4c6e64a604 fix(wallet-service): settleToBalance 添加乐观锁防止并发冲突 2026-01-06 06:56:50 -08:00
hailin 65cb574f59 fix(wallet-service): 添加钱包状态检查,确保只有 ACTIVE 钱包可结算 2026-01-06 06:50:08 -08:00
hailin 5204d24c88 fix(wallet-service): 修复 settleToBalance 方法缺少事务保护的严重 Bug
问题原因:
settleToBalance 方法先执行 wallet.save() 更新账户余额,再执行
ledgerRepo.save() 写入流水记录。两个操作不在同一个事务中。

当流水写入失败时(如 memo 字段超过 VarChar(500) 限制),账户余额
已经被修改,但流水记录未写入,导致数据不一致。

具体案例:
用户 D25122700023 点击结算时,memo 内容超长(66笔奖励详情),
wallet-service 先把 settleable_usdt 转入 usdt_available,然后
写流水失败。账户余额被改但没有对应流水。

修复内容:
1. settleToBalance: 使用 prisma.$transaction 确保原子性
   - 账户余额更新和流水记录在同一事务中
   - 任一操作失败整个事务回滚
2. schema: memo 字段从 VarChar(500) 改为 Text 类型,无长度限制

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 06:40:09 -08:00
hailin 573e58c89b fix(wallet-service): 统一奖励分配到 settleable_usdt,与 reward-service 保持一致
问题原因:
wallet-service 对不同类型奖励的分配方式不一致:
- SHARE_RIGHT: 正确使用 addSettleableReward() → settleable_usdt
- CITY_TEAM_RIGHT/COMMUNITY_RIGHT: 错误使用 addAvailableBalance() → usdt_available

这导致 reward-service 记录的 SETTLEABLE 奖励总额与 wallet-service 的
settleable_usdt 字段不匹配。用户 D25122700024 的案例中:
- reward-service: 3条奖励共 4464 USDT (SHARE_RIGHT 3600 + CITY_TEAM_RIGHT 288 + COMMUNITY_RIGHT 576)
- wallet-service: settleable_usdt = 3600 (仅 SHARE_RIGHT)
差额 864 USDT 被错误地放入了 usdt_available

修复内容:
1. allocateCommunityRight: 改用 addSettleableReward() 替代 addAvailableBalance()
2. allocateToRegionAccount: 改用 addSettleableReward() 替代 addAvailableBalance()
3. 流水类型统一使用 REWARD_TO_SETTLEABLE 替代 SYSTEM_ALLOCATION
4. 日志和备注更新以反映新的分配方式

设计原则:
- reward-service 是奖励的权威来源
- wallet-service 应跟随 reward-service 的设计
- 所有奖励都应进入 settleable_usdt,用户主动结算后才转入 usdt_available

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 03:49:31 -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 8b80e45524 fix(authorization): 火柴人排名过滤已撤销授权的考核记录
- findRankingsByMonthAndRegion 和 findRankingsByMonthAndRoleType 增加过滤条件
- 排除 authorization.status = 'REVOKED' 的记录
- 解决同一用户因有多条授权记录(含已撤销)而重复显示的问题

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 19:55:23 -08:00
hailin 6c78e22000 fix(authorization): 添加火柴人排名调试日志
添加详细日志显示返回的每条记录的区域信息,便于调试过滤问题。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 06:23:57 -08:00
hailin bdc6ba524f fix(authorization): 火柴人排名改为按区域过滤
修改排名逻辑,只显示获得相同省/市公司授权的用户排名。

- 后端 getStickmanRanking 改用 findRankingsByMonthAndRegion
- 简化实时创建评估逻辑,只为当前区域创建
- 更新前端注释说明

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 05:56:30 -08:00
hailin 3b3342de5c feat(wallet-service): 添加内部转账入账修复脚本
新增一次性修复脚本用于补录因接收方钱包未创建导致入账失败的内部转账。

脚本特性:
- DRY_RUN 模式:默认只检查不执行,需手动改为 false 才真正修复
- 完整验证:订单状态、类型、接收方信息、txHash
- 幂等性检查:确认接收方没有 TRANSFER_IN 流水
- 转出方验证:确认转出方有 TRANSFER_OUT 流水(已扣款)
- 乐观锁:使用 version 字段防止并发修改
- 审计追踪:payloadJson.dataFix=true 标记修复操作
- 详细日志:每步操作都有时间戳和日志级别

使用方法:
1. 在 wallet-service 容器内执行 DRY_RUN 检查
2. 确认无误后将 DRY_RUN 改为 false 再次执行

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 05:06:27 -08:00
hailin ac0e73afac feat(wallet/blockchain): 热钱包余额预检查及接收方钱包自动创建
1. blockchain-service: 新增热钱包 dUSDT 余额定时更新调度器
   - 每 5 秒查询热钱包在 KAVA 链上的 dUSDT 余额
   - 更新到 Redis DB 0,key 格式: hot_wallet:dusdt_balance:{chainType}
   - TTL 30 秒,服务故障时缓存自动过期

2. wallet-service: 新增热钱包余额缓存服务
   - 从 Redis DB 0 读取热钱包余额缓存
   - 严格模式:无法获取余额或余额不足时拒绝转账
   - 提示信息:"财务系统审计中,请稍后再试"

3. wallet-service: 转账确认时自动创建接收方钱包
   - 解决接收方钱包不存在导致入账失败的问题
   - 使用 upsert 避免并发创建冲突
   - 在同一事务中完成创建和入账

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 04:31:52 -08:00
hailin 66ace25935 fix(reporting): remove userId dependency in planting.order.paid handler
- Change userId to optional in PlantingOrderPaidEvent interface
- Add accountSequence field for user identification
- Remove relatedUserId from activity creation (was causing BigInt error)
- Store accountSequence in metadata instead

Fixes: TypeError: Cannot convert undefined to a BigInt

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 00:05:56 -08:00
hailin c3c15b7880 fix(wallet-service): remove invalid nested $queryRaw in getOfflineSettlementSummary
删除使用嵌套 $queryRaw 进行条件拼接的错误查询,保留简化版本。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 23:37:57 -08:00
hailin 49cdeb4aef fix(reporting-service): fix planting.order.paid event message format
planting-service 发送的消息是直接数据格式,不包含 payload 包装,
修正 ActivityEventConsumerController 以适配实际消息格式。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 23:32:32 -08:00
hailin 229dff1a9d feat(system-accounts): add ledger detail API for all system accounts
新增所有系统账户的分类账明细查询功能:
- wallet-service: 添加 getSystemAccountLedger 和 getAllSystemAccountsLedger 方法
- wallet-service: 添加 /statistics/system-account-ledger 和 /statistics/all-system-accounts-ledger API
- reporting-service: 添加 /all-ledger 端点透传分类账数据

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 23:30:38 -08:00
hailin 56f2fd206d fix(reporting-service): extract data from wrapped API response
wallet-service API 返回 { success, data } 格式,需要解析 response.data.data

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 23:20:38 -08:00
hailin 6d5c5f7e4c fix(reporting-service): add /api/v1 prefix to wallet and reward service API calls
修复 reporting-service 调用 wallet-service 和 reward-service 时的 404 错误,
所有内部 HTTP 调用路径添加 /api/v1 全局前缀。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 23:18:10 -08:00
hailin 838d5c1d3b feat(reporting): fix system account report to use wallet-service data
The system account balances were showing 0 because data was being fetched
from authorization-service.system_accounts table instead of the actual
wallet-service.wallet_accounts table where funds are stored.

Changes:
- wallet-service: Add getAllSystemAccounts() method to query all system
  accounts (fixed S*, province 9*, city 8*) with actual balances
- wallet-service: Add /wallets/statistics/all-system-accounts API endpoint
- reporting-service: Update SystemAccountReportApplicationService to fetch
  data from wallet-service instead of authorization-service
- reporting-service: Fix default service URLs to use correct container names
  and ports (rwa-wallet-service:3001, rwa-reward-service:3005)
- docker-compose: Add WALLET_SERVICE_URL and REWARD_SERVICE_URL env vars
  for reporting-service

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 23:10:20 -08:00
hailin 1c4def2867 feat(kong): add system-account-reports route to reporting-service
Add Kong route for the new system account reports API endpoint
at /api/v1/system-account-reports, forwarding to reporting-service.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 22:27:55 -08:00
hailin e95316c5f4 fix(authorization-service): register SystemAccountApplicationService in AppModule
Add missing dependency injection for SystemAccountApplicationService
which is required by InternalAuthorizationController for system account
report statistics API.

- Import SystemAccountRepositoryImpl and SYSTEM_ACCOUNT_REPOSITORY
- Register SystemAccountApplicationService as provider
- Register SYSTEM_ACCOUNT_REPOSITORY with SystemAccountRepositoryImpl

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 22:22:02 -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 8d97ed2720 fix(wallet-service): convert BigInt to string for JSON serialization in getUnprocessedSettlements
The entry.id field is BigInt type from Prisma which cannot be JSON serialized directly.
Convert to string for API response and back to BigInt when storing to database.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 07:46:46 -08:00
hailin 251fee4f1e feat(wallet-service): add offline settlement deduction feature
Add new functionality for admins to automatically deduct all settled
earnings when creating special deductions with amount=0, marking
each record to prevent duplicate deductions.

- Add OfflineSettlementDeduction model to track deducted records
- Add API endpoints for querying unprocessed settlements and executing batch deduction
- Add mode selection UI in admin-web pending-actions
- Add offline settlement card display in mobile-app special deduction page

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 06:56:39 -08:00
hailin 46b68e8652 feat(planting-service): add global stats API for data verification
Add new endpoint GET /api/v1/planting/stats/global to query planting
statistics directly from the database, providing reliable data source
for verifying reporting-service statistics.

New features:
- GlobalPlantingStats: total tree count, order count, amount
- StatusDistribution: breakdown by order status (PAID to MINING_ENABLED)
- TodayStats: daily statistics with tree count, order count, amount

Implementation:
- Pure additive changes, no modifications to existing code
- Read-only aggregate queries using Prisma aggregate/groupBy
- No database schema changes required

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 06:55:08 -08:00
hailin 8148f7a52a fix(leaderboard-service): add @IsIn validator to UpdateLeaderboardSwitchDto
The 'type' field was missing validation decorator, causing 400 Bad Request
when ValidationPipe with forbidNonWhitelisted was enabled.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 04:11:05 -08:00
hailin aa58b9e745 fix(leaderboard-service): fix AdminGuard role case sensitivity
The AdminAccount table stores roles in lowercase (admin, super_admin),
but AdminGuard was checking for uppercase (ADMIN, SUPER_ADMIN).
This caused 403 Forbidden errors for authenticated admin users.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 04:07:23 -08:00
hailin cb59a964dd fix(leaderboard-service): change global prefix from 'api' to 'api/v1'
Match the global prefix convention used by all other services.
This fixes Kong routing 404 errors for /api/v1/leaderboard/* endpoints.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 04:01:09 -08:00
hailin ea93bafe7e fix(leaderboard): add REFERRAL_SERVICE_URL to docker-compose
The leaderboard-service needs to connect to referral-service for
team statistics data. Without this environment variable, it falls
back to localhost:3004 which fails inside Docker network.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 03:47:00 -08:00
hailin dacefa2b51 feat(leaderboard): add toggle control for mobile-app ranking page
- Add public /leaderboard/status endpoint (no auth required)
- Add LeaderboardService in mobile-app to fetch board status
- Update RankingPage to show "待开启" when board is disabled
- Connect admin-web leaderboard page to real API
- Board toggle now takes effect immediately

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 03:35:57 -08:00
hailin 52afe72f17 fix(authorization): migration should drop both constraint and index
The original migration only used DROP CONSTRAINT which failed silently
because Prisma created an INDEX instead. Added DROP INDEX as well to
handle both cases in future deployments.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 03:14:00 -08:00
hailin 0991d5d484 fix(authorization): allow querying REVOKED records despite deletedAt being set
撤销授权时会同时设置 status=REVOKED 和 deletedAt(软删除),
导致 findByStatus(REVOKED) 因为 deletedAt IS NULL 条件永远返回空。
修改为查询 REVOKED 状态时不过滤 deletedAt。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 02:52:43 -08:00
hailin 5026661fa8 chore(planting): update contract PDF template to release version
Signature field position: x=449.51, y=140.18 (moved further right and up).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 02:45:28 -08:00
hailin bdc3cdd75e chore(planting): update contract PDF template to v1.2
Moved signature button field further right (x=435.60) and down (y=113.51).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 02:13:48 -08:00
hailin bc1d4a62c6 fix(authorization): add Transform decorator to parse includeRevoked query param
查询参数都是字符串类型,需要将 'true' 转换为布尔值 true,
否则后端无法正确处理 includeRevoked 参数,导致已撤销的授权记录不显示。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 02:07:49 -08:00
hailin c8f2d5edff chore(planting): update contract PDF template to v1.1
Updated signature field position to x=427.60 for better alignment.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 01:48:34 -08:00
hailin af0b9d38c0 Revert "fix(authorization): exclude revoked records when checking existing authorization"
This reverts commit ec528a7226.
2026-01-04 01:08:28 -08:00
hailin ec528a7226 fix(authorization): exclude revoked records when checking existing authorization
The findByAccountSequenceAndRoleType query now excludes REVOKED status,
allowing users to be re-authorized after their authorization was revoked.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 00:59:37 -08:00
hailin 30cb245301 refactor: rename "总部社区" to "总部" across backend services
Changed display name from "总部社区" to "总部" in:
- authorization-service
- identity-service seed
- leaderboard-service seed and entity

Note: Existing database records need manual update if already seeded.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 00:34:36 -08:00
hailin 67c7d9149c fix(planting): move signature field right to avoid overlapping text
Moved the signature field from x=415 to x=470 in the PDF template
to prevent the signature image from covering the "乙方(签字/盖章):" text.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 00:28:07 -08:00
hailin 16d895d460 debug: add logging to queryAuthorizations 2026-01-04 00:12:43 -08:00
hailin ef6b2ceb22 fix(authorization): show all authorized users in admin list including those in assessment period
Previously used findAllActive() which only returned users with benefitActive=true,
causing users still in assessment period to be hidden. Now uses findByStatus()
to show all AUTHORIZED users regardless of benefit activation status.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 00:04:24 -08:00
hailin f5afb65df8 fix(planting): center signature image on the signature field
Calculate signature position based on field center instead of left-bottom
corner, so the signature image is properly centered within the field area.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 00:00:13 -08:00
hailin ef80a2f23b fix(planting): remove signature button field before flatten to avoid gray background
The signature button field has a gray background that covers the drawn
signature image when the form is flattened. Now we remove the signature
field after drawing the signature image to prevent this.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 23:45:44 -08:00
hailin 083c0fd540 fix(planting): draw signature directly on page instead of using form field
The PDF signature field is only 92x51 points, which causes signatures to
appear too small or invisible. Changed to use drawImage() directly on
the page at the field's position with a larger size (150x80 max).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 23:28:18 -08:00
hailin 50f960ecea fix(authorization): allow admin tokens without accountSequence field
Admin JWT tokens from identity-service don't include the accountSequence
field (only userId, email, role, type). This caused a 400 error with
message "管理员账户序列号不能为空" when admins tried to grant authorizations.

Changes:
- Update AdminUserId value object to make accountSequence optional
- Use 'ADMIN' as default value when accountSequence is not provided
- Update all controller methods to handle optional accountSequence

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 22:57:56 -08:00
hailin 4a3658e770 chore(planting): update contract PDF template to v1
更新认种合同PDF模板为v1版本

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 22:43:15 -08:00
hailin 825b80b319 fix(planting): match PDF form field names to template
修改代码中的表单字段名以匹配PDF模板中的实际字段名:
- totalAmount → RmbAmount
- totalAmountChinese → SpellChineseFormatNumber
- greenPointsAmount → GreenAmount

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 21:33:14 -08:00
hailin 9c17140b33 feat(contract): update contract template with amount fields
更新合同模板和 PDF 生成服务,支持动态计算金额字段。

## 合同模板更新
- 替换为新版联合种植协议模板(3页,带公章)
- 新增表单字段:totalAmount、totalAmountChinese、greenPointsAmount

## PDF 生成服务更新
- 新增单价常量:
  - PRICE_PER_TREE_CNY = 17414.1(人民币含税价)
  - PRICE_PER_TREE_GREEN_POINTS = 15831(绿积分价格)
- 新增 numberToChineseAmount() 函数:数字转中文大写金额
- 更新 ContractPdfData 接口:新增可选字段 totalAmount、greenPointsAmount
- 更新 fillFormFields():根据认种棵数自动计算金额
- 移除坐标定位填充方式,仅使用表单字段方式
- 所有表单字段现为必需,缺少时抛出明确错误

## 金额计算逻辑
- 人民币金额 = 棵数 × 17414.1
- 绿积分金额 = 棵数 × 15831
- 大写金额自动生成(如:壹万柒仟肆佰壹拾肆元壹角)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 20:21:37 -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 35a812c058 feat(authorization): add admin authorization management API and real data integration
Backend (authorization-service):
- Add QueryAuthorizationsDto for query parameters (roleType, keyword, includeRevoked, page, limit)
- Add queryAuthorizations method to fetch all authorizations with user info
- Add GET /admin/authorizations endpoint for listing authorizations
- Add POST /admin/authorizations/:id/revoke endpoint for revoking authorization

Frontend (admin-web):
- Add authorization.types.ts with RoleType, Authorization, and request types
- Add authorizationService.ts for API calls (list, revoke, grant operations)
- Add useAuthorizations.ts React Query hooks
- Update authorization page to use real API data instead of mock data
- Add loading/error states, pagination, and revoke reason display
- Add new styles for loading, error, pagination, and date columns

The authorization management page now displays all authorized users
from the database with support for filtering by role type, status,
and keyword search.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 18:50:10 -08:00
hailin dcd6f2ce18 fix: 修复特殊扣减API路径和批量创建用户ID解析问题
1. mobile-app: 修复特殊扣减API路径重复问题
   - 将 /api/v1/wallets/special-deduction/execute 改为 /wallets/special-deduction/execute
   - 因为 ApiClient baseURL 已包含 /api/v1 前缀

2. admin-web: 批量创建待办操作支持中文逗号分隔
   - 正则表达式从 /[\n,]/ 改为 /[\n,,]/
   - 同时支持换行、英文逗号、中文逗号作为分隔符

3. identity-service: 添加用户查找调试日志
   - 在 findUserByIdOrSequence 方法中添加日志
   - 便于排查用户ID查找失败的问题

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 17:54:27 -08:00
hailin dfdd8ed65a feat(pending-actions): add special deduction feature for admin-created user actions
实现特殊扣减功能,允许管理员为用户创建扣减待办操作,由用户在移动端确认执行。

## 后端 (wallet-service)

### 领域层
- 新增 `SPECIAL_DEDUCTION` 到 LedgerEntryType 枚举
  用于记录特殊扣减的账本流水类型

### 应用层
- 新增 `executeSpecialDeduction` 方法
  - 验证用户钱包存在性
  - 检查余额是否充足
  - 乐观锁控制并发
  - 扣减余额并记录账本流水
  - 返回操作结果和新余额

### API层
- 新增内部API: POST /api/v1/wallets/special-deduction/execute
  供移动端调用执行特殊扣减操作

## 前端 (admin-web)

### 类型定义
- 新增 `SPECIAL_DEDUCTION` 到 ACTION_CODES
- 新增 `SpecialDeductionParams` 接口定义扣减参数
  - amount: 扣减金额
  - reason: 扣减原因

### 页面
- 更新待办操作管理页面
  - 当选择 SPECIAL_DEDUCTION 时显示扣减金额和原因输入框
  - 验证扣减金额必须大于0
  - 验证扣减原因不能为空

### 样式
- 新增特殊扣减表单区域样式

## 前端 (mobile-app)

### 服务层
- 新增 `executeSpecialDeduction` 方法到 WalletService
- 新增 `SpecialDeductionResult` 结果类
- 新增 `specialDeduction` 到 PendingActionCode 枚举

### 页面
- 新增 `SpecialDeductionPage` 特殊扣减确认页面
  - 显示扣减金额和管理员备注
  - 显示当前余额和扣减后余额
  - 余额不足时禁用确认按钮
  - 温馨提示说明操作性质

- 更新 `PendingActionsPage`
  - 处理 SPECIAL_DEDUCTION 类型的待办操作
  - 从 actionParams 解析 amount 和 reason
  - 导航到特殊扣减确认页面

## 工作流程

1. 管理员在 admin-web 创建 SPECIAL_DEDUCTION 待办操作
   - 选择目标用户
   - 输入扣减金额
   - 输入扣减原因

2. 用户在 mobile-app 待办操作列表看到该操作

3. 用户点击后进入特殊扣减确认页面
   - 查看扣减详情
   - 确认余额充足
   - 点击确认执行扣减

4. 后端执行扣减并记录账本流水

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 07:04:46 -08:00
hailin a609600cd8 feat(fiat-withdrawal): add complete fiat withdrawal system
实现完整的法币提现功能,支持银行卡、支付宝、微信三种收款方式。
此功能与现有的区块链划转功能完全独立,互不影响。

## 后端 (wallet-service)

### 数据库
- 新增 `fiat_withdrawal_orders` 表存储法币提现订单
- 与现有 `withdrawal_orders` 表(区块链划转)完全分离
- 添加完整索引支持高效查询

### 领域层
- 新增 `FiatWithdrawalStatus` 枚举(与 WithdrawalStatus 独立)
  - 流程: PENDING -> FROZEN -> REVIEWING -> APPROVED -> PAYING -> COMPLETED
  - 或 REJECTED / FAILED / CANCELLED
- 新增 `PaymentMethod` 枚举: BANK_CARD / ALIPAY / WECHAT
- 新增 `FiatWithdrawalOrder` 聚合根
- 新增 `IFiatWithdrawalOrderRepository` 仓储接口
- 新增 `FIAT_WITHDRAWAL` 账本流水类型

### 应用层
- 新增 `FiatWithdrawalApplicationService` 处理业务逻辑
  - 发送短信验证码
  - 申请法币提现(冻结余额)
  - 提交审核
  - 审核通过/驳回
  - 开始打款
  - 完成打款

### API层
- 新增 `FiatWithdrawalController` 提供用户端API
  - POST /wallet/fiat-withdrawal/send-sms - 发送验证码
  - POST /wallet/fiat-withdrawal - 申请提现
  - GET /wallet/fiat-withdrawal - 获取提现记录
- 新增内部API供管理端调用
  - GET /api/v1/wallets/fiat-withdrawals - 查询订单
  - POST /api/v1/wallets/fiat-withdrawals/:orderNo/review - 审核
  - POST /api/v1/wallets/fiat-withdrawals/:orderNo/start-payment - 开始打款
  - POST /api/v1/wallets/fiat-withdrawals/:orderNo/complete-payment - 完成打款

## 前端 (admin-web)

- 新增法币提现审核管理页面 `/withdrawals`
- 支持按状态分 Tab 查看订单
- 支持审核通过/驳回
- 支持打款操作
- 支持查看订单详情

## 前端 (mobile-app)

- 新增 `WithdrawFiatPage` 法币提现页面
  - 支持选择银行卡/支付宝/微信
  - 输入收款账户信息
- 新增 `WithdrawFiatConfirmPage` 确认页面
  - 短信验证码验证
  - 密码验证
- 在 `WalletService` 中添加法币提现相关方法和模型

## 重要说明

此功能与现有的区块链划转功能 (withdraw_usdt_page.dart) 完全独立:
- 独立的数据库表
- 独立的聚合根
- 独立的状态枚举
- 独立的API端点
- 独立的前端页面

原有的区块链划转功能保持不变,不受任何影响。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 06:39:11 -08:00
hailin d614d18e97 Revert "feat(withdrawal): implement fiat withdrawal with bank/alipay/wechat"
This reverts commit 288d894746.
2026-01-03 05:44:43 -08:00
hailin 288d894746 feat(withdrawal): implement fiat withdrawal with bank/alipay/wechat
Add complete fiat withdrawal feature that allows users to withdraw
green credits (绿积分) to their bank card, Alipay, or WeChat account
with 1:1 CNY conversion. Key changes:

Backend (wallet-service):
- Update Prisma schema with fiat withdrawal fields (paymentMethod,
  bankName, bankCardNo, cardHolderName, alipay*, wechat*, review fields)
- Rewrite withdrawal status enum for fiat flow: PENDING → FROZEN →
  REVIEWING → APPROVED → PAYING → COMPLETED (or REJECTED/FAILED)
- Add PaymentMethod enum: BANK_CARD, ALIPAY, WECHAT
- Update WithdrawalOrderAggregate with new fiat withdrawal methods
- Add review/payment workflow methods in WalletApplicationService
- Add internal API endpoints for admin withdrawal management
- Remove blockchain withdrawal event handler (no longer needed)

Frontend (admin-web):
- Add withdrawal review management page at /withdrawals
- Add tabs for reviewing/approved/paying order states
- Add withdrawal service and React Query hooks
- Add types for withdrawal orders and payment methods
- Add sidebar menu item for withdrawal review

Frontend (mobile-app):
- Add withdrawFiat() method to WalletService
- Add PaymentMethod enum with BANK_CARD/ALIPAY/WECHAT
- Create new WithdrawFiatPage for fiat withdrawal input
- Create WithdrawFiatConfirmPage with SMS + password verification
- Add routes for /withdraw/fiat and /withdraw/fiat/confirm
- Keep existing withdraw/usdt (划转) pages unchanged

Note: The existing withdraw_usdt_page.dart is for point-to-point
transfer (划转), which is a different feature from fiat withdrawal.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 05:28:05 -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 cbbef170e8 feat(pending-actions): display accountSequence alongside userId
- Add accountSequence field to PendingActionResponseDto
- Add helper methods to fetch accountSequence from UserAccount
- Update queryActions and getAction to include accountSequence
- Update admin-web table and detail view to show both fields
- accountSequence displayed prominently, userId shown as secondary info

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 21:33:03 -08:00
hailin 789d921fd7 fix(pending-actions): support accountSequence for user lookup
Allow admin to create pending actions using accountSequence (e.g.,
D25122700022) instead of requiring numeric userId.

- Add findUserByIdOrSequence helper method
- Update createAction to use helper
- Update batchCreateActions to use helper
- Update queryActions to support accountSequence filter

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 20:39:54 -08:00
hailin 582e80b750 fix(pending-actions): add @Public() decorator to AdminPendingActionController
Skip JWT auth for admin pending-actions endpoints since admin-web
authenticates through a different mechanism (admin-service tokens).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 19:00:24 -08:00