Commit Graph

37 Commits

Author SHA1 Message Date
hailin 9a823e8871 fix(referral): convert BigInt to string for JSON serialization
BigInt cannot be serialized by JSON.stringify, convert to string
before returning from the API endpoint.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 22:29:17 -08:00
hailin 6f46a8633f feat(reward): add internal APIs for reward distribution
- Add /referral/chain/{userId} API in referral-service for getting referral chain with hasPlanted status
- Add internal authorization APIs in authorization-service:
  - GET /authorization/nearest-community: find nearest community in referral chain
  - GET /authorization/nearest-province: find nearest province company in referral chain
  - GET /authorization/nearest-city: find nearest city company in referral chain
- Add repository methods for finding active authorizations by accountSequence
- Update reward-service client to use accountSequence parameter

These APIs enable reward-service to correctly distribute:
- 分享权益 (share benefit): to referrer with hasPlanted=true
- 社区权益 (community benefit): to nearest community leader
- 省团队权益 (province team benefit): to nearest province company
- 市团队权益 (city team benefit): to nearest city company

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 21:49:13 -08:00
hailin 9cf8b5305b feat(authorization): add community hierarchy API
- Add internal referral-chain API in referral-service for getting ancestor path and team members
- Extend ReferralServiceClient to call referral-chain API
- Add findActiveCommunityByAccountSequences repository method
- Add getCommunityHierarchy application service method
- Add GET /authorizations/my/community-hierarchy endpoint
- Update frontend with CommunityHierarchy model and getMyCommunityHierarchy method

API returns:
- myCommunity: user's own community authorization (if any)
- parentCommunity: nearest parent community (defaults to 总部社区 if none)
- childCommunities: nearest child communities in user's team

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 18:18:49 -08:00
hailin ccef23f5b0 feat(authorization): integrate with referral-service for team statistics
- Add InternalTeamStatisticsController in referral-service for service-to-service API
- Create ReferralServiceClient in authorization-service to fetch real team statistics
- Replace MockTeamStatisticsRepository with real HTTP client implementation
- Configure docker-compose with REFERRAL_SERVICE_URL for authorization-service

This enables authorization-service to get real team planting counts from
referral-service for authorization assessment and activation logic.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 16:30:35 -08:00
hailin 300fe211c8 fix: add accountSequence to all services and fix compilation errors
- reward-service: add accountSequence to aggregates, services, tests
- authorization-service: fix UserId/AdminUserId to accept accountSequence, add findByAccountSequence to repositories
- referral-service: fix test files for accountSequence changes
- Add migration files for reward-service and authorization-service

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 14:14:06 -08:00
hailin 034fb53674 refactor: use accountSequence as unified user identifier across all services
- planting-service: extract accountSequence from JWT, pass to referral-service
- referral-service: query by accountSequence instead of userId
- reward-service: add accountSequence field to schema and all layers
- wallet-service: prioritize accountSequence lookup over userId
- authorization-service: change userId from String to BigInt, add accountSequence

This change ensures consistent cross-service user identification using
accountSequence (8-digit unique business ID) instead of internal database IDs.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 13:55:03 -08:00
hailin 62a21b73a5 fix(referral): use accountSequence instead of userId for user registration events
identity-service sends userId=0 in events (temp value before DB save),
use accountSequence as the unique identifier instead
2025-12-10 13:29:36 -08:00
hailin 70d1a8bfb8 fix(referral): add idempotency check for Kafka event processing
- Add processed_events table to track handled events
- Check eventId before processing planting.created events
- Skip duplicate events and still send ACK to stop retries

This prevents data accumulation when Kafka events are redelivered
due to ACK failures or consumer timeouts.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 09:38:13 -08:00
hailin 68182fd0a3 feat(referral): add personal/team planting counts to direct referral list
- Backend: batch query TeamStatistics to get each direct referral's
  personalPlantingCount and teamPlantingCount
