# 機能設計書 33-Admin Bar

## 概要

本ドキュメントは、Payload CMSのAdmin Bar機能について記述する。この機能は、フロントエンドサイトに管理バーを表示し、認証済みユーザーがサイト閲覧中に直接管理画面へ遷移したり、現在表示中のコンテンツを編集できるクイックアクセス機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：コンテンツ管理者がフロントエンドサイトを閲覧中に、表示されているコンテンツをすぐに編集したいというニーズがある。従来は管理画面に移動し、該当コンテンツを検索する必要があったが、Admin Barにより、フロントエンドから直接該当コンテンツの編集画面にジャンプできる。これにより、コンテンツ更新のワークフローが大幅に効率化される。

**機能の利用シーン**：
- フロントエンドサイト閲覧中に表示コンテンツの編集を行いたい場合
- 新規コンテンツを素早く作成したい場合
- プレビューモードから通常表示に戻りたい場合
- 管理画面のダッシュボードにアクセスしたい場合

**主要な処理内容**：
1. ユーザー認証状態の確認（/api/{authCollectionSlug}/me エンドポイント呼び出し）
2. 認証済みの場合、画面上部に管理バーを表示
3. 編集リンク、新規作成リンク、ログアウトリンクの提供
4. プレビューモード終了ボタンの表示（preview有効時）

**関連システム・外部連携**：
- Payload CMS管理画面（リンク先）
- Payload REST API（認証確認）
- フロントエンドアプリケーション（React）

**権限による制御**：
- 認証されていないユーザーにはAdmin Barを表示しない
- ユーザー情報はPayload CMSの認証システムに依存

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | フロントエンドサイト | 主機能 | 管理バーの表示 |
| 10 | ドキュメント編集画面 | 遷移先 | 編集リンクからの遷移先 |

## 機能種別

UIコンポーネント / ナビゲーション / 認証確認

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| cmsURL | string | No | PayloadサーバーのURL（デフォルト: http://localhost:8000） | 有効なURL形式 |
| adminPath | string | No | 管理画面パス（デフォルト: /admin） | - |
| apiPath | string | No | APIパス（デフォルト: /api） | - |
| authCollectionSlug | string | No | 認証コレクションスラッグ（デフォルト: users） | - |
| collectionSlug | string | No | 表示中コンテンツのコレクションスラッグ | - |
| id | string | No | 表示中コンテンツのドキュメントID | - |
| preview | boolean | No | プレビューモードフラグ | - |
| devMode | boolean | No | 開発モードフラグ（認証失敗時もダミーユーザーで表示） | - |
| unstyled | boolean | No | デフォルトスタイル無効化フラグ | - |
| logo | ReactElement | No | カスタムロゴ要素 | - |
| onAuthChange | (user: PayloadMeUser) => void | No | 認証状態変更コールバック | - |
| onPreviewExit | () => void | No | プレビュー終了コールバック | - |

### 入力データソース

- propsとして渡されるコンポーネントパラメータ
- Payload REST API（/api/{authCollectionSlug}/me）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| JSX.Element | React.ReactNode | 管理バーコンポーネント（認証済み時） |
| null | null | 非表示（未認証時） |

### 出力先

- DOMへのレンダリング（画面上部固定表示）

## 処理フロー

### 処理シーケンス

```
1. コンポーネントマウント
   └─ useEffect発火

2. 認証確認
   └─ fetch(`${cmsURL}${apiPath}/${authCollectionSlug}/me`)
   └─ credentials: 'include'でCookie送信

3. レスポンス処理
   ├─ ユーザー存在 → setUser(user)
   ├─ ユーザー不在 + devMode → setUser(dummyUser)
   └─ ユーザー不在 + !devMode → setUser(null)

4. 認証変更通知
   └─ onAuthChange(user)呼び出し

5. レンダリング
   ├─ user存在 → 管理バー表示
   └─ user不在 → null返却
```

### フローチャート

```mermaid
flowchart TD
    A[コンポーネントマウント] --> B[/me API呼び出し]
    B --> C{ユーザー存在?}
    C -->|Yes| D[setUser - user]
    C -->|No| E{devMode?}
    E -->|Yes| F[setUser - dummyUser]
    E -->|No| G[setUser - null]
    D --> H[onAuthChange呼び出し]
    F --> H
    G --> H
    H --> I{user存在?}
    I -->|Yes| J[管理バーレンダリング]
    I -->|No| K[null返却]

    J --> L[ロゴ表示]
    J --> M[ユーザー情報表示]
    J --> N{collectionSlug & id?}
    N -->|Yes| O[編集リンク表示]
    N -->|No| P[スキップ]
    J --> Q{collectionSlug?}
    Q -->|Yes| R[新規作成リンク表示]
    J --> S{preview?}
    S -->|Yes| T[プレビュー終了ボタン表示]
    J --> U[ログアウトリンク表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 認証必須 | 認証されていないユーザーにはAdmin Barを表示しない | 常時 |
| BR-02 | 開発モード | devMode=trueの場合、認証失敗時もダミーユーザーで表示 | devMode有効時 |
| BR-03 | 編集リンク条件 | collectionSlugとidの両方が指定された場合のみ編集リンクを表示 | 条件充足時 |
| BR-04 | デフォルトスタイル | unstyled=trueでない限り、デフォルトのインラインスタイルを適用 | unstyled未指定時 |

### 計算ロジック

各リンクURLの生成：
```
ロゴリンク: ${cmsURL}${adminPath}
ユーザーリンク: ${cmsURL}${adminPath}/collections/${authCollectionSlug}/${userID}
編集リンク: ${cmsURL}${adminPath}/collections/${collectionSlug}/${docID}
新規作成リンク: ${cmsURL}${adminPath}/collections/${collectionSlug}/create
ログアウトリンク: ${cmsURL}${adminPath}/logout
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 認証確認 | - | SELECT（API経由） | /me エンドポイントでユーザー情報取得 |

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

