Commit Graph

1445 Commits

Author SHA1 Message Date
hailin 65bd4f9b65 fix(mining-admin): remove MINING_ENABLED status filter for adoption stats
The adoption stats were showing 0 because the synced_adoptions table
contains status values directly from 1.0 system (PAID, POOL_INJECTED, etc.)
rather than MINING_ENABLED. Since contribution-service doesn't update the
status after calculating contributions, we now count all synced adoptions.

Changes:
- Remove status filter in getAdoptionStatsForUsers
- Remove status filter in getUserDetail adoption queries
- Remove status filter in getUserAdoptionStats for referral tree
- Add order count display in user detail page

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 01:21:01 -08:00
hailin 2f3a0f3652 feat(mining-admin): display adoption order count in user management
Backend:
- Add personalOrders and teamOrders to adoption stats
- Return order count alongside tree count in user list API

Frontend:
- Add personalAdoptionOrders and teamAdoptionOrders to UserOverview type
- Display format: "树数量(订单数)" e.g. "6(3单)"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 01:03:59 -08:00
hailin 56ff8290c1 fix(mining-admin): filter adoption stats by MINING_ENABLED status
Only count adoptions with status='MINING_ENABLED' when calculating:
- Personal adoption count (user list)
- Team adoption count (user list)
- Personal adoption stats (user detail)
- Direct referral adoptions (user detail)
- Team adoptions (user detail)
- Referral tree adoption stats

This fixes incorrect adoption counts that included pending/unconfirmed orders.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 00:58:01 -08:00
hailin f84e8b4700 fix(deploy): use kafka-console-producer for tombstone messages
kafkacat/kcat not available in containers. Switch to kafka-console-producer
with null.marker property to send tombstone messages for Debezium offset deletion.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 23:45:38 -08:00
hailin fe2d4c3bcf fix(deploy): use correct offset topic name (debezium_offsets)
The Debezium Connect container uses OFFSET_STORAGE_TOPIC=debezium_offsets,
not the default connect-offsets. This fix updates the tombstone method
to use the correct topic name.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 23:29:57 -08:00
hailin 416867b1d5 fix(deploy): delete Debezium connector offsets during full-reset
This fixes an issue where Debezium would skip initial snapshot after
full-reset because the connector offset persisted in Kafka Connect's
internal connect-offsets topic.

The fix adds two strategies to delete connector offsets:
1. REST API method (Kafka Connect 3.6+): DELETE /connectors/<name>/offsets
2. Tombstone method (Kafka Connect 3.5-): Send NULL messages via kafkacat

Reference: https://debezium.io/documentation/faq/#how_to_remove_committed_offsets_for_a_connector

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 23:17:45 -08:00
hailin 5af39193e4 fix(deploy): delete Kafka outbox topics during full-reset
Old messages in Kafka topics were corrupting the sync because they contained
outdated data from previous resets. Now we delete the outbox topics during
full-reset to ensure clean re-sync.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 22:38:31 -08:00
hailin 44f235b185 fix(deploy): add processed_events cleanup for mining-admin-service
The full-reset script was missing the cleanup of rwa_mining_admin.processed_events
table, which caused stale idempotency records to prevent re-consumption of
contribution outbox events after reset.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 22:23:44 -08:00
hailin 5e16adc1ec fix(mining-admin): use outbox_id for event idempotency key
The outbox_events table uses outbox_id as the primary key column name
(mapped from id in Prisma). When Debezium captures changes, the message
contains outbox_id field, not id. This caused all events to have
undefined eventId, resulting in duplicate detection treating all events
as duplicates after the first one.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 21:41:54 -08:00
hailin 5447545486 fix(contribution): move calculateForAdoption out of CDC transaction
Root cause: calculateForAdoption uses separate DB connections, which
cannot see uncommitted data in Serializable isolation level, causing
"Adoption not found" errors.

Solution (following Kafka Idempotent Consumer best practice):
- Add TransactionalCDCHandlerWithResult<T> type for handlers with return
- Add withIdempotencyAndCallback() wrapper for post-commit callbacks
- Add registerTransactionalHandlerWithCallback() registration method
- AdoptionSyncedHandler.handle() now returns AdoptionSyncResult
- Contribution calculation runs AFTER transaction commits via callback

