Commit Graph

2247 Commits

Author SHA1 Message Date
hailin 6bcc571453 revert(c2c): 还原C2C市场页资产概览为原始状态
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 09:25:03 -08:00
hailin 0ad1136e48 fix(c2c): 修正资产概览显示,C2C只涉及积分值不涉及积分股
左栏改回"可用积分值",右栏改为"冻结积分值",消除重复显示。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 09:23:59 -08:00
hailin f60e3751b8 fix(c2c): 修复水单上传权限、手机号、卖方ID、资产显示
- Dockerfile: 用 su-exec 模式解决 Docker volume 权限问题
- JWT guard: 从 token 提取 phone 字段
- 订单详情: 新增卖方ID显示
- C2C市场页: 修复资产概览两列重复显示 availableCash,
  改为左列显示可用积分股、右列显示可用积分值

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 09:19:38 -08:00
hailin e783661002 fix(c2c): 修复水单上传权限、手机号显示、卖方ID显示
- Dockerfile 预创建 /app/uploads/c2c-proofs 并设置正确权限
- JWT guard 从 token payload 提取 phone 字段(之前仅提取 accountSequence)
- 订单详情页订单信息组新增卖方ID显示

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 09:13:46 -08:00
hailin 25ea0bf64e fix(trading-service): 修复 Multer 类型缺失导致构建失败
使用内联类型替代 Express.Multer.File,避免 @types/multer 依赖

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 08:58:55 -08:00
hailin ce173451f5 feat(c2c): 订单详情增强、付款水单上传、买单逻辑修复及schema对齐
- 订单详情页显示完整手机号和收款账号信息
- 新增付款水单上传功能(前后端全链路)
- 修复时间显示为本地时区格式
- 移除买单发布时的积分值余额验证(买方通过外部绿积分支付)
- 前端买单发布页隐藏余额卡片和"全部"按钮
- 补齐 Prisma migration 与 schema 差异(payment_proof_url、
  bot_purchased索引、market_maker_deposits/withdraws表)
- docker-compose 新增 trading-uploads 卷用于水单持久化

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 08:54:05 -08:00
hailin 4df23b02b8 fix(trading-service): 添加做市商钱包环境变量,修复地址未配置问题
FUSDT/EUSDT_MARKET_MAKER_ADDRESS 和 USERNAME 只传给了
mining-blockchain-service,但 trading-service 初始化时也需要
读取这些变量写入数据库,导致前端显示"做市商钱包地址未配置"。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 07:56:16 -08:00
hailin c5126187d2 feat(mining-app): 二维码扫描支持从相册选择图片识别
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 07:21:56 -08:00
hailin 286b82c63b fix(c2c): 修复 RangeError 崩溃及订单详情灰色页面问题
根因:多处 [0] 访问空列表/空字符串导致 RangeError 崩溃

- api_client.dart: 后端错误 message 为空数组时 ?[0] 崩溃,改为安全检查
- c2c_order_detail_page.dart: nickname 和 phone 均为 null 时 name[0] 崩溃,
  添加 isNotEmpty 检查和 '未知用户' 回退
- c2c_market_page.dart: makerNickname 为空字符串时 [0] 崩溃,添加 isNotEmpty 检查

这是 C2C 买方"待付款灰色页面"的根本原因:页面在渲染交易双方信息时
因空用户名 RangeError 崩溃,导致整个页面无法显示

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 07:10:05 -08:00
hailin 8e63547a3e fix(transfer): 修复积分股划转到分配账户失败问题
后端:
- transfer.service.ts: Error → BadRequestException,业务错误返回HTTP 400而非500
- transfer.controller.ts: Error → UnauthorizedException,正确返回HTTP 401
- 错误信息改为中文:余额不足、账户不存在等提示更明确

前端:
- asset_display.dart: 新增 tradingAvailableShares 计算属性(总可用 - 挖矿可用)
- trading_page.dart: 划转弹窗显示可用余额(扣除冻结)而非总余额
- trading_page.dart: 划转失败时显示后端具体错误信息而非通用提示

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 06:24:35 -08:00
hailin 3cbb874503 fix(auth-service): 返回完整手机号,修复QR码扫码失败
- login/profile 接口返回 user.phone.value 替代 user.phone.masked
- 根因:QR码编码脱敏号 199****9327,正则要求纯数字匹配失败

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 06:00:47 -08:00
hailin 0ffa875a85 fix(mining-app): 移除 debug applicationIdSuffix 修复升级后双图标
debug buildType 设置了 applicationIdSuffix = ".debug",导致
debug 包名为 com.rwadurian.mining_app.debug,release 包名为
com.rwadurian.mining_app。Android 将它们视为两个不同应用,
升级安装 release 包时不覆盖 debug 包,出现两个相同图标。

