- 后端新增 GET /referral/user/:accountSequence/direct-referrals API
- 前端新增伞下树组件,支持懒加载、缓存、展开/收起
- 使用 CustomPaint 绘制父子节点连接线
- 超出屏幕宽度时显示省略号,点击弹出底部列表
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, revoked authorizations were still shown in the profile page
because UserAuthorizationSummary.fromList() did not filter by status.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add authProvinceCompany and authCityCompany to RoleType enum
- Update UserAuthorizationSummary to support all role types
- Update profile page to display all authorization types
🤖 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>
The API returns {"success": true, "data": [...]} format but the code
was checking if response.data is List directly. Now properly extracts
the data field before parsing.
🤖 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>
API requires provinceCode, provinceName, cityCode, cityName (all strings).
Previous fix only sent 2 fields, now sending all 4 required fields.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
API expects provinceName and cityName (strings) but frontend was
sending provinceCode and cityCode (numbers), causing 400 error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The wallet API returns wrapped format { success, data, timestamp }
but the parser was reading from the root object directly.
Now correctly unpacks the inner 'data' field before parsing.
🤖 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>
- 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 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>
- 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>
- 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>
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>
- Add Kong routes for identity-service /me, referral-service, and authorization-service
- Create AuthorizationService in Flutter for fetching user authorizations
- Extend ReferralService with getMyReferralInfo() and getDirectReferrals() methods
- Update profile_page.dart to display real team stats from APIs
- Fix authorization-service JWT strategy to accept identity-service token format
- Add decimal.js dependency to authorization-service
- Add prisma migration file for authorization-service
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
## 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>
- Add DST to NetworkType enum
- Add dstAddress field to DepositAddressResponse
- Update deposit_service to fetch and cache DST address
- Add DST network button in deposit page UI
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add local avatar caching in AccountService:
- getLocalAvatarPath(): get cached avatar file path
- _saveAvatarToLocal(): save avatar to local after upload
- downloadAndCacheAvatar(): download and cache remote avatar
- Update profile_page and mining_page to use local avatar:
- Priority: local file > network URL > SVG > default icon
- Background download and cache if remote URL exists but no local cache
- Clean up local avatar file on logout
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Mining page: use accountService to load avatar (consistent with profile page)
- Account recovery: fetch and save wallet addresses after successful recovery
- Account recovery: set isWalletReady=true to skip backup mnemonic page
- Deposit service: read wallet addresses from local storage or fetch from /user/wallet API
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Parse avatarUrl from nested data object in API response
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add image picker for camera and gallery selection
- Add uploadAvatar method in AccountService
- Support SVG and image URL display in ProfilePage and EditProfilePage
- Add avatarUrl storage key for uploaded avatars
- Show upload progress indicator during avatar upload
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add updateProfile() and getMyProfile() methods to AccountService
- Load real user data (nickname, avatar) in EditProfilePage
- Call PUT /user/update-profile API to save nickname changes
- Display SVG avatar from backend
- Add loading state while fetching user data
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add import mnemonic page for account recovery
- Add serial number input field for recovery
- Add RecoverAccountResponse class for API response parsing
- Fix share page URL path (remove duplicate /api)
- Fix bottom nav bar height for better adaptability
- Update routes for import mnemonic page
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend (blockchain-service):
- Add RecoveryMnemonicAdapter to generate 12-word BIP39 mnemonic
- Generate mnemonic when wallet addresses are derived (linked to public key)
- Include mnemonic in WalletAddressCreated event
Backend (identity-service):
- Add RecoveryMnemonic table with revocation/replacement support
- Save encrypted mnemonic to database on WalletAddressCreated event
- Add PUT /user/mnemonic/backup API to mark mnemonic as backed up
- Clear plaintext mnemonic from Redis after backup confirmation
Frontend (mobile-app):
- Update markMnemonicBackedUp() to call backend API
- Fix verify_mnemonic_page validation logic:
- Checkbox checked → pass directly
- Not checked → must select correct word
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Extract 'data' field from API response before parsing
- Fix createAccount() to parse responseData['data']
- Fix getWalletInfo() to parse responseData['data']
- Resolves: type 'Null' is not a subtype of type 'int' in type cast
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
后端DeviceNameDto只接受model/platform/osVersion三个字段
移除brand/manufacturer/device/product/hardware/sdkInt/isPhysicalDevice
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive debugPrint logging with [Tag] prefixes:
- [AccountService]: API calls, storage operations, responses
- [OnboardingPage]: account status check, creation flow
- [BackupMnemonicPage]: wallet info loading, polling state
Logging includes:
- Request/response details with masked sensitive data
- Stack traces for error handling
- Polling count and timing for wallet generation
- User interaction tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Frontend (account_service.dart):
- Use Android ID instead of random UUID for deviceId
- Add DeviceHardwareInfo class with full hardware details
- Remove provinceCode/cityCode from CreateAccountRequest
- Simplify to: deviceId (required), deviceName (optional JSON), inviterReferralCode (optional)
Backend (identity-service):
- Rename validateDeviceId() to checkDeviceNotRegistered() for clarity
- Rename generateNext() to generateNextUserSequence() for semantics
- Update error message: "该设备已创建过账户"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- 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.