Reference: Lydtech Consulting - Kafka Idempotent Consumer Pattern
https://www.lydtechconsulting.com/blog/kafka-idempotent-consumer-transactional-outbox

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 21:18:21 -08:00
hailin 2a4cb829fe fix(deploy-mining): truncate processed_cdc_events after CDC offset reset
Problem: full-reset script resets Kafka consumer offsets but doesn't
clear the processed_cdc_events table. When migrations run, containers
may start and consume CDC events, inserting records into this table.
After offset reset, the service restarts and detects all events as
"duplicates" because the idempotency records still exist.

Solution: Add TRUNCATE processed_cdc_events step after CDC offset reset
in Step 8, before starting services. This ensures the idempotency table
is in sync with the Kafka offset position.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 21:00:34 -08:00
hailin 3591271a3b fix(auth-service): add python3/make/g++ to builder stage for bcrypt
The bcrypt package requires native compilation. Added build dependencies
to the builder stage so npm ci can compile bcrypt successfully.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 20:20:41 -08:00
hailin e00c81153b docs(migrations): add detailed comments for idempotency tables
- Add comments explaining unique key composition:
  - CDC events: (source_topic, offset) = Kafka topic + message offset
  - Outbox events: (source_service, event_id) = service name + outbox ID
- Fix contribution-service migration:
  - Extend source_service column from VARCHAR(50) to VARCHAR(100)
  - Set source_service as NOT NULL to match schema
  - Use snake_case for index name consistency
- Clarify that offset/event_id are NOT database auto-increment IDs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 19:44:46 -08:00
hailin 9037c2da97 feat(auth): implement transactional idempotent CDC consumer for 1.0->2.0 sync
Implements 100% exactly-once semantics for CDC events from 1.0 identity-service
(user_accounts table) to auth-service.

Key changes:
- Add ProcessedCdcEvent model with (sourceTopic, offset) unique constraint
- Implement processWithIdempotency() using Serializable transaction isolation
- All database operations now use the transaction client
- Outbox event creation is also within the same transaction

This ensures that:
1. Each CDC event is processed exactly once
2. Idempotency record and business logic are in the same transaction
3. Outbox event publishing is atomic with data sync
4. Any failure causes complete rollback

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 19:29:42 -08:00
hailin ff67319171 feat(contribution): implement transactional idempotent CDC consumer for 1.0->2.0 sync
Implements 100% exactly-once semantics for CDC events from 1.0 databases
(identity-service, planting-service, referral-service) to contribution-service.

Key changes:
- Add ProcessedCdcEvent model with (sourceTopic, offset) unique constraint
- Add withIdempotency() wrapper using Serializable transaction isolation
- Add registerTransactionalHandler() for handlers requiring idempotency
- Modify CDC handlers to accept external transaction client
- All database operations now use the passed transaction client

This ensures that:
1. Each CDC event is processed exactly once
2. Idempotency record and business logic are in the same transaction
3. Any failure causes complete rollback

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 19:22:47 -08:00
hailin 70135938c4 feat(mining-admin): implement transactional idempotent consumer for 100% exactly-once semantics
- Use Prisma $transaction with Serializable isolation level
- Insert idempotency record FIRST, then execute business logic
- Unique constraint violation (P2002) indicates duplicate event
- All operations atomic - either fully commit or fully rollback
- Modified all handlers to accept transaction client parameter
- Removed old non-atomic isEventProcessed/recordProcessedEvent methods

This ensures 100% data consistency for CDC synchronization, which is
critical for financial data where any error is catastrophic.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 19:11:30 -08:00
hailin 577f626972 fix(cdc): implement idempotent consumer pattern for reliable CDC sync
- Use (sourceTopic, eventId) as composite unique key in processed_events
- Add sourceTopic to ServiceEvent for globally unique idempotency key
- Wrap all handlers with withIdempotency() for duplicate event detection
- Fix ID collision issue between different service outbox tables