移除 applicationIdSuffix 后 debug/release 使用同一包名,
升级安装时会正确覆盖旧版本。versionNameSuffix 保留用于区分版本号。

注:用户手机上需手动卸载旧的 debug 包才能清除已存在的重复图标。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 05:57:34 -08:00
hailin 03cc5bc324 fix(mining-app): QR码解析加固 + debugPrint排查
- 清除不可见字符(BOM/零宽空格)
- 三级宽松解析:正则→Uri.parse→兜底phone=提取
- 添加 [QR_SCAN] 调试日志定位实际扫码值

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 05:54:34 -08:00
hailin 8c31dee000 fix(c2c): 修复买方待付款页面灰色无法操作问题
根因: c2c_order_model.dart 的 _parsePaymentMethod 不识别 GREEN_POINTS,
导致 paymentMethod=null → hasPaymentInfo=false → 收款信息卡片隐藏 → 页面不可操作

前端修复:
- C2cPaymentMethod 枚举增加 greenPoints,解析器支持 GREEN_POINTS
- 支持逗号分隔的多支付方式字符串(取第一个作为主要方式)
- 订单详情页增加绿积分图标和卖方 Kava 地址显示(买方可复制)

后端修复:
- takeOrder() 接买单时自动获取卖方 Kava 地址写入 sellerKavaAddress
- 买方在订单详情页可看到卖方 Kava 地址用于转绿积分

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 05:41:14 -08:00
hailin f167f1227c Revert "fix(trading-service): C2C卖单不再强制要求Kava钱包地址"
This reverts commit 9b8f720915.
2026-01-30 21:04:27 -08:00
hailin 9b8f720915 fix(trading-service): C2C卖单不再强制要求Kava钱包地址
executeTransfer不使用sellerKavaAddress,C2C交易是积分值划转+外部绿积分支付,
不涉及Kava链上操作。改为可选获取,失败不阻断订单创建。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:03:59 -08:00
hailin 9e83127113 fix(mining-app): C2C"我的"列表待接单订单增加取消按钮
在我的订单卡片上直接显示取消按钮(PENDING状态),
弹出确认对话框后调用 cancelOrder API

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 20:46:50 -08:00
hailin 7c416adecd feat(mining-app): P2P转出记录显示手续费及合计扣除
- P2pTransferModel 新增 fee 字段解析
- 转出卡片聚合显示:转账金额 + 手续费 + 合计扣除
- 转入卡片保持只显示转账金额

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 20:45:37 -08:00
hailin 7180e2ac27 fix(contribution): 算力记录按层级升序排列 L1→L2→...→L15
用户期望 L1 在前 L15 在后,将 levelDepth/bonusTier 排序从 DESC 改为 ASC

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 20:14:31 -08:00
hailin 7d548dac4e fix(mining-app): C2C接单验证收款信息 + 数字显示优化
- 接BUY单时验证收款账号和姓名必填,仅绿积分时自动使用账户ID
- 所有C2C价格/数量/金额显示改用formatCompact,去掉多余小数位

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:31:08 -08:00
hailin 17f8a61bcf feat(contribution-service): 贡献值明细按 L/T 降序排序
- 同伴下贡献值 (TEAM_LEVEL): 按 levelDepth DESC 排序 (L3, L2, L1)
- 同伴上贡献值 (TEAM_BONUS): 按 bonusTier DESC 排序 (T3, T2, T1)
- 全部/本人: 按 levelDepth DESC, bonusTier DESC, createdAt DESC

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:20:03 -08:00
hailin a31fcaa9b8 fix(mining-admin): configValue → value,修复配置读取后 fallback 到默认值
Prisma 返回的字段是 value,controller 写成了 configValue,
导致 getP2pTransferFee / getTransferEnabled 永远返回默认值

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:18:13 -08:00
hailin b50091eb1e fix(mining-app): C2C 发布页"积分值金额"改为"绿积分数量"
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:09:17 -08:00
hailin a0750fbd42 fix(mining-app): C2C 发布页单价单位改为"绿积分/积分值"
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:07:31 -08:00
hailin d91550f704 fix(mining-app): FileProvider 使用 root-path 覆盖 Flutter app_flutter 目录
files-path 映射到 getFilesDir() 即 /data/data/<pkg>/files/,
但 Flutter getApplicationDocumentsDirectory() 返回 /data/data/<pkg>/app_flutter/,
两者是同级目录而非父子关系,files-path 无法覆盖。
使用 root-path 映射设备根路径 /,确保所有内部路径都能被 FileProvider 解析。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 13:58:23 -08:00
hailin 45d038bd4b fix(mining-app): FileProvider 添加 app_flutter 路径,修复 APK 安装 IllegalArgumentException
下载的 APK 保存在 getApplicationDocumentsDirectory() 即 /data/data/<pkg>/app_flutter/updates/,
但 file_paths.xml 只配置了 files-path(对应 /data/data/<pkg>/files/),
导致 FileProvider.getUriForFile() 找不到匹配的根路径。
添加 <files-path name="app_flutter" path="app_flutter/" /> 与 mobile-app 保持一致。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 13:44:00 -08:00
hailin a27ed0fa16 fix(mining-app): APK 安装后调用 finishAffinity() 退出旧应用,与 mobile-app 保持一致
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 13:30:42 -08:00
hailin 3507805005 fix(mining-admin): Docker uploads 目录权限修复,预创建 /app/uploads 并设置 nestjs 用户所有权
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 13:19:14 -08:00
hailin 6900905475 fix(mining-admin): APK下载URL指向localhost导致手机无法下载
问题:FileStorageService 默认 UPLOAD_BASE_URL 为 http://localhost:3020/downloads,
手机端无法访问服务器的 localhost。

