# 画面設計書 7-プロジェクト一覧画面

## 概要

本ドキュメントは、Liam DBアプリケーションのプロジェクト一覧画面について定義する。

### 本画面の処理概要

プロジェクト一覧画面は、現在選択されている組織に所属するプロジェクトの一覧を表示する画面である。プロジェクトを選択して詳細画面へ遷移したり、新規プロジェクトを作成することができる。

**業務上の目的・背景**：Liam DBでは組織内のプロジェクト単位でデータベーススキーマを管理する。この画面では組織内のすべてのプロジェクトを一覧表示し、ユーザーが作業対象のプロジェクトを選択できるようにする。GitHubリポジトリと連携したプロジェクト管理の起点となる画面である。

**画面へのアクセス方法**：
- 組織一覧画面から組織を選択
- グローバルナビゲーションから「Projects」を選択
- 直接`/projects`にアクセス

**主要な操作・処理内容**：
1. 現在の組織IDを取得（Cookie またはデータベース）
2. 組織に紐づくプロジェクト一覧を取得・表示
3. プロジェクトカードをクリックしてプロジェクト詳細画面へ遷移
4. 「Add New Project」ボタンでプロジェクト新規作成画面へ遷移
5. プロジェクトが存在しない場合は空状態メッセージを表示

**画面遷移**：
- プロジェクト選択時 → プロジェクト詳細画面（`/projects/[projectId]`）
- 新規プロジェクト作成クリック時 → プロジェクト新規作成画面（`/projects/new`）
- 未認証時 → ログイン画面（`/login`）

**権限による表示制御**：認証必須。組織メンバーのみがその組織のプロジェクトを閲覧可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 27 | プロジェクト管理 | 主機能 | 組織内のプロジェクト一覧を取得・表示 |
| 25 | ユーザー認証 | 補助機能 | 認証状態の確認と未認証時のリダイレクト |
| 39 | Supabaseクライアント | API連携 | プロジェクトデータの取得 |

## 画面種別

一覧

## URL/ルーティング

- URL: `/projects`
- ファイル: `frontend/apps/app/app/projects/page.tsx`
- レンダリング: サーバーコンポーネント

## 入出力項目

なし（入力項目はない）

## 表示項目

| 項目名 | 説明 | 備考 |
|--------|------|------|
| ページタイトル | "Projects" | h1要素 |
| プロジェクトカード | プロジェクト情報を表示するカード | 複数表示、クリックで詳細へ |
| プロジェクト名 | 各プロジェクトの名称 | - |
| リポジトリ情報 | GitHubリポジトリ名・オーナー | - |
| 作成日時 | プロジェクト作成日時 | - |
| 新規作成ボタン | "Add New Project" | プロジェクト新規作成画面へのリンク |
| 空状態メッセージ | プロジェクトがない場合の案内 | NoProjectsコンポーネント |

## イベント仕様

### 1-プロジェクト選択

プロジェクトカードをクリックしてプロジェクト詳細へ遷移。

**トリガー**：プロジェクトカードクリック

**処理フロー**：
1. クリックしたプロジェクトのIDを取得
2. `/projects/[projectId]`へ遷移

### 2-新規プロジェクト作成画面への遷移

新規プロジェクトを作成するための画面へ遷移。

**トリガー**：「Add New Project」ボタンクリック

**処理フロー**：
1. `/projects/new`へ遷移

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ読み込み | organization_members | SELECT | 組織ID取得のため |
| ページ読み込み | organizations | SELECT | 組織存在確認 |
| ページ読み込み | projects | SELECT | プロジェクト一覧取得 |
| ページ読み込み | project_repository_mappings | SELECT | リポジトリマッピング取得 |
| ページ読み込み | github_repositories | SELECT | リポジトリ情報取得 |

### テーブル別更新項目詳細

#### projects

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, name, created_at, updated_at, organization_id | organization_idで絞り込み | - |

#### project_repository_mappings / github_repositories

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | repository.id, name, owner, github_installation_identifier | project_idに紐づくリポジトリ情報 | JOINで取得 |

## メッセージ仕様

| メッセージID | メッセージ内容 | 表示タイミング | 種別 |
|--------------|---------------|----------------|------|
| MSG-001 | （NoProjectsコンポーネントで表示） | プロジェクトがない場合 | 情報 |

## 例外処理

| 例外ケース | 処理内容 |
|------------|----------|
| 組織ID取得失敗 | `/login`へリダイレクト |
| ユーザー情報取得エラー | `/login`へリダイレクト |
| セッションなし | `/login`へリダイレクト |
| 組織が存在しない | 404 Not Found |
| プロジェクト一覧取得エラー | コンソールにエラーログ、nullを返却 |
| プロジェクトが存在しない | NoProjectsコンポーネントを表示 |

## 備考

- 組織IDはCookieまたはデータベースから取得（`getOrganizationId`）
- プロジェクト一覧はid降順でソート
- ServerProjectsDataProviderコンポーネントでプロジェクトデータを提供
- GitHubリポジトリ情報もJOINで同時に取得

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