This implements the industry-standard CDC exactly-once semantics pattern.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 13:31:10 -08:00
hailin 61da3652f5 fix(deploy): reorder full-reset steps for proper CDC sync
Changes:
1. Delete Debezium connectors BEFORE dropping databases (releases replication slots)
2. Start services BEFORE registering connectors (ensures tables exist and data is synced)
3. Register connectors AFTER services sync from 1.0 CDC (snapshot.mode=initial captures existing data)
4. Add wait time for connectors to initialize before publishing data

Step order: stop services → delete connectors → drop DBs → create DBs → migrate →
start services → wait for sync → register connectors → publish data

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 12:50:07 -08:00
hailin c31d64550b fix(deploy): remove duplicate contribution-records/publish-all call
The full-reset function was calling contribution-records/publish-all API
which caused duplicate records in mining-admin-service because:
- Contribution records are already published to outbox when calculated
- Debezium automatically captures outbox_events and sends to Kafka
- Calling publish-all again creates duplicate events with different IDs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 12:29:16 -08:00
hailin 1b3704b68d fix(contribution-service): fix property mapping in toDto method
The toDto method was accessing non-existent properties on ContributionAccountAggregate:
- teamLevelContribution -> totalLevelPending
- teamBonusContribution -> totalBonusPending
- totalContribution -> effectiveContribution
- isCalculated -> true (always calculated when account exists)
- lastCalculatedAt -> updatedAt

This was causing "Cannot read properties of undefined (reading 'value')" error
on GET /api/v2/contribution/accounts/{accountSequence}

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 12:17:31 -08:00
hailin bfafd6d34c refactor(prisma): consolidate migrations into single init files
Merge multiple incremental migrations into single init migration for each service:

- auth-service: 3 migrations → 1 (user auth, SMS, KYC)
- contribution-service: 4 migrations → 1 (contribution accounts, 15-level hierarchy, 3-tier bonus)
- mining-admin-service: 6 migrations → 1 (admin, CDC sync tables, prisma relation mode)
- mining-service: 1 migration (no change needed, renamed for consistency)
- mining-wallet-service: 3 migrations → 1 (wallet system, removed blockchain tables)
- trading-service: 1 migration (no change needed, renamed for consistency)

All migrations renamed from timestamp format (20260111000000_*) to sequential format (0001_init)
for cleaner migration history.

Note: Requires clearing _prisma_migrations table before applying to existing databases.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 11:04:24 -08:00
hailin 34e22d3c7f revert: restore original Dockerfiles 2026-01-12 10:12:16 -08:00
hailin d68ee398ab fix: add TEAM_BONUS cleanup to startup scripts
Delete incorrect TEAM_BONUS records (where account_sequence !=
source_account_sequence) on each container startup after migrations.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 10:10:51 -08:00
hailin ff3a614804 fix: remove broken data migration files 2026-01-12 10:08:10 -08:00
hailin 22fe23914f fix(contribution): simplify migration to only delete wrong TEAM_BONUS records
Remove the UPDATE statement that referenced non-existent columns.
The contribution_accounts table uses different field structure.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 09:59:11 -08:00
hailin 95e009966e fix(mining-admin): calculate distribution amounts from actual adoption data
Use treeCount * contributionPerTree from adoption record to calculate
the actual distribution amounts (70%, 12%, 1%, 2%, 15%) instead of
deriving from contribution_records table.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 09:55:27 -08:00
hailin e71f2aadfc fix: remove incorrect TEAM_BONUS records given to uplines
TEAM_BONUS should only be given to the adopter themselves, not to their
uplines. This migration deletes all TEAM_BONUS records where
account_sequence != source_account_sequence.

Also updates contribution_accounts totals in contribution-service.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 09:49:44 -08:00
hailin a89f4c829d feat(mining-admin): add migration for distributionSummary column
Add distributionSummary Text column to synced_adoptions table for storing
distribution details calculated during contribution calculation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 09:33:58 -08:00
hailin 23dabb0219 feat(contribution): display distribution details with actual amounts
Changes:
1. contribution-service:
   - Add distributionSummary field to SyncedAdoption schema
   - Store distribution summary after contribution calculation

2. mining-admin-service:
   - Add distributionSummary field to SyncedAdoption schema
   - Calculate actual distribution from contribution_records table
   - Return distribution details in planting ledger API

