# 画面設計書 5-組織一覧画面

## 概要

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

### 本画面の処理概要

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

**業務上の目的・背景**：Liam DBでは組織単位でプロジェクトやメンバーを管理する。ユーザーが複数の組織に所属している場合、この画面で作業対象の組織を選択する。組織を持たないユーザーは新規組織を作成することで、アプリケーションの利用を開始できる。

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

**主要な操作・処理内容**：
1. ユーザーが所属する組織の一覧を取得・表示
2. 組織カードをクリックしてプロジェクト一覧画面へ遷移
3. 「Create New Organization」ボタンで組織新規作成画面へ遷移
4. 組織が存在しない場合は空状態メッセージを表示

**画面遷移**：
- 組織選択時 → プロジェクト一覧画面（`/projects`）
- 新規組織作成クリック時 → 組織新規作成画面（`/organizations/new`）

**権限による表示制御**：認証必須。ユーザーが所属する組織のみ表示。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 26 | 組織管理 | 主機能 | ユーザーが所属する組織の一覧を取得・表示 |
| 27 | プロジェクト管理 | 遷移先機能 | 組織選択時のプロジェクト一覧画面への遷移 |
| 39 | Supabaseクライアント | API連携 | データベースから組織一覧を取得 |

## 画面種別

一覧

## URL/ルーティング

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

## 入出力項目

なし（入力項目はない）

## 表示項目

| 項目名 | 説明 | 備考 |
|--------|------|------|
| ページタイトル | "Organizations" | h1要素 |
| 新規作成ボタン | "Create New Organization" | 組織新規作成画面へのリンク |
| 組織カード | 組織名を表示するカード | クリックでプロジェクト一覧へ遷移 |
| 組織名 | 各組織の名称 | 未設定の場合は"Untitled Organization" |
| 空状態メッセージ | "No organizations found." | 組織がない場合に表示 |
| 新規作成案内 | "Create a new organization to get started." | 組織がない場合に表示 |

## イベント仕様

### 1-組織選択

組織カードをクリックしてプロジェクト一覧へ遷移。

**トリガー**：組織カードクリック

**処理フロー**：
1. クリックした組織のリンク先（`/projects`）へ遷移
2. プロジェクト一覧画面で選択組織のプロジェクトを表示

### 2-新規組織作成画面への遷移

新規組織を作成するための画面へ遷移。

**トリガー**：「Create New Organization」ボタンクリック

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

### 3-組織作成成功時のトースト表示

sessionStorageに保存された成功メッセージを表示。

**トリガー**：ページ読み込み時（sessionStorageにメッセージがある場合）

**処理フロー**：
1. OrganizationsPageClientコンポーネントでsessionStorageをチェック
2. 成功メッセージがあれば表示
3. 表示後、sessionStorageからメッセージを削除

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ読み込み | organization_members | SELECT | ユーザーの所属組織を取得 |
| ページ読み込み | organizations | SELECT | 組織情報（id, name）を取得 |

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

#### organization_members / organizations

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | user_id | 現在の認証ユーザーID | organization_membersテーブル |
| SELECT | id, name | user_idに紐づく組織 | organizationsテーブル（リレーション） |

## メッセージ仕様

| メッセージID | メッセージ内容 | 表示タイミング | 種別 |
|--------------|---------------|----------------|------|
| MSG-001 | "No organizations found." | 組織がない場合 | 情報 |
| MSG-002 | "Create a new organization to get started." | 組織がない場合 | 情報 |

## 例外処理

| 例外ケース | 処理内容 |
|------------|----------|
| ユーザー情報取得エラー | コンソールにエラーログ、nullを返却 |
| 組織一覧取得エラー | コンソールにエラーログ、nullを返却 |
| 組織が存在しない | 空状態UIを表示 |

## 備考

- 組織名が設定されていない場合は「Untitled Organization」と表示
- sessionStorageを使用したトースト表示機能あり（OrganizationsPageClient）
- 組織カードはグリッドレイアウトで表示

---

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

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

### 推奨読解順序

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

組織データの取得方法を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | getOrganizations.ts | `frontend/apps/app/components/OrganizationsPage/getOrganizations.ts` | 組織一覧取得のクエリ構造 |

**読解のコツ**: `organization_members`と`organizations`のリレーションを使用したクエリに注目。

**主要処理フロー**:
- **6-8行目**: ユーザー情報を取得
- **12-20行目**: organization_membersとorganizationsをJOINして取得
- **27行目**: organizationsオブジェクトを抽出して返却

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

組織一覧ページのエントリーポイントを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | page.tsx | `frontend/apps/app/app/organizations/page.tsx` | ページコンポーネントの定義 |
| 2-2 | OrganizationsPage.tsx | `frontend/apps/app/components/OrganizationsPage/OrganizationsPage.tsx` | メインコンポーネント |

**主要処理フロー（OrganizationsPage.tsx）**:
- **11行目**: getOrganizations()で組織一覧取得
- **14-16行目**: ヘッダー（タイトル、新規作成ボタン）
- **28-34行目**: 組織がない場合の空状態表示
- **35-44行目**: 組織カードのグリッド表示

#### Step 3: クライアントコンポーネントを理解する

sessionStorageを使用したトースト機能。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | OrganizationsPageClient.tsx | `frontend/apps/app/components/OrganizationsPage/OrganizationsPageClient.tsx` | sessionStorageトースト処理 |

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

```
app/organizations/page.tsx
    │
    └─ components/OrganizationsPage/OrganizationsPage.tsx
           │
           ├─ getOrganizations.ts
           │      ├─ supabase.auth.getUser()
           │      └─ supabase.from('organization_members').select()
           │
           ├─ OrganizationsPageClient.tsx (sessionStorageトースト)
           │
           └─ Link components
                  ├─ /organizations/new (新規作成)
                  └─ /projects (組織選択)
```

### データフロー図

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

ページアクセス      ───▶ OrganizationsPage            ───▶ 組織一覧表示
                         │
                         ├─ getOrganizations()
                         │      └─ Supabaseクエリ
                         │
                         └─ 組織データ有無で分岐
                                │
                                ├─ あり ─────────────────▶ 組織カードグリッド
                                └─ なし ─────────────────▶ 空状態UI
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| page.tsx | `frontend/apps/app/app/organizations/page.tsx` | ソース | 組織一覧ページのエントリーポイント |
| OrganizationsPage.tsx | `frontend/apps/app/components/OrganizationsPage/OrganizationsPage.tsx` | ソース | 組織一覧のメインコンポーネント |
| OrganizationsPageClient.tsx | `frontend/apps/app/components/OrganizationsPage/OrganizationsPageClient.tsx` | ソース | sessionStorageトースト処理 |
| getOrganizations.ts | `frontend/apps/app/components/OrganizationsPage/getOrganizations.ts` | ソース | 組織一覧取得サービス |
| OrganizationsPage.module.css | `frontend/apps/app/components/OrganizationsPage/OrganizationsPage.module.css` | スタイル | 組織一覧ページのスタイル |
| server.ts | `frontend/apps/app/libs/db/server.ts` | ソース | Supabaseクライアント生成 |
| urlgen.ts | `frontend/apps/app/libs/routes/urlgen.ts` | ソース | URL生成ユーティリティ |