プロジェクトデータの取得方法を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | getProjects.ts | `frontend/apps/app/components/ProjectsPage/services/getProjects.ts` | プロジェクト一覧取得のクエリ構造 |
| 1-2 | getOrganizationId.ts | `frontend/apps/app/features/organizations/services/getOrganizationId.ts` | 組織ID取得ロジック |

**読解のコツ**: projectsテーブルとproject_repository_mappings、github_repositoriesのリレーションを使用したクエリに注目。

**主要処理フロー（getProjects.ts）**:
- **6-22行目**: JOINを使用したプロジェクト・リポジトリ情報取得クエリ
- **25-27行目**: organization_idでのフィルタリング

#### Step 2: エントリーポイントを理解する

プロジェクト一覧ページのエントリーポイントを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | page.tsx | `frontend/apps/app/app/projects/page.tsx` | ページコンポーネント、認証チェック |
| 2-2 | ProjectsPage.tsx | `frontend/apps/app/components/ProjectsPage/ProjectsPage.tsx` | メインコンポーネント |

**主要処理フロー（page.tsx）**:
- **8-11行目**: 組織ID取得、失敗時はログインへリダイレクト
- **15-28行目**: ユーザー情報・セッション確認
- **30行目**: ProjectsPageコンポーネントにorganizationIdを渡す

**主要処理フロー（ProjectsPage.tsx）**:
- **17-22行目**: 組織情報取得、未存在時は404
- **25行目**: getProjects()でプロジェクト一覧取得
- **31-44行目**: プロジェクト有無による表示分岐

#### Step 3: サブコンポーネントを理解する

一覧表示と空状態のコンポーネント。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ServerProjectsDataProvider.tsx | `frontend/apps/app/components/ProjectsPage/components/ServerProjectsDataProvider/ServerProjectsDataProvider.tsx` | プロジェクトデータの提供 |
| 3-2 | NoProjects.tsx | `frontend/apps/app/components/ProjectsPage/components/NoProjects/NoProjects.tsx` | 空状態UI |

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

```
app/projects/page.tsx
    │
    ├─ features/organizations/services/getOrganizationId.ts
    │      ├─ getOrganizationIdFromCookie()
    │      └─ getOrganizationIdFromDatabase()
    │
    ├─ libs/db/server.ts (createClient)
    │
    └─ components/ProjectsPage/ProjectsPage.tsx
           │
           ├─ services/getCurrentOrganization.ts
           │
           ├─ services/getProjects.ts
           │      └─ supabase.from('projects').select()
           │
           ├─ components/NoProjects.tsx
           │
           └─ components/ServerProjectsDataProvider.tsx
```

### データフロー図

```
[入力]                    [処理]                           [出力]

ページアクセス      ───▶ page.tsx                     ───▶ プロジェクト一覧
                         │
                         ├─ getOrganizationId()
                         │      └─ Cookie or DB
                         │
                         ├─ 認証チェック
                         │      └─ 失敗 → /login
                         │
                         └─ ProjectsPage
                                │
                                ├─ getCurrentOrganization()
                                │      └─ 未存在 → 404
                                │
                                └─ getProjects()
                                       │
                                       ├─ あり → ServerProjectsDataProvider
                                       └─ なし → NoProjects
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| page.tsx | `frontend/apps/app/app/projects/page.tsx` | ソース | プロジェクト一覧ページのエントリーポイント |
| ProjectsPage.tsx | `frontend/apps/app/components/ProjectsPage/ProjectsPage.tsx` | ソース | プロジェクト一覧のメインコンポーネント |
| getProjects.ts | `frontend/apps/app/components/ProjectsPage/services/getProjects.ts` | ソース | プロジェクト一覧取得サービス |
| getCurrentOrganization.ts | `frontend/apps/app/components/ProjectsPage/services/getCurrentOrganization.ts` | ソース | 現在組織取得サービス |
| ServerProjectsDataProvider.tsx | `frontend/apps/app/components/ProjectsPage/components/ServerProjectsDataProvider/ServerProjectsDataProvider.tsx` | ソース | プロジェクトデータ提供 |
| NoProjects.tsx | `frontend/apps/app/components/ProjectsPage/components/NoProjects/NoProjects.tsx` | ソース | 空状態コンポーネント |
| getOrganizationId.ts | `frontend/apps/app/features/organizations/services/getOrganizationId.ts` | ソース | 組織ID取得サービス |
| ProjectsPage.module.css | `frontend/apps/app/components/ProjectsPage/ProjectsPage.module.css` | スタイル | プロジェクト一覧ページのスタイル |
| server.ts | `frontend/apps/app/libs/db/server.ts` | ソース | Supabaseクライアント生成 |
| urlgen.ts | `frontend/apps/app/libs/routes/urlgen.ts` | ソース | URL生成ユーティリティ |