3. mining-admin-web:
   - Display distribution details in planting ledger table
   - Show: 70%(amount) personal, 12%(amount) operation,
     1%(amount) province, 2%(amount) city, 15%(amount) team
   - Show team distribution breakdown (distributed vs unallocated)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 09:23:02 -08:00
hailin 8d97daa524 fix(contribution): correct TEAM_BONUS distribution to adopter instead of referrer
TEAM_BONUS (7.5% = 2.5% × 3 tiers) should be given to the adopter themselves,
not to their direct referrer. The unlock conditions are:
- T1 (2.5%): Self adoption (always unlocked when adopting)
- T2 (2.5%): 2+ direct referrals adopted
- T3 (2.5%): 4+ direct referrals adopted

Also fixed findAncestorChain to correctly include the first ancestor
in the chain instead of skipping it.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 09:13:13 -08:00
hailin 01ff873264 fix(mining-admin): use Prisma relationMode=prisma for CDC sync tables
Switch to Prisma's "prisma" relation mode to handle CDC event ordering issues.
This mode emulates foreign key relations at the Prisma Client layer instead of
creating database-level FK constraints, which is the recommended approach for
CDC scenarios where event arrival order cannot be guaranteed.

Reference: https://www.prisma.io/docs/orm/prisma-schema/data-model/relations/relation-mode

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 08:33:21 -08:00
hailin ea789f7fec fix(mining-admin): remove CDC sync table foreign key constraints
CDC events arrive asynchronously and order is not guaranteed.
Child records (referrals, accounts) may arrive before parent (users).
This follows CDC best practices: destination tables should not have FK constraints.

Reference: https://estuary.dev/blog/cdc-done-correctly/

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 08:24:10 -08:00
hailin 40fbdec47c fix: add migration_lock.toml for prisma migrations
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 08:09:34 -08:00
hailin e337a1dda4 feat(mining-admin): add migration for contribution records and network progress tables
- Add synced_contribution_records table for tracking contribution ledger
- Add synced_network_progress table for tracking network-wide stats
- Revert Dockerfile to use prisma migrate deploy

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 08:07:16 -08:00
hailin 1c33dd7bf3 fix(mining-admin): auto-sync schema on container startup
- Change Dockerfile to use `prisma db push` instead of `migrate deploy`
- Add publish steps for contribution records and network progress in full-reset
- This ensures new tables are created automatically when schema changes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 08:03:38 -08:00
hailin bf5a16939f fix(mining-admin-service): ignore Debezium heartbeat messages
- Add isHeartbeatMessage to detect heartbeat messages (only have ts_ms field)
- Skip processing for heartbeat messages to avoid unnecessary warnings

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 07:44:27 -08:00
hailin 30e1867eb0 fix(mining-admin-service): properly handle Debezium outbox CDC events
- Add isDebeziumOutboxEvent to detect outbox table CDC messages
- Add handleDebeziumOutboxEvent to extract service event from payload.after
- Fix CDC consumer not recognizing events from contribution-service outbox

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 07:39:27 -08:00
hailin 52c573d507 fix(contribution-service): auto-publish contribution records on calculation
- Change saveMany to return saved records with IDs
- Update saveDistributionResult to use saved records for event publishing
- Contribution records are now automatically synced to mining-admin-service

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 07:32:50 -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 c0d0088b8e feat(contribution-service): enhance CDC event logging for debugging
Add detailed [CDC] prefixed logs to all CDC handlers:
- cdc-consumer.service.ts: log message parsing, handler dispatch
- user-synced.handler.ts: log user sync operations with field details
- adoption-synced.handler.ts: log adoption sync and contribution calc
- referral-synced.handler.ts: log referral relationship sync

All logs use consistent [CDC] prefix for easy filtering.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 06:41:24 -08:00
hailin 9642901710 fix(mining-wallet-service): remove remaining blockchain references
- Remove HOT_WALLET and COLD_WALLET from initializeCoreAccounts
- Remove BLOCKCHAIN from counterpartyType union

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 06:34:46 -08:00
hailin 8e30438433 refactor(mining-wallet-service): remove KAVA blockchain integration
- Remove KavaBlockchainService and blockchain.repository
- Remove BlockchainIntegrationService and BlockchainController
- Update health controller to remove blockchain check
- Clean up Prisma schema (remove blockchain models and enums)
- Add migration to drop blockchain-related tables