- Updated DTO and query interfaces with new fields
- Frontend: parse and display "个人/团队" counts in profile page

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 05:57:46 -08:00
hailin 13f670e9dd fix(referral): fix direct referral list display and count issues
1. Return accountSequence instead of userId for direct referral list display
2. Create missing team statistics record when referrer doesn't have one

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 04:58:16 -08:00
hailin 30aa11c6c6 fix(referral): fix EventAckMessage type casting
Cast ackMessage to Record<string, unknown> for KafkaService compatibility.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 22:31:12 -08:00
hailin 807dc8705d fix(referral): add EventAckPublisher to InfrastructureModule
- Refactor EventAckPublisher to use KafkaService instead of ClientKafka
- Add kafka/index.ts export file
- Register EventAckPublisher in InfrastructureModule providers and exports

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 22:29:54 -08:00
hailin dfa21c0280 feat(mobile): integrate PlantingService with real API
- Add PlantingService for planting order management
  - createOrder: Create new planting order
  - selectProvinceCity: Select province and city
  - confirmProvinceCity: Confirm province/city selection
  - payOrder: Pay for order
  - getOrder/getMyOrders: Query orders
  - cancelOrder: Cancel unpaid orders
- Register PlantingService in DI container
- Update planting_quantity_page to create order before navigation
- Update planting_location_page to call real API endpoints
- Fix referral-service event-ack.publisher to use KafkaService

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 22:28:36 -08:00
hailin 8de7a668f0 fix(referral): remove LeaderboardCacheService dependency
Leaderboard functionality has been moved to leaderboard-service.
Remove the dependency and set leaderboardRank to null.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 22:13:57 -08:00
hailin 2bf5ca933e refactor(referral): remove legacy leaderboard code
Remove duplicate leaderboard functionality from referral-service.
All leaderboard features should now go through leaderboard-service.

Removed files:
- api/controllers/leaderboard.controller.ts
- api/dto/leaderboard.dto.ts
- application/queries/get-leaderboard.query.ts
- infrastructure/cache/leaderboard-cache.service.ts
- Related test files

Modified:
- TeamStatisticsService: removed getLeaderboard() and getUserRank()
- Module registrations updated

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 22:05:48 -08:00
hailin f04f8ed6ce chore(prisma): add missing migration_lock.toml files
Added migration_lock.toml for planting-service, reward-service,
referral-service, and authorization-service to ensure Prisma
can properly track migration provider.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 21:39:20 -08:00
hailin 014ad9d19f feat(planting): implement Outbox Pattern with consumer acknowledgment (B方案)
Implement reliable event delivery using Outbox Pattern with consumer confirmation:

## planting-service (Producer)
- Add OutboxEvent table with status: PENDING → SENT → CONFIRMED
- Add OutboxRepository with transaction support and timeout handling
- Add OutboxPublisherService with polling, timeout check, and retry
- Add EventAckController to receive consumer confirmations
- Update UnitOfWork to save outbox events atomically with business data
- Update PlantingApplicationService to use outbox pattern
- Update PoolInjectionService to use outbox pattern

## Consumer Services
- Add EventAckPublisher to reward-service, referral-service, authorization-service
- Update event handlers to send acknowledgment after successful processing

## Event Flow
1. Business data + outbox events saved in same transaction
2. OutboxPublisher polls and sends to Kafka, marks as SENT
3. Consumer processes event and sends ack to planting.events.ack
4. EventAckController receives ack and marks as CONFIRMED
5. Timeout check resets SENT→PENDING for retry (max 5 times)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 21:32:16 -08:00
hailin 429f8d5991 Revert "fix(mpc-service): don't block startup on Kafka consumer rebalance"
This reverts commit c924d3aad2.
2025-12-09 03:26:05 -08:00
hailin c924d3aad2 fix(mpc-service): don't block startup on Kafka consumer rebalance 2025-12-09 03:25:07 -08:00
hailin 781721a659 feat(withdrawal): implement withdrawal order and fund allocation system
- Add SystemAccount domain in authorization-service for managing regional/company accounts
- Implement fund allocation service in planting-service with multi-tier distribution
- Add WithdrawalOrder aggregate in wallet-service with full lifecycle management
- Create internal wallet controller for cross-service fund allocation
- Add Kafka event publishing for withdrawal requests
- Implement unit-of-work pattern for transactional consistency
- Update Prisma schemas with withdrawal order and system account tables

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 02:35:27 -08:00
hailin 5d671bf5ec feat(referral): integrate referral system with identity-service and mobile-app
## Backend Changes

