Actions
이슈 #435
진행중
JL
HP
[Go backport] AGX 회계 user_id 종속 전환 — Phase 2
이슈 #435:
[Go backport] AGX 회계 user_id 종속 전환 — Phase 2
시작일:
2026/05/12
완료일:
2026/05/12 (약 6달 지연)
진척도:
0%
추정시간:
설명
배경¶
GoTrue 인증 전환 (#434 Phase 1, commit:server|03c6c64) 의 후속. 식별 권한을 user_id 기반으로 옮겼으나, AGX 잔액 / 수익 / 집계 는 여전히 wallet_address 키 기반이다. Rust 측 #421 을 Go 원본으로 백포트해 AGX 회계의 단일 키를 GoTrue user_id 로 통일한다.
작업 범위¶
DB 스키마 v13 (마이그레이션, clean rewrite)¶
-
wallets재설계: 기존 (account_id, balance, total_earned) 1:1 →(user_id UUID, wallet_address TEXT, label TEXT, created_at)1:N.UNIQUE(user_id, wallet_address) -
job_receipts.user_id UUID컬럼 추가 + 인덱스(user_id, completed_at DESC) -
aggregated_earnings.user_id UUID컬럼 추가 +UNIQUE(user_id, period_date, period_type) -
wallet_adjustments신규 테이블:(id, user_id UUID, delta_agx DOUBLE PRECISION, reason TEXT, ref_code TEXT, created_at). redeem / admin credit·debit 결제를 기록 - 잔액 공식:
Σ job_receipts.reward_agx WHERE user_id=$1 + Σ wallet_adjustments.delta_agx WHERE user_id=$1 - clean rewrite: receipts / aggregated_earnings / wallets dev 데이터 DROP
Store 계층¶
-
store/wallets.go(신규 모듈):AddWallet(userID, wallet),RemoveWallet,ListWalletsByUser,GetUserIDByWallet -
store/wallet_adjustments.go(신규):InsertAdjustment,SumByUser,ListByUser -
store/wallet_queries.go재작성: 수익/잔액 조회를 user_id 기반으로 교체. 기존 wallet_address 기반 함수는 deprecated -
store/receipts.go:ListByUser,CountByUser,SummaryForUser,TodayForUser,EntriesByRangeuser_id 기반으로. 삽입 시 user_id 함께 저장 -
store/edge_node.go::UpsertAggregatedEarning: user_id 인자 추가
Proto¶
-
wallet.proto에서 다음 요청 메시지의wallet_address제거:WalletJobsRequest,WalletNodesRequest,WalletEarningsRequest,WalletEarningsTodayRequest,WalletReceiptsRequest,WalletNodesDetailRequest,WalletEarningsByRangeRequest,WalletEarningsSummaryRequest,ClaimVirtualNodesRequest. 서버는 caller user_id 로 조회
Handler¶
-
handler/wallet_auth.go::requireAuthenticatedWallet→requireAuthenticatedUser(caller user_id 만 검증. wallet 권한 검사가 필요한 곳은 별도 헬퍼) -
handler/wallet.go: 6개 RPC user_id 기반으로 재작성. Wallet 조회 계산 공식 적용 -
handler/wallet_vip.go: 3개 RPC. 관리자도 caller user_id 기반으로 (admin proxy 는 user_id 로 우회)
본 phase 에서 다루지 않는 것¶
-
FriendsService테이블 user_id 전환 (Phase 3 이슈 예정) -
virtual_node_assignments/virtual_node_credits/virtual_node_packages스키마를 user_id 기반으로 (이는 그대로 유지하고 user→wallet 매핑으로 우회) - Admin Dev Console GoTrue UI (#424 백포트— 별도 phase)
마이그레이션 전략¶
Clean rewrite. dev/qa DB 는 reset 필요. Phase 1 과 동일한 정책 (scripts/ec2/reset-db.sh).
DoD¶
-
make build,make test통과 - WalletService 9개 RPC 가 GoTrue user JWT 없으면 Unauthenticated 거부
- Wallet 잔액 = Σ receipts (user_id) + Σ adjustments (user_id) 로 계산
-
wallet_adjustments으로 admin credit/debit 가능 (store 계층 귀니)
관련 이슈¶
JL James Lee이(가) 6달 전에 변경
- 상태을(를) 신규에서 해결(으)로 변경되었습니다.
Phase 2 구현 완료¶
commit:server|61f09e9
적용된 변경¶
DB 스키마 v13 (clean rewrite)
-
wallets(account_id, balance) 1:1 구조 제거 →(user_id UUID, wallet_address, label, created_at)1:N.UNIQUE(user_id, wallet_address)+ 2개 인덱스 -
job_receipts.user_id UUID+ 인덱스(user_id, completed_at DESC) -
aggregated_earnings.user_id UUID+ 고유 인덱스(user_id, period_date, period_type)+ 일자 인덱스(user_id, period_date) -
wallet_adjustments신규 테이블:(user_id, delta_agx, reason, ref_code, created_at)+ 인덱스 2개 - 잔액 공식:
Σ job_receipts.reward_agx WHERE user_id=$1 AND status='completed' + Σ wallet_adjustments.delta_agx WHERE user_id=$1
Store (신규 / 개편)
-
store/wallets.go(신규):AddWalletForUser,RemoveWalletForUser,ListWalletsByUser,GetUserIDByWallet,PrimaryWalletForUser -
store/wallet_adjustments.go(신규):InsertAdjustment,SumAdjustmentsForUser,ListAdjustmentsForUser -
store/accounts.go:GetWalletBalance→ user→receipts+adjustments 로 대체.GetBalanceForUser,CreditWalletForReward(wallet→user_id 자동 매핑),UpdateLastActiveByUser헬퍼 추가.ListAccountsWithBalance는 CTE 로 receipts+adjustments 집계로 재작성 -
store/receipts.go:CreateReceipt가 wallet→user_id 자동 조회 후user_id컬럼에 스탠프.AggregateReceipts가 user_id 를 그룹에 포함해 aggregated_earnings 에 COALESCE 업서트 -
store/wallet_queries.go:GetJobsByUser,GetEarningsByUser,GetEarningsTodayForUser,GetReceiptsByUser신규 — 기존 wallet 기반 함수는 유지(virtual-node / engine 경로 호환) -
store/nodes.go:GetNodesByUserID,GetClientNodesByUserID -
store/friends.go:UpdateWalletBalanceByAccountID/GetWalletBalanceByAccountID제거.CreditAccount(accountID, delta, reason, refCode)가 account→user_id→adjustment 로 라우팅
Proto
-
wallet.proto의 9개 요청 메시지(WalletJobsRequest, WalletNodesRequest, ClaimVirtualNodesRequest, WalletEarningsRequest, WalletEarningsTodayRequest, WalletReceiptsRequest, WalletNodesDetailRequest, WalletEarningsByRangeRequest, WalletEarningsSummaryRequest) 에서wallet_address필드 제거 - 서버 codec(
internal/server/jsoncodec.go) 에DiscardUnknown: true추가 — 아직 남아있는 클라이언트가 wallet_address 필드를 보내도 마이그레이션 기간 동안 수용
Handler
-
handler/wallet_auth.go:requireAuthenticatedWallet제거 →requireUser(user JWT 만 허용) +resolvePrimaryWallet(virtual-node claim 등에서 사용) -
handler/wallet.go: 6개 RPC(GetJobs/GetNodes/ClaimVirtualNodes/GetEarnings/GetEarningsToday/GetReceipts) caller user_id 기반으로 재작성. virtual-node 집계는 user→wallets 이터레이션 후 합산 -
handler/wallet_vip.go: 3개 RPC(GetNodesDetail/GetEarningsByRange/GetEarningsSummary) user_id 기반으로 전환. wallets 명단 없으면 빈 응답 또는 0 합산
Engine / RPCBridge
-
engine/rpcbridge.go::UpdateWalletBalance→db.CreditWalletForReward(wallet, delta, "scheduler_reward")로 대체. 등록되지 않은 wallet 은 silent drop(레거시 노드 호환)
SDK
-
sdk/api.go: 9개 Wallet RPC 의 JSON payload 에서 walletAddress 필드 제거.sdk/call_test.go동일으로 업데이트
Tests
-
internal/handler/test_helpers.go:uniqueTestUserID,ctxWithUser,seedUserWithWallet헬퍼 추가 - wallet_today_test, wallet_vip_test, wallet_virtual_nodes_test, friends_halving_test, virtual_node_creditor_test, admin_cleanup_test, agx_halving_test, virtual_credit_overlap_test, virtual_node_claims_test 를 새 인증 모델에 맞춰 수정:
CreateWallet(제거됨) 호출 삭제,ContextWithWallet→ctxWithUser(seedUserWithWallet(...)), proto 요청에서WalletAddress:필드 제거
문서
-
CLAUDE.mdIdentity tables / AGX accounting 설명 업데이트, schema_version v13 표기
검증¶
-
go build ./...PASS -
go vet ./...PASS (warnings 0) -
go test ./...PASS — 모든 unit 테스트 완료(integration 테스트는 TEST_DATABASE_URL 미설정으로 skip)
DoD 체크¶
-
make build,make test통과 - WalletService 9개 RPC 가 user JWT 없으면 Unauthenticated 거부 (require_user_token 패턴)
- Wallet 잔액 = Σ receipts (user_id) + Σ adjustments (user_id) 로 계산
-
wallet_adjustments으로 friend reward + scheduler reward + redeem(추후) 계도 구축 가능 (store 계층 되)
후속 (Phase 3+ 이슈)¶
- FriendsService 테이블 user_id 전환 (
friends.inviter_id/invitee_id→ user_id; referral_claims/rewards_log user_id) - Admin Dev Console GoTrue Sign Up / Log In proxy + UI (#424 백포트)
-
nodes.owner_wallet_address제거,virtual_node_assignments/virtual_node_credits/virtual_node_packages을 user_id 직접 키로 전환
CP Chris Park이(가) 6달 전에 변경
- 담당자을(를) James Lee에서 Henry Park(으)로 변경되었습니다.
Actions