This functionality will be re-implemented when needed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 06:31:30 -08:00
hailin 025cc6871b fix(mining-wallet-service): 修复模块依赖注入问题
将 Kafka consumers 从 InfrastructureModule 移到 ApplicationModule,
因为 consumers 依赖 application 层的服务 (ContributionWalletService, SystemAccountService)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 06:20:32 -08:00
hailin 7fe954e563 feat(contribution/wallet): 实现贡献值2.0计算与钱包存储架构
主要变更:
- contribution-service: 添加省市字段到认种同步数据
- contribution-service: 实现分配结果发布服务,通过Outbox模式发布到Kafka
- contribution-service: 更新Outbox调度器,支持4小时最大退避重试
- mining-wallet-service: 添加贡献值消费者,处理分配结果入账
- mining-wallet-service: 添加用户注册消费者,自动创建钱包
- mining-wallet-service: 添加贡献值过期调度器
- mining-wallet-service: 系统账户添加contributionBalance字段

Kafka事件流:
- contribution.distribution.completed: 分配结果事件
- auth.user.registered: 用户注册事件

可靠性保证:
- Outbox模式确保事件可靠发布
- 4小时幂等退避策略(30s,1m,2m,5m,10m,30m,1h,2h,4h)
- Redis+DB双重幂等检查

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 06:13:18 -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 180e5ad057 feat(mining-admin): 重构算力构成展示,添加解锁状态
- 后端添加 unlockedBonusTiers 字段同步
- 前端算力构成卡片展示层级解锁(L1-15)和团队奖励解锁(3档)状态
- 移除无用的系统运营/省级/市级字段

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 04:59:51 -08:00
hailin bc191791e8 fix(mining-admin-service): getPlantingLedger从synced_adoptions读取真实数据
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 04:02:28 -08:00
hailin c141c3f6cd fix: TypeScript null check for originalUserId
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 03:50:29 -08:00
hailin 9e9a7364b9 fix(mining-admin-service): 实现getReferralTree返回真实推荐关系数据
- 从synced_referrals和synced_adoptions获取数据
- 实现getAncestors获取向上引荐人链
- 实现getDirectReferrals获取直推下级
- 实现getUserAdoptionStats获取认种统计

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 03:48:59 -08:00
hailin 2025c6ce36 fix(mining-admin): 用户列表API添加认种统计和推荐人信息
- 后端getUsers添加批量查询认种统计和推荐人信息
- 后端formatUserListItem返回adoption和referral字段
- 前端transformUserOverview映射新字段

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 03:42:54 -08:00
hailin 5ad71e2e4b fix(mining-admin-service): 用户列表API添加nickname字段
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 03:29:38 -08:00
hailin 5cff606e87 feat(mining-admin-service): 完善用户详情API返回字段
- getUserDetail 添加以下字段:
  - nickname: 昵称
  - referral: 推荐人信息 (referrerAccountSequence, referrerNickname, depth)
  - adoption: 认种统计 (personalAdoptionCount, directReferralAdoptions, teamAdoptions)
  - team: 团队统计 (directReferralCount, teamMemberCount)

- 从 synced_referrals 表获取推荐关系
- 从 synced_adoptions 表统计认种数量
- 通过 ancestorPath 计算团队成员和团队认种

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 03:11:19 -08:00
hailin 7b310c554b fix(migrations): 修复数据库迁移脚本语法
- 移除 IF NOT EXISTS,使用标准 Prisma 迁移格式
- 确保 full-reset 能正确执行迁移

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 03:07:14 -08:00
hailin 4635fea693 chore(migrations): 添加数据库迁移脚本
- auth-service: 20260112110000_add_nickname_to_synced_legacy_users
  - synced_legacy_users 表添加 nickname 字段

- mining-admin-service: 20260112110000_add_referral_adoption_nickname
  - synced_users 表添加 nickname 字段
  - 创建 synced_referrals 表 (推荐关系)
  - 创建 synced_adoptions 表 (认种记录)
  - 相关索引和外键约束

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 03:02:55 -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 11eb1f8a04 fix(postgres): 增加数据库最大连接数到 300
- max_connections: 100 -> 300
- max_replication_slots: 10 -> 20
- max_wal_senders: 10 -> 20

