# 画面設計書 1-ログイン画面

## 概要

本ドキュメントは、Payload CMSの管理画面におけるログイン画面の設計について記載する。ユーザーがメールアドレスまたはユーザー名とパスワードを入力してシステムにログインするための認証画面である。

### 本画面の処理概要

本画面は、Payload CMS管理画面へのアクセスを制御するための認証画面である。ユーザーは認証情報を入力し、システムへのログインを行う。

**業務上の目的・背景**：管理画面へのアクセスを制限し、認証済みユーザーのみがコンテンツ管理機能を利用できるようにする。これにより、不正アクセスを防止し、システムのセキュリティを確保する。また、autoLoginオプションにより開発環境での効率的なテストを可能にし、prefill機能でユーザー体験を向上させる。

**画面へのアクセス方法**：管理画面のURLにアクセスした際、未認証状態の場合に自動的にリダイレクトされる。または、ログアウト後にログイン画面へ遷移する。URLパターンは `/admin/login` となる。

**主要な操作・処理内容**：
1. メールアドレス/ユーザー名フィールドに認証情報を入力する
2. パスワードフィールドにパスワードを入力する
3. ログインボタンを押下してPOSTリクエストを送信する
4. 認証成功時、ダッシュボード画面またはリダイレクト先URLへ遷移する
5. パスワードを忘れた場合は「パスワードをお忘れですか？」リンクから復旧画面へ遷移する

**画面遷移**：
- 遷移元：ログアウト画面、パスワードリセット画面、メール認証画面、各種認証エラー画面
- 遷移先：ダッシュボード画面（認証成功時）、パスワードリセット依頼画面（リンク押下時）

**権限による表示制御**：本画面は未認証ユーザー向けの画面であり、既にログイン済みのユーザーがアクセスした場合は、ダッシュボード画面へ自動的にリダイレクトされる。また、`disableLocalStrategy`が有効な場合はログインフォームが非表示となる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | ユーザー認証 | 主機能 | メールアドレス/ユーザー名とパスワードによるログイン処理 |
| 30 | Admin UI | 補助機能 | ログインフォームのUIレンダリング、ロゴ表示 |
| 31 | Next.js統合 | 補助機能 | リダイレクト処理、ルーティング |

## 画面種別

認証（ログイン）

## URL/ルーティング

- **URL**: `/admin/login`
- **ルーティング定義**: `packages/next/src/routes/auth/login`
- **クエリパラメータ**: `redirect` - ログイン後のリダイレクト先URL

## 入出力項目

| 項目名 | 項目ID | 入出力区分 | データ型 | 必須 | 最大長 | 説明 |
|--------|--------|------------|----------|------|--------|------|
| メールアドレス | email | 入力 | string | 条件付き | 254 | loginWithUsername設定によりemailまたはusernameが必須 |
| ユーザー名 | username | 入力 | string | 条件付き | 255 | loginWithUsername設定によりemailまたはusernameが必須 |
| パスワード | password | 入力 | string | 必須 | - | ユーザーのパスワード |
| リダイレクトURL | redirect | 入力 | string | 任意 | - | ログイン成功後のリダイレクト先 |

## 表示項目

| 項目名 | 表示位置 | データソース | 説明 |
|--------|----------|--------------|------|
| ロゴ | 上部 | config.admin.components.graphics.Logo | カスタマイズ可能なロゴ画像 |
| beforeLoginコンポーネント | ログインフォーム上部 | config.admin.components.beforeLogin | カスタムコンポーネント挿入エリア |
| ログインフォーム | 中央 | - | メールアドレス/ユーザー名、パスワード入力欄 |
| パスワードリセットリンク | フォーム下部 | - | パスワードリセット画面へのリンク |
| ログインボタン | フォーム下部 | - | ログイン処理を実行するボタン |
| afterLoginコンポーネント | ログインフォーム下部 | config.admin.components.afterLogin | カスタムコンポーネント挿入エリア |

## イベント仕様

### 1-ログインボタン押下

- **トリガー**: ログインボタン押下
- **処理内容**:
  1. フォームバリデーションを実行
  2. `POST /api/{userSlug}/login` エンドポイントへリクエスト送信
  3. 認証成功時、レスポンスからユーザー情報を取得
  4. AuthProviderの`setUser`でユーザー状態を更新
  5. `redirect`パラメータがある場合はその URLへ、ない場合はadminRouteへリダイレクト
- **エラー処理**: 認証失敗時はエラーメッセージを表示

### 2-パスワードリセットリンク押下

- **トリガー**: 「パスワードをお忘れですか？」リンク押下
- **処理内容**: パスワードリセット依頼画面（`/admin/forgot-password`）へ遷移
- **遷移先**: パスワードリセット依頼画面

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ログインボタン押下 | users（ユーザーコレクション） | SELECT | 認証情報の検証 |
| ログイン成功 | - | - | セッション/JWTトークン発行（DBへの永続化は設定依存） |

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

