프로젝트

일반

사용자정보

Actions

이슈 #310

진행중
CP JL

17-1. 노드 목록 조회 API (지갑 주소 기반)

이슈 #310: 17-1. 노드 목록 조회 API (지갑 주소 기반)

Chris Park이(가) 약 5시간 전에 추가함.

상태:
해결
우선순위:
높음
담당자:
목표버전:
시작일:
2026/05/19
완료일:
2026/05/19 (약 6달 지연)
진척도:

0%

추정시간:

설명

GET /api/nodes?wallet=0x...

CP Chris Park이(가) 7달 전에 변경 Actions #1

  • 프로젝트을(를) 14에서 Alphea App(으)로 변경되었습니다.
  • 목표버전을(를) 6월 중간 버전(으)로 지정되었습니다.

JL James Lee이(가) 7달 전에 변경 Actions #2

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_meta JSONB → proto DeviceMeta 역직렬화

지갑 주소 기반 조회 관련

현재 구현은 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 와 동일)

JL James Lee이(가) 7달 전에 변경 Actions #3

  • 상태을(를) 신규에서 해결(으)로 변경되었습니다.

17-1 작업 완료 — 해결 전환

  • Section 17 Step 1 에서 NodeService.ListNodes RPC 구현 완료 (commit:server|7828037)
  • Section 17 Step 3 에서 archived 노드 자동 필터링 추가 (commit:server|d9668e6) — 삭제된 노드는 목록에서 자동 제외

E2E 검증 완료. 후속 기능 확장이 필요하면 별도 이슈로 추적.

Actions

내보내기 PDF Atom