支持更多服务和 Debezium connectors 同时连接

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 02:29:35 -08:00
hailin a4e1859fd2 fix(debezium): 修复 outbox connector 配置中的数据库凭证
使用实际的用户名和密码替代环境变量占位符,
因为 envsubst 不支持带默认值的变量语法

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 02:13:07 -08:00
hailin 93c9007045 fix(deploy): 修正 Debezium Connect 默认端口为 8084
docker-compose 中 Debezium Connect 映射到 8084 端口

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 02:11:19 -08:00
hailin cbdb449533 fix(auth): 修复 LegacyUserCdcConsumer 的 OutboxService 依赖注入
- 在 ApplicationModule 中导出 OutboxService
- 在 InfrastructureModule 中使用 forwardRef 导入 ApplicationModule
- 解决循环依赖问题

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 02:00:21 -08:00
hailin 4cbdf0b503 fix(auth): 修复 CDC consumer 类型错误
使用 ?? 运算符正确处理可选字段:
- update 使用 undefined 保持字段不变
- create 使用 null 明确设置为空值

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 01:45:10 -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 489966fae9 feat(auth): 新 1.0 用户自动发布事件到 mining-admin-service
- auth-service CDC consumer 在同步新用户时自动发布 LegacyUserMigratedEvent
- 只有 op='c' (create) 的新用户才发布事件,snapshot 由 publish-all API 处理
- deploy-mining.sh full-reset 更新步骤编号为 10 步

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 01:25:01 -08:00
hailin 50854f04d5 fix(deploy): 添加 mining-admin-service-cdc-group 到 CDC 重置列表
确保 full-reset 时同时重置 mining-admin-service 的 consumer group,
使其能从头消费所有 outbox 事件。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 01:18:44 -08:00
hailin 0d06080760 fix(mining-admin): 兼容 Debezium outbox 消息格式
问题:Debezium 产生的 outbox 消息使用下划线命名(event_type,
aggregate_type),而代码期望驼峰格式(eventType, aggregateType)

解决方案:
- isServiceEvent() 同时检查两种命名格式
- 新增 normalizeServiceEvent() 转换 Debezium 格式到驼峰格式
- 解析 payload JSON 字符串

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 01:10:24 -08:00
hailin 273f2f1d96 fix(deploy): 在 migration 后再次重置 CDC offset
问题:migration 会启动容器执行迁移,导致 CDC consumer
自动启动并消费消息。在数据库重建后启动服务时,消息
已经被消费完毕。

解决方案:在 migration 后增加 Step 7,停止容器并
再次重置 CDC offset,确保最终启动时能重新消费。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 00:53:55 -08:00
hailin 350ce28c40 fix(deploy): 修复 sync-reset CDC offset 重置失败问题
- sync_reset() 添加 20 秒等待时间,确保 consumer group 变成 inactive
- 添加重试逻辑(最多 3 次,每次间隔 10 秒)
- 使用 grep NEW-OFFSET 检测 offset reset 是否成功

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 00:49:09 -08:00
hailin 24412794e6 fix(deploy-mining): 修正 full-reset 步骤顺序避免 CDC offset 重置失败
- 在 migration 之前重置 CDC offsets(因为 migration 会启动容器)
- 停止服务后等待 15 秒让 Kafka consumer 变成 inactive
- 添加重试机制,最多重试 3 次,每次间隔 10 秒
- 步骤从 6 步改为 7 步

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 00:33:19 -08:00
hailin ff27195be2 fix(cdc): 修复用户同步字段映射和多 consumer group 重置
contribution-service:
- 修复 UserSyncedHandler 使用错误字段名 (data.id -> data.user_id)
- 兼容 CDC snake_case 字段命名 (user_id, account_sequence, phone_number)
- 添加数据验证,跳过无效记录

