|
| 1 | +# データベース分離設計書 |
| 2 | + |
| 3 | +## 1. 概要 |
| 4 | + |
| 5 | +### 1.1 目的 |
| 6 | +タスク情報の永続化層をSQLiteからPostgreSQLに移行し、SQLAlchemyを使用してデータベースアクセスを汎用化する。 |
| 7 | + |
| 8 | +### 1.2 対象範囲 |
| 9 | +- **タスク情報DB(tasksテーブル)のみ**を対象とする |
| 10 | +- メッセージ履歴、要約履歴、ツール実行履歴(JSONLファイル)は対象外 |
| 11 | + |
| 12 | +### 1.3 TaskKey構造の分析 |
| 13 | +現在のTaskKeyは以下の4種類があり、それぞれ異なるフィールドを持つ: |
| 14 | + |
| 15 | +| TaskKey種別 | task_source | task_type | owner | repo | project_id | number | |
| 16 | +|------------|-------------|-----------|-------|------|------------|--------| |
| 17 | +| GitHubIssueTaskKey | github | issue | ○ | ○ | - | ○ | |
| 18 | +| GitHubPullRequestTaskKey | github | pull_request | ○ | ○ | - | ○ | |
| 19 | +| GitLabIssueTaskKey | gitlab | issue | - | - | ○ | ○(issue_iid) | |
| 20 | +| GitLabMergeRequestTaskKey | gitlab | merge_request | - | - | ○ | ○(mr_iid) | |
| 21 | + |
| 22 | +これらを統一的に扱うため、以下のフィールド構成でtask_keyを分解する: |
| 23 | +- `task_source`: タスクソース(github/gitlab) |
| 24 | +- `task_type`: タスクタイプ(issue/pull_request/merge_request) |
| 25 | +- `owner`: GitHubリポジトリオーナー(GitLabの場合はNULL) |
| 26 | +- `repo`: GitHubリポジトリ名(GitLabの場合はNULL) |
| 27 | +- `project_id`: GitLabプロジェクトID(GitHubの場合はNULL) |
| 28 | +- `number`: タスク番号(GitHub: number、GitLab: issue_iid/mr_iid) |
| 29 | + |
| 30 | +--- |
| 31 | + |
| 32 | +## 2. 詳細設計 |
| 33 | + |
| 34 | +### 2.1 ファイル構成 |
| 35 | +1ファイルにDBTaskモデルとDBアクセスロジックをまとめる: |
| 36 | + |
| 37 | +``` |
| 38 | +db/ |
| 39 | +└── task_db.py # DBTaskモデル定義 + TaskDBManagerクラス |
| 40 | +``` |
| 41 | + |
| 42 | +### 2.2 task_db.py の設計 |
| 43 | + |
| 44 | +#### 2.2.1 DBTask モデル |
| 45 | +SQLAlchemy ORMを使用してtasksテーブルを定義する。 |
| 46 | + |
| 47 | +**処理内容**: |
| 48 | +- SQLAlchemy 2.0スタイルの宣言的ベースクラスを使用する |
| 49 | +- PostgreSQL用の型定義を行う |
| 50 | +- task_key分解フィールドのインデックスを定義する |
| 51 | +- `get_task_key()` メソッドでTaskKeyオブジェクトを復元する |
| 52 | + |
| 53 | +**カラム定義**: |
| 54 | +| カラム名 | 型 | PostgreSQL型 | 制約 | 説明 | |
| 55 | +|---------|-----|-------------|------|------| |
| 56 | +| uuid | String(36) | VARCHAR(36) | PRIMARY KEY | タスク一意識別子 | |
| 57 | +| task_source | String(50) | VARCHAR(50) | NOT NULL | タスクソース(github/gitlab) | |
| 58 | +| task_type | String(50) | VARCHAR(50) | NOT NULL | タスクタイプ(issue/pull_request/merge_request) | |
| 59 | +| owner | String(255) | VARCHAR(255) | NULL可 | GitHubリポジトリオーナー | |
| 60 | +| repo | String(255) | VARCHAR(255) | NULL可 | GitHubリポジトリ名 | |
| 61 | +| project_id | Integer | INTEGER | NULL可 | GitLabプロジェクトID | |
| 62 | +| number | Integer | INTEGER | NOT NULL | タスク番号 | |
| 63 | +| status | String(20) | VARCHAR(20) | NOT NULL | ステータス | |
| 64 | +| created_at | DateTime | TIMESTAMP WITH TIME ZONE | NOT NULL | 作成日時 | |
| 65 | +| started_at | DateTime | TIMESTAMP WITH TIME ZONE | - | 開始日時 | |
| 66 | +| completed_at | DateTime | TIMESTAMP WITH TIME ZONE | - | 完了日時 | |
| 67 | +| process_id | Integer | INTEGER | - | プロセスID | |
| 68 | +| hostname | String(255) | VARCHAR(255) | - | ホスト名 | |
| 69 | +| llm_provider | String(50) | VARCHAR(50) | - | LLMプロバイダー | |
| 70 | +| model | String(100) | VARCHAR(100) | - | 使用モデル | |
| 71 | +| context_length | Integer | INTEGER | - | コンテキスト長 | |
| 72 | +| llm_call_count | Integer | INTEGER | DEFAULT 0 | LLM呼び出し回数 | |
| 73 | +| tool_call_count | Integer | INTEGER | DEFAULT 0 | ツール呼び出し回数 | |
| 74 | +| total_tokens | Integer | INTEGER | DEFAULT 0 | 総トークン数 | |
| 75 | +| compression_count | Integer | INTEGER | DEFAULT 0 | 圧縮回数 | |
| 76 | +| error_message | Text | TEXT | - | エラーメッセージ | |
| 77 | +| user | String(255) | VARCHAR(255) | - | ユーザー名 | |
| 78 | + |
| 79 | +**インデックス定義**: |
| 80 | +| インデックス名 | カラム | 用途 | |
| 81 | +|--------------|--------|------| |
| 82 | +| ix_tasks_status | status | ステータス別検索の高速化 | |
| 83 | +| ix_tasks_created_at | created_at | 作成日時順ソートの高速化 | |
| 84 | +| ix_tasks_user | user | ユーザー別検索の高速化 | |
| 85 | +| ix_tasks_task_key | task_source, task_type, owner, repo, project_id, number | TaskKey検索の高速化 | |
| 86 | + |
| 87 | +**DBTaskモデルのメソッド**: |
| 88 | +| メソッド名 | 引数 | 戻り値 | 説明 | |
| 89 | +|-----------|------|--------|------| |
| 90 | +| get_task_key | - | TaskKey | task_key分解フィールドからTaskKeyオブジェクトを復元する | |
| 91 | + |
| 92 | +#### 2.2.2 TaskDBManager クラス |
| 93 | +タスクのDB操作を行うロジッククラスを実装する。 |
| 94 | + |
| 95 | +**初期化処理**: |
| 96 | +- 環境変数またはconfig.yamlからPostgreSQL接続情報を取得する |
| 97 | +- SQLAlchemyエンジンを作成する |
| 98 | +- セッションファクトリーを初期化する |
| 99 | + |
| 100 | +**接続設定**: |
| 101 | +| 環境変数名 | 説明 | デフォルト値 | |
| 102 | +|-----------|------|------------| |
| 103 | +| DATABASE_HOST | PostgreSQLホスト | localhost | |
| 104 | +| DATABASE_PORT | PostgreSQLポート | 5432 | |
| 105 | +| DATABASE_NAME | データベース名 | coding_agent | |
| 106 | +| DATABASE_USER | ユーザー名 | - | |
| 107 | +| DATABASE_PASSWORD | パスワード | - | |
| 108 | +| DATABASE_URL | 完全な接続URL(他設定を上書き) | - | |
| 109 | + |
| 110 | +**メソッド定義**: |
| 111 | + |
| 112 | +| メソッド名 | 引数 | 戻り値 | 説明 | |
| 113 | +|-----------|------|--------|------| |
| 114 | +| create_task | task_data: dict | DBTask | 新規タスクを作成し、DBにINSERTする | |
| 115 | +| create_task_from_task | task: Task | DBTask | Taskオブジェクトから新規タスクを作成し、DBにINSERTする | |
| 116 | +| get_task | uuid: str | DBTask または None | UUIDでタスクを取得する | |
| 117 | +| get_task_by_key | task_key: TaskKey | DBTask または None | TaskKeyでタスクを取得する | |
| 118 | +| save_task | db_task: DBTask | DBTask | DBTaskオブジェクトを保存(更新)する | |
| 119 | + |
| 120 | +**処理内容**: |
| 121 | +- セッション管理をコンテキストマネージャーで自動化する |
| 122 | +- 例外発生時の自動ロールバックを実装する |
| 123 | +- ログ出力によるデバッグ支援を提供する |
| 124 | + |
| 125 | +### 2.3 既存コード修正設計 |
| 126 | + |
| 127 | +#### 2.3.1 TaskContextManager の修正(context_storage/task_context_manager.py) |
| 128 | +現在のSQLite直接操作を、TaskDBManagerクラスを使用したアクセスに変更する。 |
| 129 | + |
| 130 | +**修正対象メソッド**: |
| 131 | +| メソッド | 修正内容 | |
| 132 | +|---------|---------| |
| 133 | +| `__init__` | TaskDBManagerクラスのインスタンスを作成する | |
| 134 | +| `_init_database` | 削除。初期化はTaskDBManagerクラスで行う | |
| 135 | +| `_register_or_update_task` | TaskDBManager.create_task または TaskDBManager.save_task を使用する | |
| 136 | +| `update_status` | DBTaskオブジェクトを取得し、ステータスを変更後、save_taskを使用する | |
| 137 | +| `update_statistics` | DBTaskオブジェクトを取得し、統計情報を更新後、save_taskを使用する | |
| 138 | +| `complete` | DBTaskオブジェクトを取得し、完了状態に変更後、save_taskを使用する | |
| 139 | +| `stop` | DBTaskオブジェクトを取得し、停止状態に変更後、save_taskを使用する | |
| 140 | +| `fail` | DBTaskオブジェクトを取得し、失敗状態に変更後、save_taskを使用する | |
| 141 | + |
| 142 | +### 2.4 設定ファイル設計 |
| 143 | + |
| 144 | +#### 2.4.1 config.yaml への追加 |
| 145 | +以下の設定セクションを追加する: |
| 146 | + |
| 147 | +```yaml |
| 148 | +# データベース設定 |
| 149 | +database: |
| 150 | + # PostgreSQL設定 |
| 151 | + host: "localhost" |
| 152 | + port: 5432 |
| 153 | + name: "coding_agent" |
| 154 | + user: "" |
| 155 | + password: "" |
| 156 | + |
| 157 | + # コネクションプール設定 |
| 158 | + pool_size: 5 |
| 159 | + max_overflow: 10 |
| 160 | +``` |
| 161 | +
|
| 162 | +### 2.5 DB作成ツール |
| 163 | +データベースとテーブルを作成するコマンドラインツールを提供する。 |
| 164 | +
|
| 165 | +**ファイル**: `scripts/create_db.py` |
| 166 | + |
| 167 | +**処理内容**: |
| 168 | +- PostgreSQLに接続する |
| 169 | +- tasksテーブルが存在しない場合は作成する |
| 170 | +- インデックスを作成する |
| 171 | + |
| 172 | +**使用方法**: |
| 173 | +```bash |
| 174 | +python scripts/create_db.py |
| 175 | +``` |
| 176 | + |
| 177 | +--- |
| 178 | + |
| 179 | +## 3. Docker環境設計 |
| 180 | + |
| 181 | +### 3.1 docker-compose.yml への追加 |
| 182 | +PostgreSQLコンテナを追加する。 |
| 183 | + |
| 184 | +**サービス定義**: |
| 185 | +- サービス名: `postgres` |
| 186 | +- イメージ: `postgres:16` |
| 187 | +- ボリューム: データ永続化用ボリューム |
| 188 | +- 環境変数: DB名、ユーザー名、パスワード |
| 189 | +- ヘルスチェック: pg_isready コマンド |
| 190 | + |
| 191 | +### 3.2 依存関係設定 |
| 192 | +既存のサービス(producer、consumer等)にPostgreSQLへの依存を追加する。 |
| 193 | + |
| 194 | +**処理内容**: |
| 195 | +- `depends_on` に postgres サービスを追加する |
| 196 | +- ヘルスチェック完了を待機する設定を追加する |
| 197 | + |
| 198 | +--- |
| 199 | + |
| 200 | +## 4. 依存関係 |
| 201 | + |
| 202 | +### 4.1 追加パッケージ |
| 203 | +以下のパッケージを追加する: |
| 204 | + |
| 205 | +| パッケージ名 | バージョン | 用途 | |
| 206 | +|-------------|----------|------| |
| 207 | +| sqlalchemy | >=2.0.0 | ORM・DB抽象化 | |
| 208 | +| psycopg2-binary | >=2.9.0 | PostgreSQLドライバ | |
| 209 | + |
| 210 | +### 4.2 pyproject.toml / condaenv.yaml への追加 |
| 211 | +上記パッケージを依存関係に追加する。 |
| 212 | + |
| 213 | +--- |
| 214 | + |
| 215 | +## 5. 影響範囲 |
| 216 | + |
| 217 | +### 5.1 修正対象ファイル |
| 218 | +| ファイル | 修正内容 | |
| 219 | +|---------|---------| |
| 220 | +| context_storage/task_context_manager.py | DB操作をTaskDBManagerクラス経由に変更 | |
| 221 | +| config.yaml | database セクションを追加 | |
| 222 | +| docker-compose.yml | postgres サービスを追加 | |
| 223 | +| pyproject.toml | 依存パッケージを追加 | |
| 224 | +| condaenv.yaml | 依存パッケージを追加 | |
| 225 | + |
| 226 | +### 5.2 新規作成ファイル |
| 227 | +| ファイル | 内容 | |
| 228 | +|---------|------| |
| 229 | +| db/task_db.py | DBTaskモデル + TaskDBManagerクラス | |
| 230 | +| scripts/create_db.py | DB作成ツール | |
| 231 | + |
| 232 | +--- |
| 233 | + |
| 234 | +## 6. 用語集 |
| 235 | + |
| 236 | +| 用語 | 説明 | |
| 237 | +|------|------| |
| 238 | +| ORM | Object-Relational Mapping。オブジェクトとリレーショナルデータベースの間のマッピング | |
| 239 | +| コネクションプール | データベース接続を再利用するための接続プール | |
0 commit comments