Commit Graph

23 Commits

Author SHA1 Message Date
hailin f4c9535e12 feat(capability): 补齐全部后端 API 能力拦截
## 背景
审计发现 13 项用户能力中,部分后端 API 端点缺少 @RequireCapability
拦截,用户可绕过前端 UI 限制直接调用 API。本次逐服务补齐。

## Phase 1: 高优先级 — 操作端点

### auth-service
- POST /auth/password/change → @RequireCapability('PROFILE_EDIT')
  修改登录密码需要 PROFILE_EDIT 能力
- POST /auth/trade-password/set → @RequireCapability('PROFILE_EDIT')
  设置交易密码需要 PROFILE_EDIT 能力
- POST /auth/trade-password/change → @RequireCapability('PROFILE_EDIT')
  修改交易密码需要 PROFILE_EDIT 能力
- POST /auth/trade-password/verify → @RequireCapability('TRADING')
  验证交易密码是交易前置步骤,需要 TRADING 能力

### trading-service
- POST /c2c/orders/:orderNo/cancel → @RequireCapability('C2C')
  C2C 取消订单是唯一缺失 C2C 能力检查的操作端点

## Phase 2: 低优先级 — 查看端点

### trading-service
- GET /trading/orders → VIEW_RECORDS (用户订单列表)
- GET /trading/trades → VIEW_RECORDS (成交记录)
- GET /transfers/history → VIEW_RECORDS (划转历史)
- GET /p2p/transfers/:accountSequence → VIEW_RECORDS (P2P转账历史)
- GET /c2c/orders/my → VIEW_RECORDS (我的C2C订单)

### contribution-service
- GET /contribution/accounts/:accountSequence/active → VIEW_ASSET
- GET /contribution/accounts/:accountSequence/planting-ledger → VIEW_RECORDS

## 能力覆盖总览 (补齐后)
| 能力 | 端点数 | 状态 |
|------|--------|------|
| LOGIN | 全局 |  JwtAuthGuard 拦截 |
| TRADING | 3 |  createOrder, cancelOrder, verifyTradePassword |
| C2C | 6 |  create, take, cancel, confirmPayment, confirmReceived, uploadProof |
| TRANSFER_IN | 1 |  transferIn |
| TRANSFER_OUT | 1 |  transferOut |
| P2P_SEND | 1 |  transfer |
| KYC | 1 |  submitKyc |
| PROFILE_EDIT | 3 |  changePassword, setTradePassword, changeTradePassword |
| VIEW_ASSET | 2 |  getMyAsset, getActiveContribution |
| VIEW_TEAM | 2 |  getMyTeamInfo, getDirectReferrals |
| VIEW_RECORDS | 6 |  各服务历史记录端点 |
| P2P_RECEIVE | 0 | 仅前端展示控制(无后端操作端点) |
| MINING_CLAIM | 0 | mining-service 需后续重构(@Public 类级别) |

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 05:22:37 -08:00
hailin 55cfc96464 feat(capability): 实现用户能力权限控制系统(Capability-based Permission)
借鉴 Stripe Capability 模型,实现 13 项细粒度用户功能权限控制:
LOGIN, TRADING, C2C, TRANSFER_IN/OUT, P2P_SEND/RECEIVE,
MINING_CLAIM, KYC, PROFILE_EDIT, VIEW_ASSET/TEAM/RECORDS

## 架构设计
- auth-service 为能力数据唯一写入点(DB + Redis DB14 缓存)
- 下游服务通过独立 ioredis 客户端直连 Redis DB14 检查能力(~1ms)
- 默认全部开启(fail-open):无缓存/Redis 故障 = 允许通行
- Guard 执行顺序:JwtAuthGuard → CapabilityGuard