#### users（ユーザーコレクション）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | email/username | 入力されたメールアドレス/ユーザー名と一致 | 認証対象ユーザーの検索 |
| SELECT | password | bcrypt比較 | ハッシュ化されたパスワードとの照合 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| authentication:login | ボタンラベル | ログイン | ログインボタン |
| authentication:forgotPasswordQuestion | リンクラベル | パスワードをお忘れですか？ | パスワードリセットリンク |
| - | エラー | 認証エラー | 認証失敗時 |

## 例外処理

| 例外状況 | 処理内容 |
|----------|---------|
| 認証失敗 | エラーメッセージを表示し、ログインフォームを再表示 |
| アカウントロック | ロック中のメッセージを表示（設定による） |
| ネットワークエラー | 通信エラーメッセージを表示 |
| 既にログイン済み | ダッシュボードまたはリダイレクト先URLへ自動遷移 |
| disableLocalStrategy有効 | ログインフォームを非表示にし、代替認証手段を表示 |

## 備考

- `autoLogin`オプションを設定することで、開発環境での自動ログインが可能
- `prefillOnly`オプションを使用すると、自動ログインではなくフォームへのプリフィルのみ行う
- `beforeLogin`/`afterLogin`コンポーネントを設定することで、OAuth認証ボタンなどのカスタムUIを追加可能
- `loginWithUsername`設定により、メールアドレスの代わりにユーザー名でのログインが可能

---

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

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

### 推奨読解順序

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

まず、ログイン処理で使用されるデータ構造とフォーム状態を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | FormState型定義 | `packages/payload/src/admin/forms/Form.ts` | フォームの状態管理に使用されるFormState型の構造 |
| 1-2 | UserWithToken型 | `packages/ui/src/providers/Auth/index.tsx` | ログイン成功時に返されるユーザー情報とトークンの型 |

**読解のコツ**: PayloadのフォームはReact Hook Formではなく、独自のFormStateを使用している。各フィールドは`initialValue`、`valid`、`value`の3プロパティを持つ。

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

処理の起点となるサーバーコンポーネントを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LoginView | `packages/next/src/views/Login/index.tsx` | サーバーサイドレンダリングのエントリーポイント |

**主要処理フロー**:
1. **行13-32**: `LoginView`関数でinitPageResultからユーザー情報を取得し、既ログイン時はリダイレクト
2. **行34-52**: autoLogin設定からprefill情報を抽出
3. **行54-102**: ロゴ、beforeLogin、ログインフォーム、afterLoginの順でレンダリング

#### Step 3: ログインフォームコンポーネントを理解する

クライアントサイドのフォーム処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | LoginForm | `packages/next/src/views/Login/LoginForm/index.tsx` | クライアントコンポーネントとしてのログインフォーム |

**主要処理フロー**:
- **行32-45**: configからユーザーコレクション設定とloginWithUsernameオプションを取得
- **行48-56**: ログインタイプ（email/username/emailOrUsername）を決定
- **行61-81**: 初期状態をprefill値で構築
- **行83-85**: `handleLogin`でsetUserを呼び出しユーザー状態を更新
- **行88-123**: Formコンポーネントでフォームをレンダリング、POSTアクションを設定

#### Step 4: 認証APIを理解する

バックエンドの認証処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | loginOperation | `packages/payload/src/auth/operations/login.ts` | 認証ロジックの実装 |

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

```
LoginView (Server Component)
    |
    +-- Logo (Server Component)
    |
    +-- RenderServerComponent(beforeLogin)
    |
    +-- LoginForm (Client Component)
    |       |
    |       +-- Form
    |       |     +-- LoginField (email/username入力)
    |       |     +-- PasswordField
    |       |     +-- Link (forgot password)
    |       |     +-- FormSubmit
    |       |
    |       +-- handleLogin
    |             +-- setUser (AuthProvider)
    |
    +-- RenderServerComponent(afterLogin)
```

### データフロー図

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

email/username  ----+
                    +--> LoginForm.submit() ---------> POST /api/{userSlug}/login
password -------+                                              |
                                                               v
                                                     loginOperation()
                                                              |
                                                              v
redirect URL <----------- setUser(UserWithToken) <---- JWT Token + User
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.tsx | `packages/next/src/views/Login/index.tsx` | ソース | サーバーコンポーネント、画面全体の構成 |
| LoginForm/index.tsx | `packages/next/src/views/Login/LoginForm/index.tsx` | ソース | クライアントコンポーネント、フォーム処理 |
| LoginField/index.tsx | `packages/next/src/views/Login/LoginField/index.tsx` | ソース | メールアドレス/ユーザー名入力フィールド |
| index.scss | `packages/next/src/views/Login/index.scss` | スタイル | 画面スタイル定義 |
| Logo/index.tsx | `packages/next/src/elements/Logo/index.tsx` | ソース | ロゴコンポーネント |
| Form.tsx | `packages/ui/src/forms/Form/index.tsx` | ソース | 汎用フォームコンポーネント |
| Auth/index.tsx | `packages/ui/src/providers/Auth/index.tsx` | ソース | 認証状態管理プロバイダー |
| login.ts | `packages/payload/src/auth/operations/login.ts` | ソース | 認証オペレーション |