deploy-mining.sh:
- 添加 auth-service-cdc-group 到 CDC_CONSUMER_GROUPS
- full-reset 现在重置所有 CDC consumer groups
- sync_reset 和 sync_status 支持多个 consumer groups

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 23:59:39 -08:00
hailin 5cab38c7f1 fix(deploy-mining): 修正 Docker 容器名称和默认凭据
- 修正 POSTGRES_CONTAINER 为 rwa-postgres (匹配 docker-compose.yml)
- 修正 KAFKA_CONTAINER 为 rwa-kafka
- 修正 POSTGRES_USER 为 rwa_user
- 修正 POSTGRES_PASSWORD 为 rwa_secure_password
- 修复 CDC offset 重置命令使用正确的容器名和命令格式

解决 full-reset 无法删除数据库和重置 CDC offset 的问题。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 23:41:49 -08:00
hailin 5c302bfca8 fix(deploy-mining): 支持 Docker 环境的数据库操作和迁移
- 添加 run_psql helper 函数自动检测 Docker 或本地 psql
- 修改 db_create/db_drop/db_status 使用 docker exec
- 修改 db_migrate 支持通过容器运行 prisma migration
- 修改 health_check/show_stats 支持 Docker 环境

解决在服务器 Docker 环境中 full-reset 失败的问题。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 23:38:06 -08:00
hailin 5d880f011e fix(debezium): 统一 mining-wallet-outbox-connector 数据库名称
将 database.dbname 从 mining_wallet_db 改为 rwa_mining_wallet,
与 docker-compose.2.0.yml 和 deploy-mining.sh 保持一致。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 23:31:28 -08:00
hailin 63d73af135 refactor(cdc): 统一使用 Debezium CDC 进行数据同步
1. contribution-service:
   - 添加 identity topic 订阅,全量同步 1.0 用户数据
   - 修改 fromBeginning 为 true,首次启动全量同步

2. mining-admin-service:
   - 将 Outbox 事件改为 Debezium CDC 监听 outbox_events 表
   - 修改 fromBeginning 为 true,首次启动全量同步

3. 新增 5 个 2.0 服务的 Debezium connector 配置:
   - auth-outbox-connector.json
   - contribution-outbox-connector.json
   - mining-outbox-connector.json
   - trading-outbox-connector.json
   - mining-wallet-outbox-connector.json

4. 更新 register-connectors.sh 脚本

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 23:19:34 -08:00
hailin cab36fccf1 fix(docker): 修复 contribution-service 和 mining-admin-service Dockerfile healthcheck 路径
将 healthcheck 路径从 /api/v1/health 改为 /api/v2/health,
与 main.ts 中的 API 前缀保持一致。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 22:56:26 -08:00
hailin 978dfcb2bf feat(docker): 添加 mining-wallet-service 到 docker-compose.2.0.yml
- 添加 mining-wallet-service 服务配置
  - 端口: 3025
  - 数据库: rwa_mining_wallet
  - Redis DB: 15
  - KAVA 区块链配置
- 更新所有服务的 healthcheck 路径为 /api/v2/health
  - mining-service
  - trading-service
  - mining-admin-service

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 22:53:57 -08:00
hailin 83a2800941 refactor(deploy): 移除 mining-admin-web 从 deploy-mining.sh
mining-admin-web 是前端项目,不应该在后端服务部署脚本中管理。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 22:52:26 -08:00
hailin 3c73d510b1 feat(deploy): 添加 mining-wallet-service 到 deploy-mining.sh
将 mining-wallet-service 加入 2.0 系统管理脚本:

- 添加到 MINING_SERVICES 数组
- 添加别名 wallet -> mining-wallet-service
- 添加数据库 rwa_mining_wallet
- 添加 SERVICE_DB 映射
- 添加端口 3025
- 更新帮助文档

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 22:51:19 -08:00
hailin f790d2bbe5 refactor(api): 升级 trading-service API 前缀至 v2
将 trading-service 的 API 版本从 v1 升级到 v2,统一 2.0 系统架构:

**trading-service:**
- main.ts: 全局前缀 api/v1 → api/v2
- Dockerfile: 健康检查路径 /api/v1/health → /api/v2/health
- transfer.service.ts: 更新调用 mining-service 的 API 路径
  - /api/v1/mining/accounts/.../transfer-out → /api/v2/...
  - /api/v1/mining/accounts/.../transfer-in → /api/v2/...