## Phase 1: auth-service 核心
- Prisma Schema: UserCapability + CapabilityLog 两张表
- Domain: Capability 枚举, CapabilityMap 类型, Repository 接口
- Infrastructure: PrismaCapabilityRepository(含 $transaction 原子操作)
- Application: CapabilityService(Redis 缓存优先 → DB fallback → 写回 Redis TTL 1h)
- Scheduler: 每 60 秒扫描到期限制自动恢复(Redis 分布式锁防重复)
- API: GET /auth/user/capabilities (JWT), Internal CRUD API (服务间)
- 登录/refreshToken 均增加 LOGIN 能力检查

## Phase 2: 下游 CapabilityGuard
- trading-service: 14 个端点标注(TRADING/C2C/TRANSFER/P2P_SEND/VIEW_ASSET)
- contribution-service: 3 个端点标注(VIEW_RECORDS/VIEW_TEAM)
- mining-service: Guard 注册 + JwtAuthGuard accountSequence 兼容修复
- auth-service: KYC 端点标注(controller 级别 UseGuards)

## Phase 3: mining-admin-service
- CapabilityAdminService: 代理 auth-service internal API + 本地 AuditLog
- CapabilityController: Admin CRUD + 批量设置 + 变更日志查询

## Phase 4: mining-admin-web
- capability-management.tsx: 分组 Switch 开关 + 禁用 Dialog(原因+到期时间)+ 变更日志分页
- React Query hooks: useCapabilities/useSetCapability/useCapabilityLogs
- 用户详情页新增"权限管理"Tab

## Phase 5: mining-app (Flutter)
- CapabilityMap 数据模型 + ForbiddenException 异常类
- api_client.dart: 403 响应适配 ExceptionFilter 包装格式
- capabilitiesProvider: 登录后获取能力列表,fail-open 降级

## 审计修复
- CRITICAL: users.api.ts capability 方法移入 usersApi 对象内部
- P0: Flutter 403 解析路径适配 {error:{code,message}} 实际格式
- P0: 批量接口 operatorId 提升到 body 顶层匹配 auth-service 契约
- P1: mining-service JwtAuthGuard accountSequence fallback payload.sub
- P1: refreshCache 加 try/catch 防止 Redis 故障导致 500
- P1: processExpiredRestrictions 改用 upsertWithLog 事务方法
- P1: C2C upload-proof 补加 @RequireCapability('C2C')
- HIGH: internal.controller.ts 新增 capability 枚举校验
- HIGH: admin capability.controller.ts adminId fallback + query params 类型修复
- MEDIUM: setCapability 改用 $transaction 保证 upsert+log 原子性

## 部署注意
- 需运行: cd auth-service && npx prisma migrate dev --name add_user_capabilities
- 需配置: mining-admin-service .env AUTH_SERVICE_URL=http://auth-service:3010

## 待后续处理(P2)
- P2P_RECEIVE 需在业务逻辑层检查(收款方无主动请求)
- MINING_CLAIM/PROFILE_EDIT 待对应端点实现后标注
- getCapabilities 返回 Map 转 Array 丢失 reason/expiresAt 详细字段

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 22:19:56 -08:00
hailin 9062346650 refactor(system-accounts): 移除 baseType 字段,使用 accountType+regionCode 复合唯一键
## 主要变更

### 数据模型简化
- 移除冗余的 baseType 字段,accountType 已包含类型信息
- 使用 accountType (OPERATION/PROVINCE/CITY/HEADQUARTERS) + regionCode (省市代码) 作为复合唯一键
- 所有查询改用 accountType+regionCode,100% 弃用数据库自增 ID

### contribution-service
- SystemAccount 表移除 baseType,改用 accountType+regionCode 唯一约束
- 修改算力分配逻辑,省市账户使用对应 regionCode
- 事件发布增加 regionCode 字段

### mining-service
- SystemMiningAccount 表使用 accountType+regionCode 唯一约束
- API 改为 /system-accounts/:accountType/records?regionCode=xxx 格式
- 挖矿分配逻辑支持按省市细分

