# Jotai ディレクトリ構造・ファイル配置 ## 📁 確立されたディレクトリ構造 ``` states/ ├── ui/ │ ├── sidebar/ # サイドバー状態 ✅ │ ├── editor/ # エディター状態 ✅ │ ├── device.ts # デバイス状態 ✅ │ ├── page.ts # ページUI状態 ✅ │ ├── toc.ts # TOC状態 ✅ │ ├── untitled-page.ts # 無題ページ状態 ✅ │ ├── page-abilities.ts # ページ権限判定状態 ✅ DERIVED ATOM! │ ├── unsaved-warning.ts # 未保存警告状態 ✅ JOTAI PATTERN! │ └── modal/ # 個別モーダルファイル ✅ │ ├── page-create.ts # ページ作成モーダル ✅ │ ├── page-delete.ts # ページ削除モーダル ✅ │ ├── empty-trash.ts # ゴミ箱空モーダル ✅ │ ├── delete-attachment.ts # 添付ファイル削除 ✅ │ ├── delete-bookmark-folder.ts # ブックマークフォルダ削除 ✅ │ ├── update-user-group-confirm.ts # ユーザーグループ更新確認 ✅ │ ├── page-select.ts # ページ選択モーダル ✅ │ ├── page-presentation.ts # プレゼンテーションモーダル ✅ │ ├── put-back-page.ts # ページ復元モーダル ✅ │ ├── granted-groups-inheritance-select.ts # 権限グループ継承選択 ✅ │ ├── drawio.ts # Draw.ioモーダル ✅ │ ├── handsontable.ts # Handsontableモーダル ✅ │ ├── private-legacy-pages-migration.ts # プライベートレガシーページ移行 ✅ │ ├── descendants-page-list.ts # 子孫ページリスト ✅ │ ├── conflict-diff.ts # 競合差分モーダル ✅ │ ├── page-bulk-export-select.ts # ページ一括エクスポート選択 ✅ │ ├── drawio-for-editor.ts # エディタ用Draw.io ✅ │ ├── link-edit.ts # リンク編集モーダル ✅ │ └── template.ts # テンプレートモーダル ✅ ├── page/ # ページ関連状態 ✅ ├── server-configurations/ # サーバー設定状態 ✅ ├── global/ # グローバル状態 ✅ ├── socket-io/ # Socket.IO状態 ✅ ├── context.ts # 共通コンテキスト ✅ └── features/ └── openai/ └── client/ └── states/ # OpenAI専用状態 ✅ ├── index.ts # exports ✅ └── unified-merge-view.ts # UnifiedMergeView状態 ✅ features/ # Feature Directory Pattern ✅ └── page-tree/ # ページツリー機能 ✅ (NEW!) ├── index.ts # メインエクスポート ├── client/ │ ├── components/ # 汎用UIコンポーネント │ │ ├── SimplifiedItemsTree.tsx │ │ ├── TreeItemLayout.tsx │ │ └── SimpleItemContent.tsx │ ├── hooks/ # 汎用フック │ │ ├── use-data-loader.ts │ │ └── use-scroll-to-selected-item.ts │ ├── interfaces/ # インターフェース定義 │ │ └── index.ts # TreeItemProps, TreeItemToolProps │ └── states/ # Jotai状態 ✅ │ ├── page-tree-update.ts # ツリー更新状態 │ └── page-tree-desc-count-map.ts # 子孫カウント状態 └── constants/ └── index.ts # ROOT_PAGE_VIRTUAL_ID ``` ## 📋 ファイル配置ルール ### UI状態系 (`states/ui/`) - **個別機能ファイル**: デバイス、TOC、無題ページ等の単一機能 - **複合機能ディレクトリ**: サイドバー、エディター等の複数機能 - **モーダル専用ディレクトリ**: `modal/` 配下に個別モーダルファイル ### データ関連状態 (`states/`) - **ページ関連**: `page/` ディレクトリ - **サーバー設定**: `server-configurations/` ディレクトリ - **グローバル状態**: `global/` ディレクトリ - **通信系**: `socket-io/` ディレクトリ ### 機能別専用states (`states/features/` および `features/`) **OpenAI機能**: `states/features/openai/client/states/` **ページツリー機能**: `features/page-tree/client/states/` ✅ (Feature Directory Pattern) ### Feature Directory Pattern (新パターン) ✅ `features/{feature-name}/` パターンは、特定機能に関連するコンポーネント、フック、状態、定数をすべて一箇所に集約する構造。 **適用例**: `features/page-tree/` ``` features/page-tree/ ├── index.ts # 全エクスポートの集約 ├── client/ │ ├── components/ # UIコンポーネント │ ├── hooks/ # カスタムフック │ ├── interfaces/ # 型定義 │ └── states/ # Jotai状態 └── constants/ # 定数 ``` **インポート方法**: ```typescript import { SimplifiedItemsTree, TreeItemLayout, usePageTreeInformationUpdate, ROOT_PAGE_VIRTUAL_ID } from '~/features/page-tree'; ``` ## 🏷️ ファイル命名規則 ### 状態ファイル - **単一機能**: `{機能名}.ts` (例: `device.ts`, `toc.ts`) - **複合機能**: `{機能名}/` ディレクトリ(例: `sidebar/`, `editor/`) - **モーダル**: `modal/{モーダル名}.ts`(例: `modal/page-create.ts`) ### export/import規則 - **公開API**: `index.ts` でのre-export - **内部atom**: `_atomsForDerivedAbilities` 特殊名export - **機能専用**: 機能ディレクトリ配下の独立したstates ## 📊 ファイルサイズ・複雑度の目安 ### 適切なファイル分割 - **単一ファイル**: ~100行以内、単一責務 - **ディレクトリ分割**: 複数のhook・機能がある場合 - **個別モーダルファイル**: 1モーダル = 1ファイル原則 ### 複雑度による分類 - **シンプル**: Boolean状態、基本的な値管理 - **中程度**: 複数プロパティ、actions分離 - **複雑**: Derived Atom、Map操作、副作用統合 ## 🔗 依存関係・インポート構造 ### インポート階層 ``` components/ ├── import from states/ui/ # UI状態 ├── import from states/page/ # ページ状態 ├── import from states/global/ # グローバル状態 └── import from states/features/ # 機能別状態 states/ui/ ├── 内部相互参照可能 └── states/page/, states/global/ からのimport states/features/{feature}/ ├── states/ui/ からのimport ├── 他のfeatures からのimport禁止 └── 独立性を保つ ``` ### 特殊名Export使用箇所 ``` states/page/internal-atoms.ts → _atomsForDerivedAbilities states/ui/editor/atoms.ts → _atomsForDerivedAbilities states/global/global.ts → _atomsForDerivedAbilities states/context.ts → _atomsForDerivedAbilities ``` ## 🎯 今後の拡張指針 ### 新規機能追加時 1. **機能専用度評価**: 汎用 → `states/ui/`、専用 → `features/{feature-name}/client/states/` 2. **複雑度評価**: シンプル → 単一ファイル、複雑 → ディレクトリ 3. **依存関係確認**: 既存atomの活用可能性 4. **命名規則遵守**: 確立された命名パターンに従う 5. **Feature Directory Pattern検討**: 複数のコンポーネント・フック・状態が関連する場合は `features/` 配下に集約 ### ディレクトリ構造維持 - **責務単一原則**: 1ファイル = 1機能・責務 - **依存関係最小化**: 循環参照の回避 - **拡張性**: 将来の機能追加を考慮した構造 - **検索性**: ファイル名から機能が推測できる命名 ### Feature Directory Pattern 採用基準 以下の条件を満たす場合は `features/` 配下に配置: - 複数のUIコンポーネントが関連している - 専用のカスタムフックがある - 専用のJotai状態がある - 機能として独立性が高い **例**: `features/page-tree/` は SimplifiedItemsTree, TreeItemLayout, useDataLoader, page-tree-update.ts などが密接に関連 --- ## 📝 最終更新日 2025-11-28 (Feature Directory Pattern 追加)