### referral-service
- Add accountSequence field to ReferralRelationship aggregate for cross-service user identification
- Add findByAccountSequence() method to repository interface and implementation
- Update CreateReferralRelationshipCommand to accept accountSequence and inviterAccountSequence
- Modify ReferralService to support looking up inviter by accountSequence
- Update event handler to listen to identity.UserAccountAutoCreated and identity.UserAccountCreated topics
- Add initial database migration with all tables including accountSequence field
- Update DTO and controller to support new parameters

### identity-service
- Add inviterSequence field to MeResult interface
- Update getMe() method to return inviterSequence from user account
- Update MeResponseDto to include inviterSequence field

## Frontend Changes (mobile-app)

### API & Storage
- Add /me endpoint constant in api_endpoints.dart
- Add inviterSequence key in storage_keys.dart
- Add MeResponse and WalletAddressInfo classes in account_service.dart
- Add getMe() method to fetch complete user info including inviter
- Add getInviterSequence() method to retrieve from local storage

### Profile Page
- Update profile_page.dart to load referrer info from API
- Add _loadMeData() method to call getMe() API
- Display inviterSequence (referrer serial number) dynamically

## Flow Summary
1. User creates account with optional inviterReferralCode
2. identity-service validates and saves inviterSequence
3. identity-service publishes UserAccountAutoCreated/UserAccountCreated event
4. referral-service listens and creates referral relationship using inviterAccountSequence
5. Mobile app calls GET /me to display inviter info in profile page

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 22:37:06 -08:00
hailin 0c00382a98 fix: convert deploy.sh CRLF to LF and add executable permission
- Convert Windows CRLF line endings to Unix LF for all deploy.sh files
- Add executable permission to all deploy.sh scripts

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 07:01:13 -08:00
hailin dba9d16074 . 2025-12-07 00:40:19 -08:00
hailin 747e4ae8ef refactor(mpc-system): migrate to party-driven architecture with PartyID-based routing
- Remove Address field from PartyEndpoint (parties connect to router themselves)
- Update K8s Discovery to only manage PartyID and Role labels
- Add Party registration and SessionEvent protobuf definitions
- Implement PartyRegistry and SessionEventBroadcaster domain logic
- Add RegisterParty and SubscribeSessionEvents gRPC handlers
- Prepare infrastructure for party-driven MPC coordination

This is the first phase of migrating from coordinator-driven to party-driven
architecture following international MPC system design patterns.
2025-12-05 08:11:28 -08:00
Developer 9898665506 feat(all-services): 添加数据库自动迁移到所有服务启动流程
在每个服务的 Dockerfile 中添加启动脚本:
- 服务启动前先执行 prisma migrate deploy
- 如果迁移失败则回退到 prisma db push
- 确保数据库表在服务启动时自动创建

修改的服务:
- identity-service
- wallet-service
- backup-service
- planting-service
- referral-service
- reward-service
- leaderboard-service
- reporting-service
- authorization-service
- admin-service
- presence-service

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 01:50:01 -08:00
Developer 24c7be6a8d fix(referral-service): 修复端口配置使用 APP_PORT 2025-12-02 10:47:46 -08:00
Developer f1b6370aae fix(referral-service): 统一使用 curl 进行健康检查 2025-12-02 10:39:36 -08:00
Developer 1150d7e514 fix(wallet,referral): correct build output path to dist/main.js
These services build to dist/main.js (no src subdirectory).
Added build verification steps.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 05:38:36 -08:00
Developer 9b4a1d119c fix(services): switch from Alpine to Debian slim for Prisma OpenSSL
Alpine 3.22 removed openssl1.1-compat package which Prisma needs.
Switched production stage from node:20-alpine to node:20-slim (Debian)
which has proper OpenSSL support.

Changes:
- Use node:20-slim for production stage (keep Alpine for build)
- Install openssl and wget via apt-get
- Update user creation from Alpine (addgroup/adduser) to Debian (groupadd/useradd)

