# 機能設計書 27-プロジェクト管理

## 概要

本ドキュメントは、Liam DBシステムにおけるプロジェクト管理機能の設計を記述するものである。本機能は、GitHubリポジトリと連携したプロジェクトの作成・管理を実現する。

### 本機能の処理概要

プロジェクト管理機能は、組織内でのプロジェクト作成、一覧表示、詳細取得を提供する。プロジェクトはGitHubリポジトリと紐付けられ、スキーマファイルのパスとフォーマットを指定して作成される。

**業務上の目的・背景**：Liam DBはデータベース設計ツールであり、プロジェクト単位でスキーマを管理する。GitHubリポジトリと連携することで、バージョン管理されたスキーマファイルを基にしたデザインセッションが可能となる。

**機能の利用シーン**：
- プロジェクト一覧画面でプロジェクトを確認・選択
- 新規プロジェクト作成時にGitHubリポジトリとスキーマファイルを指定
- プロジェクト詳細画面でセッション一覧を確認

**主要な処理内容**：
1. プロジェクト作成（addProject、RPCでアトミック処理）
2. プロジェクト一覧取得（getProjects）
3. プロジェクト詳細取得（getProject）
4. プロジェクトに紐づくセッション取得（fetchProjectSessions）
5. GitHubリポジトリ一覧取得（getRepositories）

**関連システム・外部連携**：Supabase PostgreSQL、GitHub API

**権限による制御**：組織メンバーのみが該当組織のプロジェクトにアクセス可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | プロジェクト一覧画面 | 主画面 | プロジェクト一覧表示、検索、ソート |
| 7 | プロジェクト新規作成画面 | 主画面 | プロジェクト作成、リポジトリ選択 |
| 8 | プロジェクト詳細画面 | 主画面 | セッション一覧表示 |

## 機能種別

データ管理 / プロジェクト管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| projectName | string | Yes | プロジェクト名 | - |
| repositoryName | string | Yes | GitHubリポジトリ名 | - |
| repositoryOwner | string | Yes | リポジトリオーナー | - |
| installationId | string | Yes | GitHub Appインストール識別子 | number変換 |
| repositoryIdentifier | string | Yes | GitHubリポジトリID | number変換 |
| schemaFilePath | string | Yes | スキーマファイルパス | - |
| schemaFormat | string | Yes | スキーマフォーマット | - |
| organizationId | string | Yes（自動取得） | 組織ID | UUID形式 |

### 入力データソース

- フォーム入力（プロジェクト名、スキーマファイルパス）
- GitHub API（リポジトリ情報）
- Cookie（organizationId）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| project_id | string | 作成されたプロジェクトのID |
| repository_id | string | 紐づけられたリポジトリID |
| schema_file_path_id | string | スキーマファイルパスID |
| projects | Project[] | プロジェクト一覧 |
| sessions | ProjectSession[] | プロジェクトに紐づくセッション一覧 |

### 出力先

- Supabase データベース（projects、github_repositories、schema_file_paths、project_repository_mappings）

## 処理フロー

### 処理シーケンス

```
1. プロジェクト一覧画面
   └─ getCurrentOrganization(organizationId)
   └─ getProjects(organization.id)
   └─ 一覧表示
2. プロジェクト作成
   └─ getOrganizationId() で組織ID取得
   └─ addProject (Server Action)
   └─ add_project RPC（アトミック）
   └─ redirect /projects/{projectId}
3. プロジェクト詳細
   └─ getProject(projectId)
   └─ fetchProjectSessions(projectId)
   └─ セッション一覧表示
```

### フローチャート

