# ナレッジベースの強化機能設計 ## 🎯 機能概要 今回の開発には、以下の3つのコア機能が含まれます: 1. **ナレッジベースのグループ化** - グループを作成し、ドキュメントを複数のグループに所属させ、検索時にグループを指定可能にします。 2. **検索履歴** - 対話プロセス全体を保存し、過去の会話の閲覧や再開を可能にします。 3. **PDF プレビュー** - すべてのファイルを PDF 形式に変換し、オンラインでプレビューできるようにします。 ## 🗄️ データベース設計 ### 新規テーブル構造 ```sql -- ナレッジベースグループ管理テーブル CREATE TABLE knowledge_groups ( id TEXT PRIMARY KEY, name TEXT NOT NULL, description TEXT, color TEXT DEFAULT '#3B82F6', -- グループの色分けID user_id TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- ドキュメント・グループ関連付けテーブル (多対多) CREATE TABLE knowledge_base_groups ( knowledge_base_id TEXT NOT NULL, group_id TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (knowledge_base_id, group_id), FOREIGN KEY (knowledge_base_id) REFERENCES knowledge_base(id) ON DELETE CASCADE, FOREIGN KEY (group_id) REFERENCES knowledge_groups(id) ON DELETE CASCADE ); -- 検索履歴テーブル CREATE TABLE search_history ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, title TEXT NOT NULL, -- 対話タイトル (質問の先頭50文字) selected_groups TEXT, -- JSON配列: ["group1", "group2"] または null(すべて) created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 対話メッセージテーブル CREATE TABLE chat_messages ( id TEXT PRIMARY KEY, search_history_id TEXT NOT NULL, role TEXT NOT NULL CHECK (role IN ('user', 'assistant')), content TEXT NOT NULL, sources TEXT, -- JSON配列: 引用ソース情報 created_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (search_history_id) REFERENCES search_history(id) ON DELETE CASCADE ); ``` ### 既存テーブルの修正 ```sql -- knowledge_base テーブルに PDF パスフィールドを追加 ALTER TABLE knowledge_base ADD COLUMN pdf_path TEXT; ``` ## 🔌 API エンドポイント設計 ### ナレッジベースグループ API ```typescript // ユーザーの全グループを取得 GET /api/knowledge-groups Response: { groups: Array<{ id: string; name: string; description?: string; color: string; fileCount: number; // 含まれるファイル数 createdAt: string; }> } // グループの作成 POST /api/knowledge-groups Body: { name: string; description?: string; color?: string } Response: { id: string; name: string; description?: string; color: string } // グループの更新 PUT /api/knowledge-groups/:id Body: { name?: string; description?: string; color?: string } // グループの削除 DELETE /api/knowledge-groups/:id // グループ内のファイルを取得 GET /api/knowledge-groups/:id/files Response: { files: KnowledgeBase[] } // ファイルをグループに追加 POST /api/knowledge-bases/:fileId/groups Body: { groupIds: string[] } // グループからファイルを削除 DELETE /api/knowledge-bases/:fileId/groups/:groupId ``` ### 検索履歴 API ```typescript // 検索履歴の取得 (ページネーション) GET /api/search-history?page=1&limit=20 Response: { histories: Array<{ id: string; title: string; selectedGroups: string[] | null; messageCount: number; lastMessageAt: string; createdAt: string; }>; total: number; page: number; limit: number; } // 対話詳細の取得 GET /api/search-history/:id Response: { id: string; title: string; selectedGroups: string[] | null; messages: Array<{ id: string; role: 'user' | 'assistant'; content: string; sources?: Array<{ fileName: string; content: string; score: number; chunkIndex: number; }>; createdAt: string; }>; } // 新しい対話の作成 POST /api/search-history Body: { title: string; selectedGroups?: string[]; firstMessage: string; } Response: { id: string } // 対話の削除 DELETE /api/search-history/:id // 対話の継続 (既存のチャットインターフェースを拡張し、historyId パラメータを追加) POST /api/chat/stream Body: { message: string; history: ChatMessage[]; userLanguage?: string; selectedGroups?: string[]; // 新規:選択されたグループ historyId?: string; // 新規:対話履歴ID } ``` ### PDF プレビュー API ```typescript // ファイルの PDF プレビューを取得 GET /api/knowledge-bases/:id/pdf Response: PDF ファイルストリーム、または PDF URL へのリダイレクト // PDF ステータスの確認 GET /api/knowledge-bases/:id/pdf-status Response: { status: 'pending' | 'converting' | 'ready' | 'failed'; pdfPath?: string; error?: string; } ``` ## 🎨 フロントエンドコンポーネント設計 ### 1. ナレッジベースグループコンポーネント ```typescript // グループマネージャー interface GroupManagerProps { groups: KnowledgeGroup[]; onCreateGroup: (group: CreateGroupData) => void; onUpdateGroup: (id: string, data: UpdateGroupData) => void; onDeleteGroup: (id: string) => void; } // グループセレクター (検索時の選択用) interface GroupSelectorProps { groups: KnowledgeGroup[]; selectedGroups: string[]; onSelectionChange: (groupIds: string[]) => void; showSelectAll?: boolean; } // ファイルグループタグ interface FileGroupTagsProps { fileId: string; groups: KnowledgeGroup[]; assignedGroups: string[]; onGroupsChange: (groupIds: string[]) => void; } ``` ### 2. 検索履歴コンポーネント ```typescript // 履歴リスト interface SearchHistoryListProps { histories: SearchHistoryItem[]; onSelectHistory: (historyId: string) => void; onDeleteHistory: (historyId: string) => void; onLoadMore: () => void; hasMore: boolean; } // 履歴対話ビューアー interface HistoryViewerProps { historyId: string; onContinueChat: (historyId: string) => void; onClose: () => void; } ``` ### 3. PDF プレビューコンポーネント ```typescript // PDF プレビューアー interface PDFPreviewProps { fileId: string; fileName: string; onClose: () => void; } // PDF プレビューボタン interface PDFPreviewButtonProps { fileId: string; fileName: string; status: 'pending' | 'converting' | 'ready' | 'failed'; } ``` ## 🔄 ビジネスフロー設計 ### ナレッジベースグループ化フロー ``` 1. ユーザーがグループを作成 → knowledge_groups テーブルに保存 2. ファイルアップロード時 → グループを選択可能 → knowledge_base_groups テーブルに関連付けを保存 3. 検索時 → グループを選択 → Elasticsearch のクエリ範囲をフィルタリング 4. ファイル管理 → ファイルの所属グループを編集可能 ``` ### 検索履歴フロー ``` 1. ユーザーがチャットを開始 → search_history データを生成 2. 各メッセージ → chat_messages テーブルに保存 3. 履歴の確認 → 履歴リストをページネーションでロード 4. 履歴をクリック → 対話内容全体をロード 5. 対話の継続 → 既存の履歴をベースに新しいメッセージを追加 ``` ### PDF プレビューフロー ``` 1. ファイルアップロード → PDF かどうかを確認 2. PDF 以外の場合 → LibreOffice を呼び出して PDF に変換 3. PDF パスを knowledge_base.pdf_path に保存 4. フロントエンドからプレビューをリクエスト → PDF ファイルストリームを返却 5. HTML の または