프로젝트

일반

사용자정보

Actions

이슈 #433

진행중
JL HP

VfsService 포팅 — per-account 가상 파일시스템 (Read/Write/List/Mkdir/Delete/Stat/Exists/Lock/Unlock)

이슈 #433: VfsService 포팅 — per-account 가상 파일시스템 (Read/Write/List/Mkdir/Delete/Stat/Exists/Lock/Unlock)

James Lee이(가) 약 7시간 전에 추가함.

상태:
해결
우선순위:
보통
담당자:
목표버전:
시작일:
2026/05/11
완료일:
진척도:

0%

추정시간:

설명

배경

alphea-ai-edge (Rust) 에 legacy VfsService 9 RPC 를 포팅한다. legacy 구현은 wallet-keyed vfs_nodes 테이블 + in-memory MemLocker 로 단순한 per-account 가상 파일시스템을 제공.

레거시 위치:

  • proto: ~/Works/alphea-rpc-next/alphea-rpc/proto/alphea/v1/vfs.proto (9 RPC)
  • handler: ~/Works/alphea-rpc-next/alphea-rpc/internal/handler/stubs.go:51-330 (~280 LoC)
  • store: ~/Works/alphea-rpc-next/alphea-rpc/internal/store/vfs.go (231 LoC)
  • domain locker: ~/Works/alphea-rpc-next/alphea-rpc/internal/domain/vfs/{locker.go,memlocker.go} (123 LoC)

목표

  • 9 RPC 모두 작동: Read, Write, List, Mkdir, Delete, Stat, Exists, Lock, Unlock.
  • legacy 와 기능 동등하지만 account-scope (user_id UUID) 로 전환 — wallet_address 키는 사용 안 함 (#421 정합성).
  • in-memory locker 백그라운드 evictor 포함.
  • /modules, /sys read-only 경로 보호.
  • 처음 접근 시 default tree 자동 초기화 (/home/node/{jobs,logs,workspace}, /modules/demo.*, /sys/version 등).

Proto 처리

proto/alphea/v1/vfs.proto 를 legacy 에서 복사하되:

  • option go_package 라인 제거 (CLAUDE.md 규칙).
  • 기존 필드명 wallet_address 는 wire 호환성을 위해 그대로 유지. 핸들러는 이 필드를 무시하고 JWT caller_user_id 를 사용 (silent override) — 향후 정리 시 별도 이슈에서 user_id 로 rename.
  • build.rs 에 vfs.proto 추가.

DB 스키마 (#254 refs)

신규 마이그레이션 migrations/0014_vfs_nodes.sql:

CREATE TABLE vfs_nodes (
    id            BIGSERIAL PRIMARY KEY,
    user_id       UUID        NOT NULL,
    path          TEXT        NOT NULL,
    name          TEXT        NOT NULL,
    node_type     TEXT        NOT NULL,        -- 'file' | 'directory'
    content       TEXT,
    mime_type     TEXT,
    size          BIGINT      NOT NULL DEFAULT 0,
    readonly      BOOLEAN     NOT NULL DEFAULT FALSE,
    created_at    TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    modified_at   TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE (user_id, path)
);

CREATE INDEX idx_vfs_user_path ON vfs_nodes (user_id, path);

(legacy 의 BIGINT unix-seconds 타임스탬프 → Rust 측 TIMESTAMPTZ 통일. proto wire 에서는 .timestamp() 로 변환.)

인증

  • auth_middleware::public_path_set() 에 VfsService RPC 추가하지 않음 — 모두 protected.
  • 핸들러 본문에서 require_user_token(&request)? 로 GoTrue user UUID 가져와 user_id 로 사용.
  • proto 의 wallet_address 필드는 받아서 무시 (deprecated).
  • node 토큰은 거부 — VFS 는 사용자 계정 스코프 자원.

Lock 의미

  • holder_id 는 클라이언트가 정하는 자유 문자열 (legacy 와 동일 — node_id, session id, 임의 UUID 모두 가능).
  • TTL 기본 60초, 커스텀 TTL 지정 가능.
  • 동일 holder 의 재 lock 은 TTL 연장.
  • Write/Delete 핸들러는 metadata x-holder-id (gRPC 소문자 헤더) 로 lock ownership 검증 — holder 가 다른 사람의 lock 키와 매치되면 aborted 반환.

파일 추가

  • proto/alphea/v1/vfs.proto (copy + go_package 제거)
  • migrations/0014_vfs_nodes.sql
  • src/store/vfs.rs — VfsRow, get_node, list_children, write, mkdir, delete, exists, ensure_init
  • src/domain/vfs/mod.rs + src/domain/vfs/locker.rs — MemLocker (tokio::sync::Mutex<HashMap> 기반, evictor task)
  • src/handler/vfs.rs — 9 RPC

파일 수정

  • build.rs — proto 목록에 vfs.proto 추가
  • src/handler/mod.rs — VfsHandler 노출
  • src/server/mod.rs — AppState.vfs_locker: Arc<MemLocker> 추가, evictor spawn, gRPC 서비스 등록
  • src/main.rs — AppState 구성
  • src/store/mod.rs — pub mod vfs;
  • src/domain/mod.rs — pub mod vfs;

완료 기준 (DoD)

  • 9 RPC 모두 구현 (unimplemented stub 없음).
  • cargo build clean.
  • cargo clippy --lib 신규 코드 경고 0.
  • cargo test --lib 전부 통과 + 신규 단위 테스트:
    • vfs::locker::* (acquire / re-acquire same holder / blocked by other / TTL expiry / unlock).
    • vfs::store::* (path 정규화 / list_children direct-child filter — 가능하면).
  • CLAUDE.md 의 "Current Implementation Snapshot" 표에 VfsService 추가, "5 미포팅 서비스" 목록에서 제거.

관련 이슈

  • #254 — DB 스키마 (마이그레이션 추가 시 refs).
  • #421 — account-scope 전환. 본 이슈가 그 정책 위에서 동작.
  • #375 — JWT 전역 인터셉터. require_user_token 사용.

예상 작업량

  • proto + migration + store: 1.5h
  • locker + evictor: 1h
  • handler 9 RPC: 2h
  • 테스트 + wiring + CLAUDE.md: 1.5h
  • 총: 6h

연결된 일감 2 (2 건 진행 중 — 모두 미완료)

다음 일감과 관련됨: 이슈 #254: 8-2. 데이터베이스 스키마 설계 (사용자. 앱. 일정)진행James Lee2026/04/282026/04/29

Actions
다음 일감과 관련됨: 이슈 #421: AGX 잔액을 Wallet 종속 → Account(GoTrue user_id) 종속으로 전환해결James Lee2026/04/27

Actions
Actions

내보내기 PDF Atom