- 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>
Allows faster detection of urgent updates while preventing excessive
API calls with random cooldown period.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change download path from getApplicationDocumentsDirectory to
getExternalStorageDirectory for proper FileProvider support
- Add finishAffinity() after starting APK install intent
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
APK downloaded to getApplicationDocumentsDirectory() which maps to
files/app_flutter/ on Android. FileProvider needs this path configured
to grant URI permission for APK installation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move checkForAppUpdate from SplashPage to HomeShellPage
- Use WidgetsBindingObserver to check on app resume
- Add 24-hour interval check to avoid frequent API calls
- Fix: context.go() invalidates context, so check was never executed
🤖 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>
- markAsConfirmed now uses aggregateId + eventType for precise matching
- Prevents accidentally confirming multiple events for the same order
- EventAckController passes eventType to markAsConfirmed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
- Fix brokers type narrowing issue in deposit-ack-consumer.service.ts
- Add Prisma.InputJsonValue type cast for payload in outbox-event.repository.impl.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
The /api/v1/leaderboard route was duplicated in both referral-service
and leaderboard-service. Since leaderboard-service is the dedicated
ranking service with more features (daily/weekly/monthly rankings,
virtual accounts, snapshots), all leaderboard requests should be
routed to leaderboard-service.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add ClientsModule with KAFKA_SERVICE registration
- Add EventAckPublisher to KafkaModule providers/exports
- Move EventConsumerController to AppModule (has access to repositories)
Resolves: Nest can't resolve dependencies of EventConsumerController
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add routes for APIs that were implemented but missing from Kong:
- /api/v1/backup-share (backup-service)
- /api/v1/virtual-accounts (leaderboard-service)
- /api/v1/export (reporting-service)
- /api/v1/analytics (presence-service)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement Outbox Pattern with consumer ACK to ensure 100% reliable event
delivery between blockchain-service and wallet-service:
blockchain-service:
- Add OutboxEvent model to Prisma schema with status tracking
- Create outbox repository interface and implementation
- Modify deposit-detection.service to write events to outbox
- Add outbox-publisher.service with cron jobs for publishing/retry
- Add deposit-ack-consumer.service to receive ACK from wallet-service
- Add publishRaw method to event-publisher.service
wallet-service:
- Modify deposit-confirmed.handler to send ACK after successful processing
- Add wallet.deposit.credited topic mapping for ACK events
Event flow:
1. Deposit detected → written to outbox (status: PENDING)
2. Outbox publisher sends to Kafka → status: SENT
3. wallet-service processes and sends ACK → status: ACKED
4. Events without ACK are retried with exponential backoff
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
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>
- Add initial migration for wallet-service (wallet_accounts, ledger_entries, deposit/settlement/withdrawal orders)
- Add initial migration for planting-service (planting_orders, fund_allocations, positions, batches, events)
- Both services now have migrations that will be automatically applied on container startup via `prisma migrate deploy`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add /api/v1/wallet route to Kong gateway to support:
- GET /wallet/my-wallet
- POST /wallet/claim-rewards
- POST /wallet/settle
- POST /wallet/withdraw
- GET /wallet/withdrawals
- GET /wallet/ledger/my-ledger
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add WalletService to fetch wallet/rewards data from backend
- Replace hardcoded earnings data with real API calls
- Add loading/error states for earnings section
- Implement claim rewards functionality with API
- Add comprehensive debug logging for troubleshooting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1. Avatar display:
- Detect if _avatarSvg is URL or SVG string
- Use Image.network for URLs, SvgPicture.string for SVG
2. API endpoints:
- Remove /api/v1 prefix from endpoints (already in baseUrl)
- Fixes duplicate /api/v1/api/v1 in requests
3. Guide page:
- Restore BoxFit.cover for fullscreen images
- Fix page indicator positioning with SafeArea
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change BoxFit.cover to BoxFit.fitWidth for guide page images
- Add screen info logging (resolution, pixel ratio, aspect ratio)
- Add detailed avatar loading logs in frontend and backend
- Log avatarUrl from DB and API response during recovery
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added debug logs in:
- ProfilePage._loadUserData() - local storage data
- ProfilePage._loadMeData() - API response and sync conditions
- ProfilePage._buildAvatarContent() - avatar rendering decision
- UserApplicationService.getMe() - backend avatarUrl value
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When recovering an account via mnemonic, the avatar SVG might not be
saved to local storage. Now the profile page checks if avatarUrl is
returned from the /me API and updates both the display and local storage.
- Add updateLocalAvatarSvg() method to AccountService
- Update _loadMeData() to sync avatar from API response
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When recovering account via mnemonic or phone, check if avatarUrl is null
and regenerate a new random avatar SVG if needed. This fixes the bug where
users see no avatar after recovering their account.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove condition that only checked updates when wallet was created
- Add debug logging to version checker and self hosted updater
- Updates should now prompt on every app launch
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Downloads route was getting /api/v1 prefix, making it inaccessible at /downloads
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Set BASE_URL to public API gateway address so mobile app can download
APK files from correct URL instead of localhost.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Mobile app was calling /api/app/version/check but this route was not
configured in Kong gateway. Added admin-mobile-version route to forward
these requests to admin-service.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Changelog: allow empty value, return default "No changelog provided"
- MinOsVersion: allow empty value and single number format (e.g., "24" -> "24.0")
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- admin-service: provide default empty string for optional changelog
- profile page: fix map literal syntax for referrals list
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- VersionName value object now accepts x.y.z.w format
- changelog field is now optional in upload version DTO
- profile page: ensure expired section has full width
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allow version names like 1.0.0.4 in addition to the standard x.y.z format.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The balance display was incorrect because decimals were hardcoded to 18,
but USDT uses 6 decimals. Now reads decimals() from the ERC20 contract.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
sessionTimeout remains at 5 minutes (needed for long MPC operations),
but rebalanceTimeout only affects joining consumer group, not processing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>