データベース設計

ERD概要

users
├── id (UUID, PK)
├── name (VARCHAR)
├── email (VARCHAR, UNIQUE)
├── role (ENUM: admin, employee)
├── password_hash (VARCHAR)
├── is_active (BOOLEAN, DEFAULT true)
├── must_change_password (BOOLEAN, DEFAULT true)  ← 初回ログイン強制変更フラグ
├── created_at (TIMESTAMP)
└── updated_at (TIMESTAMP)

categories
├── id (UUID, PK)
├── name (VARCHAR)
├── description (TEXT)
├── is_restricted (BOOLEAN, DEFAULT false)  ← 将来のアクセス制御拡張ポイント
├── created_at (TIMESTAMP)
└── updated_at (TIMESTAMP)

documents
├── id (UUID, PK)
├── title (VARCHAR)
├── category_id (FK → categories.id)
├── current_version_id (FK → document_versions.id, nullable)
├── created_by (FK → users.id)
├── created_at (TIMESTAMP)
└── updated_at (TIMESTAMP)

document_versions
├── id (UUID, PK)
├── document_id (FK → documents.id)
├── content (TEXT)                      -- 抽出済みテキスト
├── content_tsv (TSVECTOR)              -- PostgreSQL全文検索用(GIN index)
├── file_path (VARCHAR)                 -- UUID形式の相対パス(絶対パス禁止)
├── file_type (ENUM: pdf, docx, xlsx, text)
├── version_no (INTEGER)
├── change_summary (TEXT)               -- 変更概要(任意)
├── ingestion_status (ENUM: pending, processing, completed, failed)  ← 追加
├── ingestion_error_message (TEXT, nullable)  ← 追加
├── created_by (FK → users.id)
├── created_at (TIMESTAMP)
└── updated_at (TIMESTAMP)

chat_sessions
├── id (UUID, PK)
├── user_id (FK → users.id)
├── title (VARCHAR, nullable)           -- セッション一覧表示用(最初の質問から自動生成)
├── created_at (TIMESTAMP)
└── updated_at (TIMESTAMP)

chat_messages
├── id (UUID, PK)
├── session_id (FK → chat_sessions.id)
├── role (ENUM: user, assistant)
├── content (TEXT)                      -- テキスト回答
├── mermaid_content (TEXT, nullable)    -- Mermaid図(別カラムで保存)
├── sources_json (JSONB, nullable)      -- 引用元情報
├── created_at (TIMESTAMP)
└── updated_at (TIMESTAMP)

audit_logs                              ← 新規追加(監査・コンプライアンス対応)
├── id (UUID, PK)
├── user_id (FK → users.id, nullable)  -- 未ログイン操作も記録可
├── action (ENUM: login, logout, document_view, document_upload,
│                document_update, document_delete, chat_query, user_create,
│                user_update, user_delete, version_restore)
│                -- document_view は任意記録(大量ログ懸念あり・Phase 4 実装時に要否判断)
├── target_id (UUID, nullable)          -- 操作対象のリソースID
├── target_type (VARCHAR, nullable)     -- 'document' / 'user' / 'category' 等
├── ip_address (VARCHAR)
├── created_at (TIMESTAMP)
└── (updated_atなし:監査ログは不変)

revoked_tokens ← ログアウト時の Refresh Token 即時無効化テーブル

├── id (UUID, PK)
├── token_hash (VARCHAR, UNIQUE)        -- SHA-256 ハッシュ値を格納(生トークンは保存しない)
├── expired_at (TIMESTAMP)             -- トークン自体の有効期限(定期クリーンアップ基準)
└── created_at (TIMESTAMP)

採用方針: revoked_tokens テーブルによる即時無効化 ログアウト時に Refresh Token のハッシュを記録し、/auth/refresh 呼び出し時に照合する。 ログアウト後 60 分以内の再利用を防止できる。

別方針(不採用): Cookie クリアのみ ログアウト時に Cookie を削除するだけ。実装は最もシンプルだが、 盗まれた Refresh Token が有効期限(7日)まで使用可能なリスクが残るため不採用とした。

インデックス設計:

  • document_versions.content_tsv に GIN インデックス(全文検索高速化)
  • audit_logs.user_id, audit_logs.created_at に複合インデックス
  • chat_messages.session_id にインデックス
  • revoked_tokens.token_hash に UNIQUE インデックス(照合の高速化)
  • revoked_tokens.expired_at にインデックス(期限切れレコードの定期クリーンアップ用)

APIエンドポイント設計

システム

MethodPath説明権限
GET/health全コンポーネント疎通確認(DB・ChromaDB・Ollama)-

認証

MethodPath説明権限
POST/auth/login認証 → JWTをHttpOnly Cookieにセット-
POST/auth/logoutCookieクリア(トークン無効化)全員
POST/auth/refreshRefresh TokenでAccess Token更新全員
GET/auth/me現在ユーザー情報(must_change_passwordフラグ含む)全員
POST/auth/reset-password対象ユーザーのパスワードをリセット(admin専用)admin

カテゴリ

MethodPath説明権限
GET/categories一覧取得全員
POST/categories新規作成admin
PUT/categories/{id}更新admin
DELETE/categories/{id}削除(紐づくドキュメントがある場合はエラー)admin

ドキュメント

MethodPath説明権限
GET/documents一覧取得(カテゴリフィルタ・キーワード検索)全員
POST/documents新規登録(multipart/form-dataadmin
GET/documents/{id}詳細取得(ingestion_status含む)全員
PUT/documents/{id}更新(新バージョン作成)admin
DELETE/documents/{id}論理削除 + ChromaDB整合的削除admin
GET/documents/{id}/versionsバージョン履歴一覧全員
POST/documents/{id}/restore/{version_id}バージョン復元(旧チャンク削除 + 再Ingestion)admin
POST/documents/{id}/retry-ingestionIngestion再実行(failed 状態のバージョンのみ受付)admin

ユーザー管理

MethodPath説明権限
GET/users一覧取得admin
POST/users新規作成(must_change_password=trueで作成)admin
PUT/users/{id}更新(ロール変更・有効/無効切替)admin
DELETE/users/{id}削除(自分自身は不可)admin

チャット

MethodPath説明権限
POST/chat質問 → RAG → 構造化レスポンス全員
GET/chat/sessionsセッション一覧取得全員
GET/chat/sessions/{session_id}セッション内の会話履歴取得全員