※Admin Bar自体はフロントエンドコンポーネント。データベースアクセスはPayload REST API経由。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ネットワークエラー | /me API呼び出し失敗 | console.warnで警告、devMode時はダミーユーザー使用 |

### リトライ仕様

- 自動リトライなし
- コンポーネント再マウント時に再試行

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

- フロントエンドコンポーネントのためトランザクション不要

## パフォーマンス要件

- コンポーネントマウント時に1回のAPI呼び出し
- credentials: 'include'によりCookie送信（CORS設定必要）

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

- credentials: 'include'によるCookieベースの認証
- target="_blank"と rel="noopener noreferrer"によるリンクセキュリティ
- devModeはプロダクション環境で無効にすべき

## 備考

- React 16.8以降、17、18、19に対応
- カスタムスタイリングはclassNamesプロップまたはunstyled+独自CSSで対応

---

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

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

### 推奨読解順序

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

まず、コンポーネントのprops型定義を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.ts | `packages/admin-bar/src/types.ts` | PayloadAdminBarProps型の構造 |

**読解のコツ**: `PayloadAdminBarProps`が主要な型。各propsの用途とデフォルト値を把握する。`PayloadMeUser`は認証ユーザー情報の型。

#### Step 2: メインコンポーネントを理解する

AdminBar.tsxがコンポーネントの全実装を含む。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AdminBar.tsx | `packages/admin-bar/src/AdminBar.tsx` | コンポーネント実装全体 |

**主要処理フロー**:
1. **4-7行目**: dummyUser定義（devMode用）
2. **11-36行目**: propsの分割代入とデフォルト値
3. **38行目**: useState(user)
4. **40-65行目**: useEffectで/me API呼び出し
5. **70-75行目**: useEffectでonAuthChange呼び出し
6. **76-348行目**: 条件付きレンダリング

#### Step 3: 認証処理を理解する

useEffect内の認証確認ロジック。

**主要処理フロー**:
- **43-44行目**: fetch API呼び出し（credentials: 'include'）
- **45-46行目**: レスポンスJSON解析
- **48-57行目**: ユーザー存在判定とstate更新
- **58-63行目**: エラーハンドリング（devMode対応）

#### Step 4: レンダリングを理解する

条件付きレンダリングとスタイル適用。

**主要処理フロー**:
- **77行目**: user存在チェック
- **84-102行目**: ルートdivのスタイル（unstyled対応）
- **106-130行目**: ロゴリンク
- **131-170行目**: ユーザー情報リンク
- **192-233行目**: 編集リンク（collectionSlug && id条件）
- **234-274行目**: 新規作成リンク（collectionSlug条件）
- **275-303行目**: プレビュー終了ボタン（preview条件）
- **305-343行目**: ログアウトリンク

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

```
PayloadAdminBar (AdminBar.tsx)
    │
    ├─ useState(user)
    │
    ├─ useEffect (認証確認)
    │      └─ fetch(`${cmsURL}${apiPath}/${authCollectionSlug}/me`)
    │             └─ setUser(user | dummyUser | null)
    │
    ├─ useEffect (認証変更通知)
    │      └─ onAuthChange(user)
    │
    └─ return (条件付きレンダリング)
           ├─ ロゴリンク
           ├─ ユーザー情報リンク
           ├─ 編集リンク (条件: collectionSlug && id)
           ├─ 新規作成リンク (条件: collectionSlug)
           ├─ プレビュー終了ボタン (条件: preview)
           └─ ログアウトリンク
```

### データフロー図

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

props                     PayloadAdminBar
    │                          │
    │                          ▼
    │                     fetch /me API ───▶ Payload CMS
    │                          │                  │
    │                          │◀────────────────┘
    │                          │            (user data)
    │                          ▼
    │                     setState(user)
    │                          │
    │                          ▼
    │                     onAuthChange(user) ───▶ 親コンポーネント
    │                          │
    │                          ▼
    └─────────────────▶  条件付きレンダリング
                               │
                               ▼
                          DOM要素 ───▶ 画面上部に固定表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/admin-bar/src/index.ts` | ソース | パッケージエントリーポイント |
| AdminBar.tsx | `packages/admin-bar/src/AdminBar.tsx` | ソース | メインコンポーネント実装 |
| types.ts | `packages/admin-bar/src/types.ts` | ソース | 型定義 |
| package.json | `packages/admin-bar/package.json` | 設定 | パッケージ定義 |