此变更使 trading-service 正式成为 2.0 系统的一部分,
与 auth-service、contribution-service、mining-service、
mining-admin-service、mining-wallet-service 保持一致。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 22:37:17 -08:00
hailin 6d619c0a02 refactor(api): 升级 mining-service 和 mining-wallet-service API 前缀至 v2
将以下服务的 API 版本从 v1 升级到 v2,统一 2.0 系统架构:

**mining-service:**
- main.ts: 全局前缀 api/v1 → api/v2
- Dockerfile: 健康检查路径 /api/v1/health → /api/v2/health

**mining-wallet-service:**
- main.ts: 全局前缀 api/v1 → api/v2
- Dockerfile: 健康检查路径 /api/v1/health → /api/v2/health

此变更使 mining-service 和 mining-wallet-service 正式成为 2.0 系统的一部分,
与 auth-service、contribution-service、mining-admin-service 保持一致。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 22:31:06 -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 6fedebf020 fix(trading-service): 更新 package-lock.json
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 21:35:33 -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 1a7c73e531 feat(mining-admin): 添加用户详情页缺失的 API 端点
- 添加 referral-tree API(返回空推荐关系数据)
- 添加 planting-ledger API(返回空认种数据)
- 添加 wallet-ledger API(返回空钱包流水数据)
- 修复前端 referral-tree 组件空数据处理

注:这些 API 目前返回占位数据,完整数据需要通过 CDC 从各服务同步

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 20:53:18 -08:00
hailin e0f529799f fix(mining-admin): 添加 syncAllUsers 和 syncAllContributionAccounts 方法
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 20:24:48 -08:00
hailin 582beb4f81 feat(cdc): 添加 legacy 用户批量同步功能
auth-service:
- 添加 AdminController 和 AdminSyncService
- POST /admin/legacy-users/publish-all: 为所有 legacy 用户发布事件
- GET /admin/users/sync: 获取所有用户数据供同步

mining-admin-service:
- 添加 user.legacy.migrated 事件处理器
- 添加 sync-users 和 sync-contribution-accounts API

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 20:17:46 -08:00
hailin 49b1571bba fix(cdc): 修复 auth-service 与 mining-admin-service 的 CDC 事件同步
- auth-service: 将 outbox topic 从 auth.events 改为 mining-admin.auth.users
- mining-admin-service: 添加 user.registered 和 user.kyc_verified 事件处理器
- 确保 auth-service 发布的事件能被 mining-admin-service 正确接收和处理

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 19:51:01 -08:00
hailin e83b3d420c chore(mining-admin-service): 统一API版本为v2
- 将globalPrefix从api/v1改为api/v2
- 更新Swagger文档版本为2.0

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 19:25:49 -08:00
hailin 5dab829995 fix(deploy-mining): 修复rebuild命令不更新容器的问题
rebuild命令之前只调用build,现在会在构建后停止旧容器并启动新容器

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 18:47:25 -08:00
hailin 7a68668aa9 feat(auth-service): 增强登录错误提示和指数退避锁定机制
- 区分用户不存在和密码错误的提示信息
- 登录失败最多允许6次尝试
- 每次密码错误显示剩余尝试次数
- 超过次数后实现指数退避锁定(1,2,4,8...分钟,最长24小时)
- 锁定时显示剩余等待时间
- 优化mining-app底部导航栏图标间距

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 18:33:23 -08:00
hailin 608e22a8e7 fix(contribution-service): 修复JWT验证与auth-service不兼容
- 移除 type 字段检查 (auth-service 不生成此字段)
- 修复 JwtPayload 接口与 auth-service 生成的 token 结构一致
- 从 payload.sub 获取 accountSequence

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 18:18:21 -08:00
hailin 4d5c9e7c49 fix(docker): 为contribution-service添加JWT_SECRET配置
contribution-service需要JWT_SECRET来验证auth-service签发的token。
与auth-service共享相同的密钥配置。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 18:14:37 -08:00
hailin c35d90e94f fix(kong): 修复auth-service路由配置
- 将service URL从 /api/v2 改为根路径
- 设置 strip_path: false 直接透传请求路径
- 保持前后端路径一致: /api/v2/auth/...

问题原因: strip_path: true 会移除 /api/v2/auth,
导致后端收到 /api/v2/login 而不是 /api/v2/auth/login

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:52:53 -08:00
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