### mining-admin-service
- SyncedSystemContribution 表使用 accountType+regionCode 唯一约束
- CDC 同步处理器适配新格式
- API 统一使用 accountType+regionCode 查询

## API 示例
- 运营账户: GET /admin/system-accounts/OPERATION/records
- 广东省: GET /admin/system-accounts/PROVINCE/records?regionCode=440000
- 广州市: GET /admin/system-accounts/CITY/records?regionCode=440100
- 总部: GET /admin/system-accounts/HEADQUARTERS/records

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 21:29:01 -08:00
hailin 5f2f223f7b fix(contribution): 修复 SystemAccountSyncedEvent 缺少 baseType/regionCode 参数
问题:
- admin.controller.ts 中 republishSystemAccounts 端点调用 SystemAccountSyncedEvent 时
  只传递了 4 个参数,但构造函数需要 6 个参数
- 缺少 baseType(基础类型)和 regionCode(区域代码)参数

修复:
- 添加 account.baseType 和 account.regionCode 参数
- 与 contribution-calculation.service.ts 中的调用保持一致

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 20:12:49 -08:00
hailin 1c787a22a3 fix(mining): 修复 mining-service 订阅错误的 Kafka topic
问题:mining-service 订阅的是 cdc.contribution.outbox (Debezium CDC topic),
但 contribution-service 使用 Outbox Pattern 直接发送到 contribution.{eventType} topic。

修复:
- mining-service 订阅正确的 topic 列表
- 修复消息解析逻辑支持 Outbox Pattern 消息格式
- contribution-service 添加 GET /admin/unallocated-contributions 端点(调试用)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 03:03:17 -08:00
hailin 4ec6c9f48b feat(contribution/mining-app): add team tree API using contribution-service 2.0
Add team info and direct referrals endpoints to contribution-service,
using SyncedReferral data synced via CDC. Update mining-app to use the
new v2 contribution API instead of legacy referral-service.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 09:17:18 -08:00
hailin 0241930011 feat(contribution/mining): sync unallocated contributions to mining-service
- Add UnallocatedContributionSyncedEvent in contribution-service
- Add event handler in mining-service's contribution-event.handler.ts
- Add handleUnallocatedContributionSynced in network-sync.service.ts
- Add admin endpoint to publish all unallocated contributions
- Sync pending/unallocated contributions to PendingContributionMining table

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 05:29:28 -08:00
hailin de5416aee6 feat(mining): 实现系统账户和待解锁算力参与挖矿
重大变更:
- 挖矿分母从用户有效算力改为全网理论算力(networkTotalContribution)
- 系统账户(运营12%/省1%/市2%)参与挖矿,有独立的挖矿记录
- 待解锁算力参与挖矿,收益归总部账户,记录包含完整来源信息

