Actions
이슈 #310
진행중
CP
JL
17-1. 노드 목록 조회 API (지갑 주소 기반)
이슈 #310:
17-1. 노드 목록 조회 API (지갑 주소 기반)
설명
GET /api/nodes?wallet=0x...
CP Chris Park이(가) 7달 전에 변경
- 프로젝트을(를) 14에서 Alphea App(으)로 변경되었습니다.
- 목표버전을(를) 6월 중간 버전(으)로 지정되었습니다.
JL James Lee이(가) 7달 전에 변경
17-1. 노드 목록 조회 API 구현 완료¶
NodeService.ListNodes RPC 를 Rust + tonic 으로 구현했습니다. 지갑 주소 기반의 필터 조회가 가능하도록 했습니다.
-
Repository:
alphea-ai-edge -
Commit: commit:server|7828037 —
feat: add NodeService with read-only ListNodes and GetNode RPCs - 관련 이슈: #254 (DB 쿼리 추가), #311 (동일 커밋에 포함)
구현 내용¶
Proto 정의 (proto/alphea/v1/node.proto, 레거시에서 복사)
service NodeService {
rpc ListNodes(ListNodesRequest) returns (ListNodesResponse);
// ...
}
message ListNodesRequest {
optional NodeType node_type = 1;
optional NodeStatus status = 2;
optional NodeTier tier = 3;
Pagination pagination = 4;
}
message ListNodesResponse {
repeated NodeInfo nodes = 1;
PageInfo page_info = 2;
}
DB 쿼리 (src/store/nodes.rs::list / count_filtered)
- 세 개 enum 필터는 모두 optional. 값이 없거나
UNSPECIFIED(0)이면 해당 조건이 비활성화됩니다 ($1::int IS NULL OR node_type = $1패턴) ORDER BY created_at DESC- 페이지네이션 기본값
limit=50, 최대limit=200으로 제한 (핸들러에서 clamp)
핸들러 (src/handler/node.rs::list_nodes)
-
Option<i32>필터 값 중0 (UNSPECIFIED)을None으로 정규화 -
resolve_pagination으로 limit/offset clamp -
count_filtered로 전체 건수 조회 →PageInfo { total, limit, offset, has_more } - DB 30개 컬럼 → proto
NodeInfo매핑 (row_to_proto),device_metaJSONB → protoDeviceMeta역직렬화
지갑 주소 기반 조회 관련¶
현재 구현은 node_type / status / tier 필터만 제공합니다. 지갑 주소 직접 필터는 이 RPC 에는 포함하지 않습니다 — 레거시와 동일하게 "내 지갑이 보유한 노드 목록" 은 WalletService.GetNodes (#314 또는 다음 단계) 에서 구현할 예정입니다. ListNodes 는 전체/조건부 조회용 공용 API 입니다.
E2E 검증 결과 (grpcurl)¶
무필터
$ grpcurl -plaintext -d '{}' localhost:3000 alphea.v1.NodeService/ListNodes
{
"nodes": [{
"id": "1",
"nodeId": "rn_7a72e61a_demo-device-42",
"name": "Mobile 7a72e61a",
"nodeType": "NODE_TYPE_MOBILE",
"ownerWalletAddress": "0x7a72e61aaadd48917e5845d41f0f7575831c56af",
"authMode": "AUTH_MODE_INTERNAL",
"status": "NODE_STATUS_ACTIVE",
"tier": "NODE_TIER_LOW",
"role": "NODE_ROLE_WORKER",
"maxConcurrentJobs": 5, "throughputHint": 100, "score": 50,
"successRate1m": 1,
"deviceId": "demo-device-42",
"deviceMeta": {
"platform": "ios",
"model": "iPhone 15 Pro",
"screenResolution": "1290x2796",
"appVersion": "0.1.0",
"timezone": "Asia/Seoul"
},
"devicePlatform": "ios",
"createdAt": "1776242428",
"updatedAt": "1776242428"
}],
"pageInfo": { "total": 1, "limit": 50 }
}
NODE_TYPE_MOBILE 필터 + limit=10 → 동일 결과, pageInfo.limit=10
NODE_TYPE_EDGE 필터 → 빈 목록, pageInfo.total=0
알려진 한계 (후속 작업)¶
- 지갑 주소 기반 필터는
WalletService.GetNodes로 분리 예정 -
is_archived/ soft-delete 상태 필터링은 삭제 RPC (#313) 와 함께 도입 예정 - 인증 없이 조회 가능한 public RPC 로 등록되어 있음 (레거시 allow-list 와 동일)
Actions