```mermaid
flowchart TD
    A[プロジェクト一覧] --> B[getCurrentOrganization]
    B --> C[getProjects]
    C --> D{プロジェクト存在?}
    D -->|Yes| E[ProjectsListView]
    D -->|No| F[NoProjects]
    F --> G[新規作成へ誘導]

    H[新規作成フォーム] --> I[リポジトリ選択]
    I --> J[getRepositories]
    J --> K[スキーマファイル設定]
    K --> L[addProject]
    L --> M[add_project RPC]
    M --> N[redirect プロジェクト詳細]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-27-01 | 組織スコープ | プロジェクトは組織に紐づく | 全操作 |
| BR-27-02 | GitHub連携必須 | プロジェクト作成時にリポジトリを指定 | 作成時 |
| BR-27-03 | アトミック作成 | プロジェクト関連レコードはRPCでアトミックに作成 | 作成時 |
| BR-27-04 | ID降順ソート | プロジェクト一覧はID降順（新しい順） | 一覧取得 |

### 計算ロジック

- セッション取得制限: デフォルト limit = 10

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| addProject | - | RPC | add_project |
| getProjects | projects, project_repository_mappings, github_repositories | SELECT | 一覧取得 |
| getProject | projects | SELECT | 詳細取得 |
| fetchProjectSessions | design_sessions | SELECT | セッション取得 |

### テーブル別操作詳細

#### projects

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, name, created_at, updated_at, organization_id | organization_id フィルタ | 一覧取得 |
| SELECT | id, name | id = projectId | 詳細取得 |

#### project_repository_mappings

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT (JOIN) | repository | projects との結合 | 一覧取得 |

#### github_repositories

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT (JOIN) | id, name, owner, github_installation_identifier | project_repository_mappings 経由 | 一覧取得 |

#### design_sessions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, name, created_at, project_id | project_id, created_by_user_id | セッション取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| org_not_found | 組織未取得エラー | getOrganizationId 失敗 | エラーメッセージ返却 |
| create_failed | 作成エラー | add_project RPC 失敗 | エラーメッセージ返却 |
| invalid_response | レスポンスエラー | RPC レスポンス検証失敗 | エラーメッセージ返却 |
| fetch_repos_failed | リポジトリ取得エラー | GitHub API 失敗 | エラーメッセージ返却 |

### リトライ仕様

- プロジェクト作成失敗時はユーザーに再試行を促す
- GitHub API 失敗時はエラー表示

## トランザクション仕様

- addProject: `add_project` RPC でアトミック処理（projects、github_repositories、schema_file_paths、project_repository_mappings を一括作成）

## パフォーマンス要件

- getProjects: organization_id でインデックス検索、JOIN でリポジトリ情報取得
- fetchProjectSessions: project_id + created_by_user_id でインデックス検索、limit 10

## セキュリティ考慮事項

- Row Level Security (RLS) で組織単位のアクセス制御
- 認証ユーザーのみセッション取得可能（created_by_user_id チェック）

## 備考

add_project RPC の実装はデータベース側に存在する。複数テーブルへの INSERT をトランザクション内でアトミックに実行する。

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: プロジェクト一覧の仕組みを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ProjectsPage.tsx | `frontend/apps/app/components/ProjectsPage/ProjectsPage.tsx` | 一覧ページ全体構造 |
| 1-2 | getProjects.ts | `frontend/apps/app/components/ProjectsPage/services/getProjects.ts` | プロジェクト取得 |
| 1-3 | getCurrentOrganization.ts | `frontend/apps/app/components/ProjectsPage/services/getCurrentOrganization.ts` | 現在組織取得 |

**主要処理フロー**:
- **16-48行目（ProjectsPage.tsx）**: 組織取得 → プロジェクト取得 → 表示
- **3-37行目（getProjects.ts）**: JOIN でリポジトリ情報含めて取得

#### Step 2: プロジェクト作成フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | addProject.ts | `frontend/apps/app/components/ProjectNewPage/actions/addProject.ts` | プロジェクト作成 Server Action |
| 2-2 | getRepositories.ts | `frontend/apps/app/components/ProjectNewPage/components/InstallationSelector/actions/getRepositories.ts` | リポジトリ取得 |

**主要処理フロー**:
- **28-90行目（addProject.ts）**: フォームデータ取得 → 組織ID取得 → RPC呼び出し → リダイレクト
- **52-61行目**: add_project RPC 呼び出しパラメータ
- **19-49行目（getRepositories.ts）**: GitHub API 経由でリポジトリ取得

#### Step 3: プロジェクト詳細とセッション取得を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | getProject.ts | `frontend/apps/app/components/CommonLayout/AppBar/ProjectsDropdownMenu/services/getProject.ts` | プロジェクト詳細取得 |
| 3-2 | fetchProjectSessions.ts | `frontend/apps/app/components/ProjectSessionsPage/services/fetchProjectSessions.ts` | セッション一覧取得 |

**主要処理フロー**:
- **4-12行目（getProject.ts）**: id で single 取得
- **10-37行目（fetchProjectSessions.ts）**: project_id + created_by_user_id でフィルタ、limit 適用

#### Step 4: GitHubコミット情報取得を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | fetchLastCommitData.ts | `frontend/apps/app/components/ProjectsPage/services/fetchLastCommitData.ts` | 最終コミット取得 |

**主要処理フロー**:
- **6-25行目**: GitHub API 経由で最終コミット情報取得

### プログラム呼び出し階層図

```
[プロジェクト一覧]
ProjectsPage
    │
    ├─ getCurrentOrganization
    │      └─ supabase.from('organization_members').select
    │
    ├─ getProjects
    │      └─ supabase.from('projects').select
    │             └─ JOIN project_repository_mappings
    │                    └─ JOIN github_repositories
    │
    └─ ServerProjectsDataProvider
           └─ ProjectsListView
                  └─ fetchLastCommitData