新增功能:
- mining-service: 系统挖矿账户表、待解锁算力表及相关挖矿记录表
- mining-service: NetworkSyncService 同步全网数据
- mining-service: /admin/sync-network 和 /admin/system-accounts 端点
- contribution-service: /admin/system-accounts 和发布系统账户事件端点
- mining-admin-service: 状态检查返回全网理论算力信息

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 03:39:56 -08:00
hailin b5fca7bb04 fix(mining-admin): 修复算力同步状态检查的 API 路径
- contribution-service: 给 /contribution/stats 接口添加 @Public() 装饰器
- mining-admin-service: 修正 API 路径从 api/v1 改为 api/v2

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 03:09:05 -08:00
hailin 81a58edaca fix(contribution-service): calculate totalContribution correctly in CDC event
Previously, totalContribution was incorrectly set to effectiveContribution.
Now correctly calculated as: personal + teamLevel + teamBonus

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 23:40:50 -08:00
hailin 8199bc4d66 feat(contribution): add CDC sync status API and fix deploy script timing
- Add initialSyncCompleted flag to track CDC sequential sync completion
- Add getSyncStatus() method to CDCConsumerService
- Add /health/cdc-sync endpoint to expose sync status
- Update deploy-mining.sh to wait for CDC sync completion before calling publish APIs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 21:34:58 -08:00
hailin dbe9ab223f feat(contribution): fix pending fields update and add network progress tracking
- Fix updateContribution to properly update levelXPending and bonusTierXPending fields
- Add NetworkAdoptionProgress and DailyContributionRate tables for tracking contribution coefficient
- Create ContributionRateService for dynamic rate calculation (base 22617, +0.3% per 100 trees after 1000)
- Add ContributionRecordSynced and NetworkProgressUpdated events for CDC sync
- Add admin endpoints for network progress query and contribution records publishing
- Update mining-admin-service to sync contribution records and network progress

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 07:26:32 -08:00
hailin 1b8791fe5d fix(contribution-service): 添加 unlockedBonusTiers 字段到同步事件
事件和 API 返回中缺少 unlockedBonusTiers 字段,导致
mining-admin-service 无法正确显示团队奖励解锁状态

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 05:09:01 -08:00
hailin 30b04c6376 feat(sync): 完善 CDC 数据同步 - 添加推荐关系、认种记录和昵称字段
- auth-service:
  - SyncedLegacyUser 表添加 nickname 字段
  - LegacyUserMigratedEvent 添加 nickname 参数
  - CDC consumer 同步 nickname 字段
  - SyncedLegacyUserData 接口添加 nickname

- contribution-service:
  - 新增 ReferralSyncedEvent 事件类
  - 新增 AdoptionSyncedEvent 事件类
  - admin.controller 添加 publish-all APIs:
    - POST /admin/referrals/publish-all
    - POST /admin/adoptions/publish-all

- mining-admin-service:
  - SyncedUser 表添加 nickname 字段
  - 新增 SyncedReferral 表 (推荐关系)
  - 新增 SyncedAdoption 表 (认种记录)
  - handleReferralSynced 处理器
  - handleAdoptionSynced 处理器
  - handleLegacyUserMigrated 处理 nickname

- deploy-mining.sh:
  - full_reset 更新为 14 步
  - Step 13: 发布推荐关系
  - Step 14: 发布认种记录

解决 mining-admin-web 缺少昵称、推荐人、认种数据的问题

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 02:48:15 -08:00
hailin 40745ca580 feat(cdc): 完善 2.0 服务数据聚合到 mining-admin-service
1. deploy-mining.sh:
   - 添加 outbox connectors 配置数组 (auth, contribution, mining, trading, wallet)
   - 添加 register_outbox_connectors() 函数自动注册 Debezium 连接器
   - 添加 outbox-register, outbox-status, outbox-delete 命令
   - full-reset 更新为 12 步,包含注册 outbox connectors 和初始数据发布

2. contribution-service:
   - 添加 ContributionAccountSyncedEvent 事件
   - 添加 POST /admin/contribution-accounts/publish-all API 用于初始全量同步

3. mining-admin-service:
   - 添加 ContributionAccountSynced 事件处理(复用 ContributionAccountUpdated 处理器)
   - 添加 ContributionCalculated 事件处理

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 01:41:46 -08:00
hailin 05f98def6d fix(sync): 修复数据同步 API 认证和响应解析
- 为 contribution/mining/trading 服务的 AdminController 添加 @Public 装饰器
- 修复 initialization.service.ts 中响应格式解析,支持 { data: { ... } } 格式

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 21:47:32 -08:00
hailin 3fe6bdbbf0 feat(sync): 添加批量同步 API 端点
- 为 contribution-service、mining-service、trading-service 添加 AdminController
- 提供 /admin/accounts/sync 端点用于批量获取账户数据
- 在 mining-admin-service 添加同步 mining/trading 账户的初始化端点
- 添加 sync-all 端点支持一键同步所有数据

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 21:27:35 -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 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 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 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