将新用户默认昵称从「用户D2512140001」改为「用户1」,
使用 accountSequence.dailySequence 提取当日序号并去除前导零。
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
省团队(AUTH_PROVINCE_COMPANY)和市团队(AUTH_CITY_COMPANY)收益分配不再要求
认种者选择的省市与被授权用户的省市一致,只要在推荐链上有授权即可获得收益。
省区域(PROVINCE_COMPANY)和市区域(CITY_COMPANY)收益仍保持省市匹配要求。
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Province area (PROVINCE_COMPANY): 50,000 trees initial target
- City area (CITY_COMPANY): 10,000 trees initial target
- Apply consistent assessment logic: pre-target rewards go to system account, post-target rewards go to company
- Auto-activate benefit when target is reached
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add POST /admin/authorizations/auth-province-company for 省团队授权
- Add POST /admin/authorizations/auth-city-company for 市团队授权
- Add team uniqueness validation for all province/city authorization types
- Add domain events: AuthProvinceCompanyGrantedEvent, AuthCityCompanyGrantedEvent
- Add factory methods: createAuthProvinceCompanyByAdmin, createAuthCityCompanyByAdmin
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When tree count + current team count equals initial target exactly,
the benefit was not being activated. Now properly handles three cases:
- afterPlantingCount < target: still in assessment, no activation
- afterPlantingCount === target: reached target, activate benefit
- afterPlantingCount > target: exceeded target, split rewards & activate
Applied to community, province team, and city team reward distribution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1. Assessment calculation now uses subordinate team count (excluding self planting)
- Added selfPlantingCount to referral-service API response
- Added subordinateTeamPlantingCount getter to TeamStatistics interface
- Updated all assessment checks to use subordinateTeamPlantingCount
2. Auto-activate benefit when assessment target is reached
- Added tryActivateBenefit helper method
- Community, province team, and city team reward distribution methods
now automatically activate benefit when target is reached
3. Fixed event consumer to support AUTHORIZED status (admin grants)
- Previously only checked PENDING status for activation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When calculating reward distribution for community/province/city benefits,
the totalTeamPlantingCount was being read after referral-service had already
updated it with the current planting. This caused incorrect distribution
where benefits were given to the community holder before they completed
their assessment target.
Fix: Subtract treeCount from rawTeamCount to restore the "before planting"
team count, ensuring correct assessment calculation.
Affected methods:
- getCommunityRewardDistribution
- getProvinceTeamRewardDistribution
- getCityTeamRewardDistribution
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed findActiveCommunityByAccountSequences to not require benefitActive=true.
This allows communities that haven't passed assessment to still be shown as
parent communities in the UI, while reward distribution logic remains unchanged.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Admin grant APIs now default to requiring assessment (benefitActive=false).
Added optional skipAssessment parameter to bypass assessment when needed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive logging to RewardCalculationService for easier debugging:
- Log start/end of calculateRewards with order info
- Log each benefit calculation with input parameters
- Log distribution results from authorization-service calls
- Log share right decisions (settleable vs pending)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add proper assessment/考核 logic for all 5 benefit types:
- Community (80 USDT): 10-tree initial assessment, splits rewards between
current community and parent/headquarters based on progress
- Province Team (20 USDT): 500-tree initial assessment for AUTH_PROVINCE_COMPANY
- Province Area (15 USDT + 1%): 50000-tree target for PROVINCE_COMPANY,
routes to system account until target reached
- City Team (40 USDT): 100-tree initial assessment for AUTH_CITY_COMPANY
- City Area (35 USDT + 2%): 10000-tree target for CITY_COMPANY,
routes to system account until target reached
Changes:
- authorization-service: Add 4 new distribution API endpoints and application
service methods for province/city team/area reward distribution
- authorization-service: Add repository methods for querying authorizations
including benefitActive=false records
- reward-service: Update client to call new distribution APIs
- reward-service: Modify calculation methods to return multiple reward entries
based on assessment distribution plan
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The authorization-service uses TransformInterceptor which wraps all API
responses in a standard format: { success, data, timestamp }
Before this fix, the AuthorizationServiceClient was reading:
data.accountSequence (undefined - wrong level)
After this fix, it correctly reads:
result.data.accountSequence
This ensures that COMMUNITY_RIGHT is allocated to the correct authorized
community user (e.g., accountSequence=6) instead of falling back to
HEADQUARTERS (accountSequence=1).
Changes in reward-service:
- Added AuthorizationServiceResponse<T> interface
- Added NearestAuthorizationResult interface
- Updated findNearestAuthorizedProvince() to parse wrapped response
- Updated findNearestAuthorizedCity() to parse wrapped response
- Updated findNearestCommunity() to parse wrapped response
- Added debug logging for findNearestCommunity
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The authorization-service uses TransformInterceptor which wraps all API
responses in a standard format: { success, data, timestamp }
Before this fix, the AuthorizationServiceClient was reading:
response.data.accountSequence (undefined)
After this fix, it correctly reads:
response.data.data.accountSequence
This ensures that nearestCommunity, nearestProvinceAuth, and nearestCityAuth
are properly extracted from the wrapped response, allowing community benefits
to be correctly allocated to authorized users instead of falling back to
SYSTEM_HEADQUARTERS_COMMUNITY.
Changes:
- Added AuthorizationServiceResponse<T> interface to model wrapped response
- Updated findNearestCommunity() to use wrapped response type
- Updated findNearestProvince() to use wrapped response type
- Updated findNearestCity() to use wrapped response type
- Updated catchError handlers to return properly structured fallback data
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
两个服务互相调用,形成循环依赖。移除 depends_on 约束,使用 fallback 机制处理服务暂时不可用的情况。
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The OutboxPublisherService sends payload fields directly at the message
root level, not nested under a 'payload' property. Update the consumer
to read fields directly from message instead of message.payload.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add publishSummaryUpdatesToOutbox method to write reward.summary.updated
events to outbox table for synchronization to wallet-service.
Events are published after:
- distributeRewards: when rewards are distributed to users
- claimPendingRewardsForUser: when pending rewards are claimed
- settleRewards: when rewards are settled
- expireOverdueRewards: when rewards expire
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Both referral-service and authorization-service use global prefix /api/v1,
so the client calls need to include this prefix.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
Expired referral rewards are transferred to headquarters community (seq=1),
not operation account. Remove the unused method to avoid confusion.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>
- 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>
Add new endpoint POST /api/v1/admin/authorizations/community
that allows administrators to directly authorize users as community
managers without requiring the user to self-apply first.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
reward-service was trying to connect to localhost instead of Docker
network service names, causing connection refused errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>
Add BACKUP_SERVICE_URL, BACKUP_SERVICE_ENABLED, and SERVICE_JWT_SECRET
to mpc-service configuration to enable backup share storage.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- mpc-service: add accountSequence param to StoreBackupShareParams
- mpc-service: pass accountSequence when calling backup-service
- backup-service: add logging for store request success/failure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>
- 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>
Previously used amount (raw) with hardcoded 18 decimals, which caused
incorrect formatting for USDT (6 decimals). Now uses amountFormatted
which is already correctly formatted during deposit detection.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The updateConfirmations logic only checked for DETECTED status
when confirming, so deposits that transitioned to CONFIRMING
would never be confirmed even with enough confirmations.
Changed condition to accept both DETECTED and CONFIRMING status.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously decimals were hardcoded to 18, causing incorrect amount parsing
for USDT which uses 6 decimals. Now reads decimals() from ERC20 contract
when processing deposits.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes BigInt conversion error when consuming planting.order.paid events.
The orderId from planting-service is a string format like PLT1765391584505Q0Q6QD,
not a numeric value.
Changes:
- reward-source.vo.ts: sourceOrderId (bigint) → sourceOrderNo (string)
- reward-calculation.service.ts: updated all method signatures
- reward-application.service.ts: updated distributeRewards params
- event-consumer.controller.ts: removed BigInt() conversion
- prisma schema: changed column type to VarChar(50)
- mapper/repository: updated field names accordingly
- Removed incompatible prisma.config.ts (Prisma 7.x format)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allow same device to create multiple accounts for testing purposes.
Original validation code is commented out and can be restored later.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
EventConsumerController was not registered in KafkaModule, causing
@MessagePattern('planting.order.paid') to never be subscribed.
This resulted in reward-service having empty memberAssignment.
Also added forwardRef to resolve circular dependency between
ApplicationModule and InfrastructureModule.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
authorization-service uses @EventPattern('planting-events') to consume
planting events but was missing connectMicroservice() configuration.
Without this, the service could not receive planting events, causing:
- Province team benefits (20 USDT) not distributed
- City team benefits (40 USDT) not distributed
- Community benefits (80 USDT) not distributed
- Monthly assessment data not updated
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The @MessagePattern decorator requires connectMicroservice() to work.
Without this configuration, services could not consume Kafka messages
via @MessagePattern, causing events to be lost.
Fixed services:
- planting-service: ACK consumption
- identity-service: event consumption
- reward-service: event consumption
blockchain-service already had this configured.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>
Added comprehensive logging to track:
- Request parameters (userId, amount, orderId)
- Wallet balance information
- Balance check results
- Freeze operation status
This helps debug the 400 error when planting-service calls wallet-service.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend:
- Add initialTargetTreeCount, currentTreeCount, monthlyTargetTreeCount
fields to AuthorizationDTO and AuthorizationResponse
- Query TeamStatistics to populate current tree count in getUserAuthorizations
Frontend:
- Update AuthorizationResponse to parse new progress fields
- Replace hardcoded community assessment values with real API data
- Show authorization status: red (unauthorized), orange (pending), green (active)
- Display progress bar and target requirements based on benefit status
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## wallet-service
- Add freeze/confirm/unfreeze API endpoints for planting deduction
- Add deductFrozen method to wallet-account aggregate
- Add PLANT_FREEZE and PLANT_UNFREEZE ledger entry types
- Add idempotency check in deductForPlanting
- Fix test files to include accountSequence parameter
## planting-service
- Add PaymentCompensation model and migration
- Add payment-compensation.repository.ts
- Add payment-compensation.service.ts (background job for retry)
- Add HTTP retry mechanism with exponential backoff
- Refactor payOrder to use freeze → transaction → confirm flow
- Create compensation record on unfreeze failure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>
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>
Add internal APIs to diagnose and repair historical deposit issues:
- GET /internal/deposit-repair/diagnose - Query unnotified deposits
- POST /internal/deposit-repair/repair/:depositId - Repair single deposit
- POST /internal/deposit-repair/repair-all - Batch repair all pending deposits
- POST /internal/deposit-repair/reset-failed-outbox - Reset failed outbox events
The repair service creates new outbox events for CONFIRMED deposits
that were never notified to wallet-service.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
- 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>
- 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>