Validated identity-service build and startup in WSL2:
- Build passes successfully
- NestJS starts and loads all routes
- Prisma client connects without OpenSSL errors

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 04:12:27 -08:00
Developer c2b44eef29 fix(services): add OpenSSL 1.1 compatibility for Prisma in Alpine
Prisma engine requires libssl.so.1.1 which is not available in Alpine
Linux by default (Alpine uses OpenSSL 3.x). Added openssl1.1-compat
package to all service Dockerfiles.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 04:03:15 -08:00
Developer 7bb4259290 fix(services): correct NestJS build output path in all Dockerfiles
NestJS with sourceRoot: "src" outputs to dist/src/main.js not dist/main.js.
Fixed CMD paths in all service Dockerfiles:
- identity-service: dist/src/main.js (verified in WSL2)
- wallet-service: dist/src/main.js
- backup-service: dist/src/main.js
- planting-service: dist/src/main.js
- referral-service: dist/src/main.js
- reward-service: dist/src/main.js
- mpc-service: dist/src/main.js
- leaderboard-service: dist/src/main.js
- reporting-service: dist/src/main.js
- authorization-service: dist/src/main.js

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 03:56:02 -08:00
Developer 0a0b7eb886 feat(services): add individual deploy scripts for each service
Add deploy.sh script to each service directory for independent
deployment and management:
- identity-service, wallet-service, backup-service
- planting-service, referral-service, reward-service
- mpc-service, leaderboard-service, reporting-service
- authorization-service

Each script supports:
- build / build-no-cache
- start / stop / restart
- logs / logs-tail
- status / health
- migrate / shell

Also updated main deploy.sh with build-no-cache command.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 03:36:50 -08:00
Developer 77db1009dd fix(services): add DATABASE_URL for Prisma generate in Dockerfiles
Add dummy DATABASE_URL environment variable prefix to all npx prisma
generate commands in Dockerfiles. Prisma requires DATABASE_URL at
build time to generate the client, but the actual value is only used
at runtime.

Services updated:
- authorization-service (postgresql)
- backup-service (postgresql)
- leaderboard-service (postgresql)
- mpc-service (mysql)
- planting-service (postgresql)
- referral-service (postgresql)
- reporting-service (postgresql)
- reward-service (postgresql)
- wallet-service (postgresql + npm install fix)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 02:54:31 -08:00
Developer f99cac21cf feat(services): add unified Docker deployment system
- Add docker-compose.yml for all 11 backend services
- Add deploy.sh automation script with install/build/up/down commands
- Add init-databases.sh for PostgreSQL multi-database initialization
- Add .env.example template with secure key placeholders
- Fix empty Dockerfiles for admin/referral/reporting/wallet services

Services included:
- identity-service (:3000)
- wallet-service (:3001)
- backup-service (:3002)
- planting-service (:3003)
- referral-service (:3004)
- reward-service (:3005)
- mpc-service (:3006)
- leaderboard-service (:3007)
- reporting-service (:3008)
- authorization-service (:3009)
- admin-service (:3010)

Infrastructure: PostgreSQL, Redis, Kafka/Zookeeper

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 02:12:49 -08:00
Developer 7ae98c7f5b feat(referral-service): Implement complete referral service with DDD architecture
Implement the referral service microservice with comprehensive features:

## Domain Layer
- ReferralRelationship aggregate: manages user referral relationships
- TeamStatistics aggregate: tracks team statistics and leaderboard scores
- Value Objects: UserId, ReferralCode, ReferralChain, LeaderboardScore, ProvinceCityDistribution
- Domain Services: ReferralChainService, LeaderboardCalculationService
- Domain Events: ReferralRelationshipCreated, TeamStatisticsUpdated

## Application Layer
- ReferralService: create relationships, get user info, validate codes
- TeamStatisticsService: update statistics, get leaderboard, province/city distribution
- Commands: CreateReferralRelationship, UpdateTeamStatistics
- Queries: GetUserReferralInfo, GetDirectReferrals, GetLeaderboard, GetProvinceCityDistribution
- Event Handlers: UserRegisteredHandler, PlantingCreatedHandler

## Infrastructure Layer
- Prisma repositories with PostgreSQL
- Redis caching for leaderboard
- Kafka messaging for domain events
- JWT authentication guard

## API Layer
- REST endpoints for referral management
- Leaderboard endpoints with pagination
- Team statistics endpoints
- Health check endpoints

## Testing (127 unit + 35 integration + 16 E2E tests)
- Domain layer unit tests (100% coverage)
- Integration tests with mocks
- E2E tests with supertest
- Docker test environment with PostgreSQL, Redis, Redpanda

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 00:18:20 -08:00
Developer b350d6b023 . 2025-11-30 19:04:47 -08:00
hailin b9a3fb9a83 first commit 2025-11-23 21:21:44 -08:00