修复:
- docker-compose.2.0.yml: 添加 UPLOAD_BASE_URL=https://rwaapi.szaiai.com/mining-admin/downloads
- 添加 mining-admin-uploads volume 持久化上传的 APK 文件
- 修正默认端口 3020→3023(mining-admin-service 实际端口)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 12:56:40 -08:00
hailin 94d4524ee3 fix(c2c): 积分股→积分值,C2C交易对象修正为积分值(cash)
C2C交易的产品是积分值,支付方式是绿积分(外部1.0系统),与积分股无关。

前端:
- c2c_publish_page: 余额卡、数量输入、提示文案、确认弹窗全部改为积分值
- c2c_market_page: 余额概览(availableShares→availableCash)、订单数量标签、接单弹窗
- c2c_order_detail_page: 订单详情、划转提示、确认收款弹窗

后端 c2c.service.ts:
- createOrder SELL: freezeShares→freezeCash
- takeOrder BUY(taker=卖方): freezeShares→freezeCash
- takeOrder SELL(taker=买方): 移除冻结(买方通过外部支付绿积分)
- cancelOrder SELL: unfreezeShares→unfreezeCash
- expireOrder: unfreezeShares→unfreezeCash,SELL不再解冻taker
- executeTransfer: 统一BUY/SELL为单向积分值划转,assetType改为CASH

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 12:41:23 -08:00
hailin 49bcb96c4c fix(trading): 补充 p2p_transfers 表遗漏的 fee 列
schema 中定义了 fee 字段但 0002 migration 遗漏,导致
prisma.p2pTransfer.create() 报错 "column fee does not exist"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 12:24:50 -08:00
hailin cfa0e2ca40 fix(mining-app): 更新弹窗点击"立即更新"无反应 — 进度流订阅竞态修复
问题根因:
SelfHostedUpdater._listenToProgress() 在 initState 和 _startDownload 中
订阅 UpdateService.downloadProgressStream,但该 getter 返回
_downloadManager?.progressStream —— _downloadManager 在 downloadUpdate()
调用前为 null,?.listen 无操作。downloadUpdate() 创建新 _downloadManager
后,其 progressStream 无人监听,进度事件全部丢失,UI 无任何反馈。