[プロジェクト作成]
addProject (Server Action)
    │
    ├─ getOrganizationId
    │      └─ Cookie or Database
    │
    ├─ supabase.rpc('add_project')
    │      └─ アトミック INSERT
    │             ├─ projects
    │             ├─ github_repositories
    │             ├─ schema_file_paths
    │             └─ project_repository_mappings
    │
    └─ redirect(/projects/{projectId})

[リポジトリ取得]
getRepositories (Server Action)
    │
    └─ getRepositoriesByInstallationId
           └─ GitHub API
```

### データフロー図

```
[プロジェクト作成フロー]
フォーム入力 ─────────────▶ addProject
       │                        │
       │  projectName           │
       │  repositoryName        │
       │  repositoryOwner       │
       │  installationId        │
       │  repositoryIdentifier  │
       │  schemaFilePath        │
       │  schemaFormat          │
       │                        │
       ├─ getOrganizationId ───▶ organizationId
       │                        │
       └───────────────────────▶ supabase.rpc('add_project')
                                       │
                                       ├─ project_id
                                       ├─ repository_id
                                       └─ schema_file_path_id
                                              │
                                              ▼
                                       redirect /projects/{projectId}

[プロジェクト一覧取得フロー]
organizationId ────────────▶ getProjects
       │                        │
       │                        ├─ projects SELECT
       │                        │
       │                        ├─ JOIN project_repository_mappings
       │                        │
       │                        └─ JOIN github_repositories
       │                               │
       └───────────────────────────────▶ projects[]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| addProject.ts | `frontend/apps/app/components/ProjectNewPage/actions/addProject.ts` | ソース | プロジェクト作成 |
| getProjects.ts | `frontend/apps/app/components/ProjectsPage/services/getProjects.ts` | ソース | プロジェクト一覧取得 |
| getProject.ts | `frontend/apps/app/components/CommonLayout/AppBar/ProjectsDropdownMenu/services/getProject.ts` | ソース | プロジェクト詳細取得 |
| getCurrentOrganization.ts | `frontend/apps/app/components/ProjectsPage/services/getCurrentOrganization.ts` | ソース | 現在組織取得 |
| fetchProjectSessions.ts | `frontend/apps/app/components/ProjectSessionsPage/services/fetchProjectSessions.ts` | ソース | セッション一覧取得 |
| fetchLastCommitData.ts | `frontend/apps/app/components/ProjectsPage/services/fetchLastCommitData.ts` | ソース | 最終コミット取得 |
| getRepositories.ts | `frontend/apps/app/components/ProjectNewPage/components/InstallationSelector/actions/getRepositories.ts` | ソース | リポジトリ取得 |
| ProjectsPage.tsx | `frontend/apps/app/components/ProjectsPage/ProjectsPage.tsx` | ソース | プロジェクト一覧画面 |
| types.ts | `frontend/apps/app/components/ProjectsPage/types.ts` | 型定義 | プロジェクト型 |
