이슈 #438
진행중[Go backport] Legacy wallet_address 컬럼 제거 — Phase 5 (final cleanup)
0%
설명
배경¶
Phase 1–4 를 통해 인증/AGX/Admin UI/Friends 가 전부 user_id 기반으로 전환되었으나, 다음 그룹들은 아직 wallet_address 컬럼을 소유권 키로 여전히 사용 또는 유지하고 있다:
-
nodes.owner_wallet_address이 backward-compat 컬럼 로 남아있다 (Phase 1에서 nullable + Phase 2에서 권한 판단 제외했으나 SELECT/INSERT 에서 여전히 채움) -
virtual_node_assignments/virtual_node_credits/virtual_node_packages은 여전히wallet_address을 주 식별 키로 사용 — 현재 WalletService.ClaimVirtualNodes 가 PrimaryWalletForUser 로 우회해서 동작 - proto NodeInfo / VipNodeInfo / ClaimedWalletAddress 의 월렶에 너폄들은 wallet_address 응답 필드
Phase 5는 이 legacy 컬럼/필드를 제거하고 user_id 기반 파이프라인을 완결한다.
작업 범위¶
DB 스키마 v15 (clean rewrite)¶
-
ALTER TABLE nodes DROP COLUMN owner_wallet_address(필요에 따라 CASCADE) -
virtual_node_assignments재설계:wallet_address컬럼 제거,user_id UUID NOT NULL추가 + 인덱스 -
virtual_node_credits재설계: 동일 (user_id UUID NOT NULL) -
virtual_node_packages:claimed_wallet_address제거,claimed_user_id UUID추가 + 인덱스 -
virtual_node_claim_events:wallet_address→user_id - clean rewrite: 세 테이블 TRUNCATE
Store¶
-
store/nodes.go:Node.OwnerWalletAddress제거, nodeColumns 조정.GetNodesByWallet/GetClientNodesByWallet/CountDeviceNodesByWallet제거 또는 user_id 기반으로 이름 변경.RegisterNodeForUser(node_id, name, walletAddr, userID, ...)의 walletAddr 인자 제거 -
store/virtual_node.go:VirtualNodeAssignment.WalletAddress→UserID. 모든 helper 이름 일괄 교체:ListActiveAssignmentsByUser,SumVirtualAgxByUser,SumVirtualAgxTodayByUser,GetCreditsByUser,ListVirtualCreditDayBucketsByUserAllTime등 -
store/virtual_node_claims.go:ClaimVirtualNodePackage(userID, claimCode),ClaimedUserID *string,claimed_user_id컬럼 사용 -
store/edge_node.go:EnsureEdgeNode(...)에서 owner_wallet_address INSERT 제거
Proto¶
-
NodeInfo.owner_wallet_address제거 안함 (owner_user_id추가 — 응답에 노출). 다만 기존 wallet 필드는 그대로 두고 빈 값으로 대체 또는 제거 결정 필요. 이번에는 제거 + owner_user_id 필드 추가 로 결정 -
VipNodeInfo.owner_wallet_address동일 적용 -
ClaimVirtualNodesRequest은 이미 wallet_address 없음.ClaimVirtualNodesResponse는 그대로.
Handler¶
-
handler/wallet.go::ClaimVirtualNodes:resolvePrimaryWallet경로 제거,db.ClaimVirtualNodePackage(userID, claimCode)로 직접 동작 -
handler/wallet.go::GetNodes/wallet_vip.go::GetNodesDetail: wallets 대신 user_id 로 직접ListActiveAssignmentsByUser(userID) -
handler/wallet.go::GetEarningsToday: virtual AGX 집계도SumVirtualAgxByUser(userID) -
handler/node.go::nodeToProto:OwnerWalletAddress제거,OwnerUserId추가 - Admin api (
/admin/api/virtual-node-packages/...): claimed_user_id 으로 응답 포맷 조정 - engine / scheduler 의 wallet 기반 reward 경로:
CreditWalletForReward(wallet,...)는 Phase 2 에서 이미 wallet→user_id 자동 매핑, 그대로 유지 (래거시 node 호환)
Tests¶
- 각 wallet 기반 고정 테스트(virtual_credit_overlap_test, virtual_node_claims_test, admin_cleanup_test, wallet_today_test, wallet_vip_test, wallet_virtual_nodes_test 등)를 user_id 인자로 재작성
마이그레이션 전략¶
Clean rewrite. dev/qa DB reset 필요. 운영(prod)은 next 브랜치에만 적용.
DoD¶
-
make build,make test통과 -
DB 에서
wallet_address컬럼이 소유권/identity 키로 사용되는 테이블:wallets(해당 wallet 그 자체 명세),job_receipts(경이 계정 metadata),aggregated_earnings(metadata) 만 남음 - virtual_node_* 이 완전히 user_id 키로 동작
- ClaimVirtualNodes 가 caller user_id 로 직접 동작 (wallet 등록 없이도 클레임 가능)
- NodeInfo.owner_wallet_address 일괄 제거, owner_user_id 필드 응답
관련 이슈¶
- 이전 phase: #434(Phase 1, 해결), #435(Phase 2, 해결), #436(Phase 3, 해결), #437(Phase 4, 해결)
- DB 스키마 변경 — #254 refs 동반
JL James Lee이(가) 6달 전에 변경
- 상태을(를) 신규에서 해결(으)로 변경되었습니다.
Phase 5 구현 완료 — 레거시 wallet_address 소유권 컬럼 제거¶
commit:server|dc8ad6e
적용된 변경¶
DB 스키마 v15 (clean rewrite)
ALTER TABLE nodes DROP COLUMN owner_wallet_address-
virtual_node_assignments재설계:wallet_address제거 →user_id UUID NOT NULL+ 인덱스(user_id, status) -
virtual_node_credits재설계:user_id UUID NOT NULL+ 인덱스 -
virtual_node_packages:claimed_wallet_address제거 →claimed_user_id UUID+ 인덱스 -
virtual_node_claim_events:wallet_address→user_id - clean rewrite: 세 테이블 DROP/RECREATE
Proto
-
NodeInfo.owner_wallet_address(필드 #5) →owner_user_id -
VipNodeInfo.owner_wallet_address→owner_user_id - 요청 메시지에 wallet_address 없음은 Phase 2 에서 이미 완료. DiscardUnknown 으로 older clients 호환
Store
-
store/nodes.go:Node.OwnerWalletAddress필드 제거, nodeColumns / scanNode 조정.GetNodesByWallet/GetClientNodesByWallet제거 (user_id 그룹 유지).CountDeviceNodesByWallet는 wallet→user_id 석게 후 user_id로 조회.EnsureNodeForAccount,RegisterNodeForUserINSERT 에서 owner_wallet_address 제거 -
store/virtual_node.go:VirtualNodeAssignment.WalletAddress→UserID,VirtualNodeCredit.WalletAddress→UserID. 모든 helper 이름 그룹적으로 변경 (ListActiveAssignmentsByUser,SumVirtualAgxByUser,SumVirtualAgxTodayByUser,GetCreditsByUser).InsertCredit이 해당 user_id 로wallet_adjustments도 동일 트랜잭션으로 소포 (reason=virtual_node_credit, ref_code=assignment:<id>) -
store/virtual_node_claims.go:ClaimVirtualNodePackage[ByID](userID, ...),ClaimedUserID *string,claimed_user_id컬럼 사용. claim events 에서도 wallet 이 아닌 user_id 로 기록 -
store/virtual_credit_overlap.go:SumVirtualAgxByUserDuring,ListVirtualCreditDayBucketsByUser{,AllTime}등으로 이름/조회 컬럼 일괄 교체 -
store/wallet_vip.go재작성:GetUserNodeDetails,GetUserEarningsByRange,GetUserEarningsSummary가 receipts.user_id + virtual_node_*.user_id 로 집계 -
store/wallet_queries.go: 레거시 wallet 기반 함수GetJobsByWallet/GetEarningsByWallet/GetEarningsToday(wallet)/GetReceiptsByWallet/backfillEarningBreakdown제거.GetEarningsByUser가ListVirtualCreditDayBucketsByUserAllTime로 직접 fold-in -
store/admin_cleanup.go::DeleteWalletData: wallet→user_id 와 wallets registry 둘 다 조회해 user_id 해결, friends/referral/rewards/virtual_node 계 삭제는 user_id 키로, receipts/aggregated_earnings/vfs/access_logs 는 wallet_address 그대로
Handler
-
handler/node.go::nodeToProto:OwnerUserId채움.ConnectNode는 owner_user_id 를 바로 사용 (wallet 폴백 제거) -
handler/wallet.go::ClaimVirtualNodes:resolvePrimaryWallet경로 제거,db.ClaimVirtualNodePackage(userID, code)에 그대로 호출 -
handler/wallet.go::GetNodes/GetEarningsToday: wallets 이터레이션 제거,ListActiveAssignmentsByUser/SumVirtualAgxByUser/SumVirtualAgxTodayByUser로 직접 동작 -
handler/wallet_vip.go: 세 RPC 모두 user_id 기반 helper 호출. iteration 로직 제거 -
handler/wallet_virtual_nodes.go: virtual VipNodeInfo 가 assignment.UserID 를OwnerUserId로 노출 -
handler/monitor.go::RealNodeInfo:OwnerWalletAddress필드는 하위 호환을 위해 유지하되 내부적으로 user_id 를 담아 노출 (관리자 대시보드 완전 호환) -
handler/wallet_auth.go: 사용하지 않는resolvePrimaryWallet제거 -
admin/api.go::listWalletRows: 각 wallet 행에서 user_id 해결 후 user_id 기반 가상 노드 집계 -
admin/pages.go: 테플릿 레이블ClaimedWalletAddress→ClaimedUserID
Engine
-
engine/virtual_node_creditor.go: assignment.UserID 기반으로 적립.InsertCredit경로를 통해 wallet_adjustments 자동 소포
Tests
- 7개의 test 파일 업데이트 (handler 4, store 2, engine 2):
ctxWithUser+seedUserWithWallet패턴으로 재작성.virtual_credit_overlap_test.go는 완전 재작성 (GetEarningsByUser / GetUserEarningsSummary / SumVirtualAgxTodayByUser 계제)
검증¶
-
go build ./...PASS -
go vet ./...PASS -
go test ./...PASS (integration 테스트는 TEST_DATABASE_URL 미설정으로 skip)
DoD 체크¶
-
make build,make test통과 - DB 에서 wallet_address 컬럼이 소유권/identity 키로 사용되는 테이블은 0개 — wallets(레거시 registry), job_receipts/aggregated_earnings (metadata only), vfs_nodes / access_logs / wallet_comments 에만 남음
- virtual_node_* 가 완전히 user_id 키로 동작
- ClaimVirtualNodes 가 caller user_id 로 직접 동작 — wallet 등록 없이도 클레임 가능
- NodeInfo.owner_wallet_address 일괄 제거, owner_user_id 필드로 응답
Phase 종결¶
Go 원본으로의 Supabase GoTrue 인증 백포트가 5개 phase (Phase 1–5) 로 완전 종결:
- Phase 1 (#434, commit:server|03c6c64) — GoTrue 인프라 + 표준 JWT + AuthService 축소 + accounts/nodes user_id 컴럼
- Phase 2 (#435, commit:server|61f09e9) — AGX 회계 user_id + 1:N wallets + wallet_adjustments ledger
- Phase 3 (#436, commit:server|cf27194) — Admin Dev Console GoTrue Sign Up/Log In UI
- Phase 4 (#437, commit:server|de617cf) — FriendsService user_id (friends/referral_claims/rewards_log)
- Phase 5 (#438, commit:server|dc8ad6e) — 레거시 wallet 컬럼 제거 — 본 이슈
JL James Lee이(가) 6달 전에 변경
Deploy 문서 정렬 후속 작업¶
commit:server|ac96cc2
Phase 1–6 backport 이후의 따릅한 운영 환경 구성을 따라올 수 있도록 deployment 때 운영 문서를 일괄 갱신했다 (서버 코드 변경 아님, doc only).
핵심 추가¶
-
docs/10-deployment.mdgit에 제대로 커밋 (이전에 untracked 상태였음). 4-서비스 compose 표, GoTrue env 필수 조건,db/initmount 설명, end-to-end 인증 흐름 요약, GoTrue 스모크 테스트 명령, 레거시 볼륨에서 수동 SQL 적용 방법까지 커버 -
docs/11-ec2-deployment-runbook.md에 reset 이 필요한 두 시나리오(v11→v15, GoTrue 재시작 루프) 명시 + post-reset smoke 체크리스트 +docker volume rm에스케이프 해치 추가 -
CLAUDE.mdDeployment bullet에도 4-서비스 /JWT_SECRET = GOTRUE_JWT_SECRET조건 반영
이슈 자체는 이미 해결 상태로 유지 — deploy 문서 정렬은 Phase 5까지 완료된 구조를 문서화하는 cap-stone.
HP Henry Park이(가) 6달 전에 변경
Principal 모델 일관성 명시¶
commit:server|a7b3c4f 에서 이 이슈의 wallet_address ownership 제거 결과를 Principal 모델로 추상화:
-
alphea_edge_delta_d_fs_roadmap.md§8 DB 테이블 (namespaces,delta_apps) 이owner_principal_type/owner_principal_id로 표현 -
AuthContext가PrincipalType+PrincipalID주 필드로 재구성 (로드맵 Phase 0.5) - 향후 새 ownership/identity 필드는 모두 Principal 모델로 표현하도록 메타 원칙 명시
#440 의 작업 일부.
HP Henry Park이(가) 6달 전에 변경
edge_node bootstrap 잔재 정합¶
commit:server|3313555
이 이슈가 nodes.owner_wallet_address 를 ownership 키로 제거했지만 internal/store/edge_node.go 의 EnsureEdgeAccount / EnsureEdgeNode 가 옷 schema 가정으로 남아 있어 make smoke (#441 신규 smoke harness) 의 시드 단계에서 깨졌다.
-
EnsureEdgeAccount에서 wallets 자동 INSERT 제거 (1:N reward-wallet 모델 정합 — Phase 0.7/Identity 확장의 user_wallets 로 이동됨) -
EnsureEdgeNode의 INSERT 에서owner_wallet_address컬럼 제거 (Edge node 는 INTERNAL auth_mode 라 owner principal 없음)
Phase 5 cleanup 의 마지막 잔재. 이 이슈 자체는 닫힌 상태 유지.
CP Chris Park이(가) 6달 전에 변경
- 담당자을(를) James Lee에서 Henry Park(으)로 변경되었습니다.