修复:
1. UpdateService 新增持久化广播流 _downloadProgressController,
   downloadUpdate() 创建新 DownloadManager 后将其进度转发到此流
2. downloadProgressStream getter 改为返回持久化流(非 nullable)
3. SelfHostedUpdater 在 initState 中一次性订阅持久化流,
   dispose 时取消订阅,_startDownload 不再重复订阅

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 12:24:47 -08:00
hailin bde7f0c53b fix(mining-app): 自动更新检查未触发 — 修复双重节流 + 添加调试日志
问题原因:
1. checkForUpdate() 未传 force:true,被 UpdateService 内部的60分钟
   SharedPreferences 间隔二次节流,导致实际请求被跳过
2. 缺少日志输出,无法诊断检查流程是否执行

修复:
- checkForUpdate(force: true) 跳过内部60分钟限制,
  因为 MainShell 已有自己的90-300秒随机冷却节流
- 在 initState / dispose / didChangeAppLifecycleState /
  _checkForUpdateIfNeeded 各关键节点添加 debugPrint 日志,
  方便 flutter run 控制台追踪完整检查流程

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 12:20:56 -08:00
hailin 53a2e64cad feat(mining-app): 启动和切回前台自动检测升级
MainShell 从 StatelessWidget 转为 StatefulWidget + WidgetsBindingObserver,
参考 mobile-app HomeShellPage 模式,实现:
- initState 首帧后自动检查更新
- didChangeAppLifecycleState(resumed) 从后台恢复时自动检查
- 90-300秒随机冷却间隔防止频繁请求(static 变量跨 rebuild 保持)
- 延迟3秒启动检查,避免干扰用户操作
- 有更新时弹出 SelfHostedUpdater 对话框(支持强制更新)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 12:07:40 -08:00
hailin f0c7cee94e fix(auth): lookupByPhone 支持查询未迁移的 1.0 用户
P2P 转账验证手机号时,lookupByPhone 只查 users 表(V2 注册用户),
导致未登录过 2.0 的 1.0 老用户(CDC 同步在 synced_legacy_users 表)
被报"不存在"。修改为先查 users 表,未找到再查 synced_legacy_users。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:41:58 -08:00
hailin 187b82e9ac feat(c2c): 修复6项C2C交易问题 (#11-#16)
- #11: 价格固定1:1,最小交易数量为1
- #12: BUY买单不再冻结买方积分值(绿积分通过外部1.0系统支付)
- #13: 支持部分成交,taker可指定数量,剩余自动拆分为新PENDING订单
- #14: 发布页双向输入,积分股数量与积分值金额1:1联动
- #15: 接BUY单时弹出收款信息输入(收款方式、账号、姓名)
- #16: BUY单创建时验证积分值余额但不冻结

后端: cancelOrder/expireOrder/executeTransfer 均按BUY/SELL分别处理
前端: 发布页价格只读、市场页接单对话框增加数量和收款输入

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:36:57 -08:00
hailin c28ccb6206 fix(mining-app): 总资产估值仅显示积分值,未包含积分股估值
问题:_calculateTotalAssetValue() 依赖 WebSocket 推送的 _currentPrice
和定时器初始化的 _currentShareBalance,在 WebSocket 未连接或定时器未
启动时这些值均为 0,导致 shareValue=0,总资产仅显示现金余额。

修复:当 WebSocket/_timer 未初始化时,回退到 API 返回的
asset.currentPrice、asset.burnMultiplier 和 asset.shareBalance,
与 _buildAssetList 中积分股估值的计算逻辑保持一致。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:03:41 -08:00
hailin 9adef67bb8 feat(admin-web): P2P划转记录管理页面 + 手续费汇总
## 后端 — mining-admin-service
- users.controller: 新增 GET /users/p2p-transfers 端点(搜索+分页)
  - 放在 :accountSequence 路由之前避免被 catch-all 拦截
- users.service: 新增 getP2pTransfers() 代理方法
  - 调用 trading-service 的 /api/v2/p2p/internal/all-transfers
  - 返回划转记录列表 + 汇总统计 + 分页信息

## 前端 — mining-admin-web
- 新增 /p2p-transfers 页面:
  - 三个汇总卡片:累计手续费收入、累计划转金额、成功划转笔数
  - 搜索框支持账号、手机号、转账单号搜索
  - 记录表格:转账单号、发送方、接收方、转账金额、手续费、备注、时间
  - 分页控件
- sidebar: 新增"P2P划转"导航项(位于"交易管理"下方)
- users.api: 新增 getP2pTransfers API + P2pTransferRecord 类型
- use-users: 新增 useP2pTransfers hook

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 10:41:55 -08:00
hailin 9f94344e8b feat: 算力记录排序 + P2P转账管理后台查询端点
## 算力记录排序(全栈)
- mining-admin-service controller: 新增 sortBy/sortOrder 查询参数
- users.service: 动态构建 orderBy(支持 sourceType, levelDepth, amount, createdAt)
  - levelDepth 排序特殊处理:先按 sourceType 分组,再按 levelDepth/bonusTier 排序,null 值排末尾
- admin-web contribution-records-list: 可点击排序表头(来源、获得算力、层级/等级、生效日期)
  - 三态切换:升序 → 降序 → 取消排序
  - 排序图标指示当前状态

## P2P转账管理后台查询端点(后端准备)
- trading-service P2pTransferService: 新增 getAllTransfers() 方法
  - 列出全部已完成 P2P 转账记录(分页 + 搜索)
  - 返回汇总统计:总手续费、总转账金额、总笔数
- trading-service controller: 新增 GET /p2p/internal/all-transfers(@Public 内部端点)
- P2pTransferHistoryItem 接口扩展 fromPhone/fromNickname/toNickname 字段

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 10:37:22 -08:00
hailin b1607666a0 fix(contribution): LEVEL_OVERFLOW 回收任务,修复已解锁层级的溢出记录无法被回收的 bug
当下级认种时上级 unlocked_level_depth 不足,层级奖励进入 LEVEL_OVERFLOW(PENDING)。
上级后续解锁到足够层级后,现有 backfill 因条件 expectedLevel > currentLevel 为 false
而跳过,导致 PENDING 记录永远无法被回收。新增独立调度任务每10分钟扫描并回收。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 10:12:48 -08:00
hailin ca4e5393be feat(p2p-transfer): 实现P2P划转手续费功能(全栈)
## 功能概述
- P2P转账(积分值)支持手续费收取,手续费存入系统成本费账户 S0000000002
- 发送方实际扣除 = 转账金额 + 手续费,接收方全额收到转账金额
- 手续费金额和最小划转金额可在管理后台动态配置(默认: 手续费5, 最小划转6)

## 后端 — mining-admin-service
- GET /configs/p2p-transfer-fee: 管理端获取手续费配置(需鉴权)
- POST /configs/p2p-transfer-fee: 管理端设置手续费配置,校验最小划转 > 手续费
- GET /configs/internal/p2p-transfer-fee: 内部调用端点(@Public 无鉴权)

## 后端 — trading-service
- Prisma schema: P2pTransfer model 新增 fee Decimal(30,8) 字段
- docker-compose: 新增 MINING_ADMIN_SERVICE_URL 环境变量
- p2p-transfer.service: 动态获取手续费配置,余额校验含手续费,
  事务内分别记录转账流水和手续费流水(P2P_TRANSFER_FEE),
  手续费存入系统成本费账户 S0000000002
- p2p-transfer.controller: 新增 GET /p2p/transfer-fee-config 代理端点
- 转账结果和历史记录新增 fee 字段返回

## 前端 — mining-admin-web
- configs.api.ts: 新增 getP2pTransferFee / setP2pTransferFee API
- use-configs.ts: 新增 useP2pTransferFee / useSetP2pTransferFee hooks
- configs/page.tsx: 新增"P2P划转手续费设置"卡片(手续费 + 最小划转金额)

## 前端 — mining-app (Flutter)
- api_endpoints.dart: 新增 p2pTransferFeeConfig 端点常量
- p2p_transfer_fee_config_model.dart: 新增手续费配置 Model
- trading_remote_datasource.dart: 新增 getP2pTransferFeeConfig 方法
- transfer_providers.dart: 新增 p2pTransferFeeConfigProvider
- send_shares_page.dart: 发送页面显示手续费信息、最小划转金额提示、
  实际扣除金额计算、"全部"按钮扣除手续费、确认弹窗展示手续费明细

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 06:44:19 -08:00
hailin 817b7d3a9f fix(contribution): 算力分配时序保证 + bonus补发stale-read修复
4处改动确保部署清库重新同步后100%可靠:

1. contribution.scheduler.ts - CDC就绪门控
   注入CDCConsumerService,processUnprocessedAdoptions/publishRecentlyUpdatedAccounts/
   processContributionBackfill三个调度方法开头加isCdcReady()检查,
   确保用户+推荐+认种三阶段CDC同步全部完成后才开始处理。

2. contribution-calculation.service.ts - 推荐数据防护
   calculateForAdoption()中,userReferral为null时warn并return,
   不标记distributed,调度器下次重试。覆盖continuous mode下
   认种事件先于推荐事件到达的竞态场景。

3. bonus-claim.service.ts - bonus补发stale-read修复
   processBackfillForAccount()中,level事务的updateAccountUnlockStatus
   通过incrementDirectReferralAdoptedCount()同时修改unlockedLevelDepth
   和unlockedBonusTiers,导致bonus分支条件永远为false。
   修复:保存originalDirectReferralAdoptedCount和originalUnlockedBonusTiers,
   bonus分支使用原始值判断和传参。

4. config.controller.ts - mining-admin同步检查增强
   isSynced新增allAdoptionsProcessed条件(unprocessedAdoptions===0),
   确保所有认种分配+补发完成后才允许激活挖矿。
   修复data变量作用域问题(原在if块内声明,外部引用会报错)。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 05:54:02 -08:00
hailin 83384acdac fix(mining-service): Redis DB 11 冲突修复,迁移至 DB 16
问题:
  mining-service (2.0) 与 blockchain-service (1.0) 共用 Redis DB 11,
  存在数据污染和资源抢占风险。虽然当前 Key 前缀不同
  (mining:* vs blockchain:*),但缺乏结构性隔离保障。

方案:
  - 将 mining-service Redis DB 从 11 迁移到 16 (超出默认 0-15 范围)
  - Redis 基础设施配置增加 --databases 20,支持 DB 16+
  - 同步修正 .env.example 与代码默认值不一致的问题 (原 .env=1, 代码=11)

修改清单:
  - mining-service/infrastructure.module.ts: 代码默认值 11 → 16
  - mining-service/redis.service.ts: fallback 默认值 1 → 16
  - mining-service/.env.example: REDIS_DB=1 → REDIS_DB=16
  - docker-compose.2.0.yml: mining-service REDIS_DB 11 → 16 + 注释
  - docker-compose.yml: Redis 添加 --databases 20
  - docker-compose.infra.yml: Redis 添加 --databases 20
  - docker-compose.windows.yml: Redis 添加 --databases 20

部署注意:
  1. 需重启 Redis 容器使 --databases 20 生效
  2. 需重启 mining-service 使新 DB 16 生效
  3. 旧 DB 11 中 mining-service 的残留数据可手动清理:
     redis-cli -n 11 KEYS "mining:*" | xargs redis-cli -n 11 DEL

Redis DB 分配表 (修改后):
  1.0: DB 0-11 (identity=0, wallet=1, ..., blockchain=11)
  2.0: DB 8,10,12-16 (blockchain=8, contribution=10, trading=12,
       admin=13, auth=14, wallet=15, mining=16)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 02:22:20 -08:00
hailin 454b379f6c feat(mining-blockchain-service): mining_ 前缀隔离,与 blockchain-service 100% 资源分离
mining-blockchain-service 的所有共享资源全部加上 mining_ 前缀,
确保与 1.0 blockchain-service 完全隔离,互不干扰。

## Kafka Topic 隔离 — 生产者 (event-publisher.service.ts)

- source header: 'blockchain-service' → 'mining-blockchain-service'
- topic 映射全部加 mining_ 前缀:
  - blockchain.deposits → mining_blockchain.deposits
  - blockchain.wallets → mining_blockchain.wallets
  - blockchain.transactions → mining_blockchain.transactions
  - mpc.SigningRequested → mining_mpc.SigningRequested
  - blockchain.market_maker.deposits → mining_blockchain.market_maker.deposits
  - 默认 fallback: blockchain.events → mining_blockchain.events

## Domain Event eventType 隔离 (5 个事件类)

- deposit-detected.event.ts: mining_blockchain.deposit.detected
- deposit-confirmed.event.ts: mining_blockchain.deposit.confirmed
- wallet-address-created.event.ts: mining_blockchain.wallet.address.created
- transaction-broadcasted.event.ts: mining_blockchain.transaction.broadcasted
- market-maker-deposit-confirmed.event.ts: mining_blockchain.market_maker.deposit.confirmed

## Kafka Topic 隔离 — 消费者 (3 个 consumer)

- mpc-event-consumer: mining_mpc.KeygenCompleted / SigningCompleted / SessionFailed
- withdrawal-event-consumer: mining_wallet.withdrawals / mining_wallet.system-withdrawals
  - 事件类型检查: mining_wallet.withdrawal.requested / mining_wallet.system-withdrawal.requested
- deposit-ack-consumer: mining_wallet.acks
  - 事件类型检查: mining_wallet.deposit.credited
  - outbox ACK 匹配: mining_blockchain.deposit.confirmed

## Kafka 事件类型 — Event Handlers

- mpc-signing.client.ts:
  - MPC_SIGNING_TOPIC → mining_mpc.SigningRequested
  - eventType → mining_blockchain.mpc.signing.requested
- withdrawal-requested.handler.ts:
  - mining_blockchain.withdrawal.confirmed / failed / status
- system-withdrawal-requested.handler.ts:
  - mining_blockchain.system-withdrawal.confirmed / failed

## Redis Key 前缀隔离

- address-cache: blockchain:monitored_addresses: → mining_blockchain:monitored_addresses:
- hot-wallet-balance: hot_wallet:dusdt_balance: → mining_hot_wallet:dusdt_balance:
- hot-wallet-balance: hot_wallet:native_balance: → mining_hot_wallet:native_balance:

## 数据库名称隔离

- docker-compose.yml: rwa_blockchain → rwa_mining_blockchain
- docker-compose.2.0.yml: rwa_blockchain → rwa_mining_blockchain
- deploy-mining.sh: MINING_DATABASES + SERVICE_DB 映射 → rwa_mining_blockchain

## 下游服务需配套更新 (不在本次修改范围)

- mpc-service: 消费 mining_mpc.SigningRequested, 发布 mining_mpc.* 结果
- mining-wallet-service: 发布 mining_wallet.*, 消费 mining_blockchain.*
- trading-service: 消费 mining_blockchain.market_maker.deposits

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 01:58:45 -08:00
hailin 08cf4681f2 fix: migration 使用 IF NOT EXISTS 防止重复创建 + clean 去掉 --remove-orphans
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 00:37:29 -08:00
hailin 4a803ea008 feat(deploy): 添加 clean 命令清除 2.0 所有 Docker 资源
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 23:36:35 -08:00
hailin 6b92ab0dd8 Revert "fix(2.0): 所有 Kafka consumer 改为 fromBeginning: true 确保 full-reset 全量同步"
This reverts commit 534d4ce70c.
2026-01-29 22:41:40 -08:00
hailin a41feb841f fix(mining-service): 添加 ManualMiningRecord 缺失的 migration 0004
schema 中定义的 manual_mining_records 表缺少对应的 migration 文件,
导致 schema 与 migration 不一致。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 22:30:04 -08:00
hailin 534d4ce70c fix(2.0): 所有 Kafka consumer 改为 fromBeginning: true 确保 full-reset 全量同步
- mining-blockchain-service: withdrawal/mpc/deposit-ack consumer 改为 fromBeginning: true
- trading-service: cdc-consumer/market-maker-deposit consumer 改为 fromBeginning: true
- mining-service: contribution-event handler 改为 fromBeginning: true
- deploy-mining.sh: CDC_CONSUMER_GROUPS 补充所有 2.0 服务的 consumer group ID

确保 ./deploy-mining.sh full-reset 可以 100% 从 0 开始同步所有 1.0 数据。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 22:20:23 -08:00
hailin 830d99a504 feat(mining-app): 分离发送/接收记录 + 隐藏买入待开启
- 发送页右上角"转出记录"只显示转出明细
- 接收页右上角新增"接收记录"只显示转入明细
- P2pTransferRecordsPage 支持 filterDirection 参数过滤方向
- 兑换页隐藏"买入待开启" Tab(_showBuyTab=false,保留代码备启用)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 22:10:47 -08:00