メインコンテンツへ

ストレージ

一言でいうと

storage は「テナントのドキュメントがどこに実体として存在するか」を表す StorageDevice(+ その配下の複数ルート StorageDeviceRoot)を管理するモジュール。LOCAL(ユーザーのPC・Tauriデスクトップアプリ経由)と NETWORK_DRIVE(事務所のNAS・Go agent 経由)はどちらも agent-based(WebSocket 常時接続)で、"あるメンバーのローカルにしかない" という状態は存在しない — オンラインなデバイス上のファイルは接続中の全メンバーに配信される。実際のファイル同期処理そのものは sync モジュールが担当し、storage はデバイスのライフサイクル(登録・接続状態・ルート構成)を管理する。

主要ドメイン概念

概念役割
StorageDevice1台の物理/仮想ストレージ拠点。type(LOCAL / NETWORK_DRIVE)と connectionMode(AGENT / CLI)を持つ
StorageDeviceRootデバイス内の名前付きサブツリー(マルチルート)。rootKey == "" は multi-root 導入前からの legacy root で / に固定マウントされる
ConnectionModeAGENT(astar-agent 常駐・WebSocket 常時接続・ファイル同期あり)/ CLI(本人PCの astar CLI・トークン疎通のみでファイル同期なし)
StorageModeworkspace モジュール側)ワークスペースがどのストレージを使うか。CLOUD(既定)/ LOCAL / NETWORK_DRIVE / EXTERNAL_CLOUD の4種、詳細は ワークスペース
WebDAV 資格情報core/webdav が発行するネットワークドライブマウント用の認証情報。UI は storage モジュールに同居

Backend 構造

core/storage/ は規約どおりの3層構造。

  • api/controller/: StorageControllerGET /local-path — DocumentNode をエージェントホストの絶対パスへ解決し、Tauri opener や ms-word:ofe|u|... URI でネイティブアプリを起動する)、StorageDeviceController(デバイス CRUD、ルート CRUD、接続トークン発行・再発行、登録コード発行、Codex device-auth フロー、SSE ストリーム)
  • domain/service/: StorageDeviceService(デバイス作成・接続状態記録・ハートビート・ルート追加/削除・トークン検証・削除)、LocalPathResolutionService(上記 local-path 解決。CLOUD モードのワークスペースは 503 で拒否し、呼び出し元に in-app 編集へのフォールバックを促す)
  • domain/model/: StorageDeviceStorageDeviceRootStorageDeviceTypeConnectionModeAgentUpdateStatusLocalPathResolution
  • domain/event/: StorageDeviceConnectedEvent(エージェントが WebSocket 認証されオンラインになった時に発火。AFTER_COMMIT で消費され、デバイスオフライン中に失敗した処理をオンライン復帰時にリトライさせる)、StorageDeviceDeletedEvent
  • infrastructure/adapter/: StorageTenantResolutionAdapter

Frontend 構造

app/modules/storage/ は規約の4分類に加えて storesutils を持つ。

  • components/: StorageDeviceList.vue(デバイス一覧・選択の共通UI)、StorageDeviceListPanel.vueStorageDeviceForm.vue / StorageDeviceEditDialog.vueStorageDeviceRootsEditor.vue / StorageDeviceRootRow.vue(マルチルート編集)、StorageDeviceReconnectDialog.vueNasFolderPickerField.vueMountDriveLetterDialog.vueWinFspGuidanceDialog.vueWorkspaceMountCard.vue / WorkspaceMountCardBody.vueAgentSidecarBadge.vueStorageUsageSummary.vue
  • composables/: useStorageDevices(デバイス一覧取得)、useStorageStatsuseCodexDeviceAuthuseWinFspCheck(Windows の WinFsp 前提条件チェック)、useWorkspaceAutoReconnect / useWorkspaceMountPreferencesuseStableOfflineDevicesuseNasTreePickerDataLoader
  • repositories/: StorageDeviceRepositoryWebDavCredentialRepository(WebDAV 資格情報の発行・一覧・失効)

WebDAV (core/webdav)

core/webdav はテナントのドキュメントツリーを WebDAV サーバーとして公開するバックエンド専用モジュール(frontend モジュールは持たず、UI は storage に同居)。api/servlet/WebDavServlet が実際の WebDAV プロトコル(PROPFIND/PUT/LOCK 等)を処理し、api/controller/WebDavCredentialController が資格情報の発行/一覧/失効 API を提供する。frontend 側は WebDavCredentialRepository 経由で MountDriveLetterDialog.vue などから呼び出す。

他モジュールとの辺

  • sync: storage はデバイスの存在・接続状態・ルート構成を管理し、実際のファイルスキャン・同期は sync(+ core/agent の WebSocket ハンドラ)が行う。デバイス追加 UI(DeviceConnectDialog.vue)は sync モジュール側にあり、デバイス選択・一覧 UI(StorageDeviceList.vue)は storage 側にある
  • workspace: WorkspaceStorageLinkedEvent を受けてワークスペースが agent-based デバイスに紐づいた際に再スキャンを起動する
  • editor: LocalPathResolutionServiceDocumentNodeRepository を使い、ノードのローカルファイルパスを解決する
  • agent: WebSocket 接続そのもの(AgentWebSocketHandler 等)は core/agent が持ち、storage はその上のデバイスレコードを管理する

共通デバイス選択 UI は2つのモジュールに分かれている(自作禁止)— 選択・一覧storage モジュールの StorageDeviceList.vue新規追加sync モジュールの DeviceConnectDialog.vue。デバイス関連 UI を新設するときにどちらか一方だけを見て「同種コンポーネントがない」と誤判定しやすいので、両モジュールを横断して確認すること。