# 画面設計書 2-ログアウト画面

## 概要

本ドキュメントはInvenTreeシステムのログアウト画面の設計仕様を記載する。ユーザーセッションを終了するための画面である。

### 本画面の処理概要

ログアウト画面は、ユーザーがInvenTreeシステムからログアウトするための画面である。画面表示時に自動的にログアウト処理が実行され、セッションが終了した後にログイン画面へリダイレクトされる。

**業務上の目的・背景**：セキュリティ上の理由から、ユーザーが明示的にセッションを終了できる機能が必要である。共有端末での使用時や、作業終了時にセッションを確実に終了させることで、不正アクセスを防止する。URLを直接指定することでログアウトを実行できるため、ブックマークやスクリプトからのログアウトも可能である。

**画面へのアクセス方法**：ブラウザで `/logout` URLに直接アクセスするか、アプリケーション内のログアウトボタン/リンクをクリックする。

**主要な操作・処理内容**：
1. 画面表示時に自動的にログアウトAPI呼び出し
2. サーバーセッションの削除
3. クライアント側の認証状態クリア
4. CSRFクッキーの削除
5. ログイン画面への自動リダイレクト

**画面遷移**：
- 遷移元：アプリケーション内の任意の画面（ログアウトリンク/ボタン経由）、URLの直接入力
- 遷移先：ログイン画面（ログアウト完了後）

**権限による表示制御**：
- 認証状態に関わらずアクセス可能
- 未認証ユーザーがアクセスした場合もログイン画面へリダイレクト

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 33 | 認証・ログイン | 主機能 | ログアウト処理の実行 |

## 画面種別

処理画面（自動実行）

## URL/ルーティング

| パス | 説明 |
|------|------|
| `/logout` | ログアウト画面 |

## 入出力項目

### 入力項目

なし（自動実行のため入力項目なし）

### 出力項目

| No | 項目名 | 説明 |
|----|--------|------|
| 1 | 画面タイトル | "Logging out" |
| 2 | ローディングインジケーター | 処理中を示すスピナー |

## 表示項目

| No | 項目名 | 表示条件 | 説明 |
|----|--------|----------|------|
| 1 | 画面タイトル | 常時 | "Logging out" |
| 2 | ローディングインジケーター | 常時 | 処理中スピナー |

## イベント仕様

### 1-画面表示時（自動実行）

画面がマウントされた時点で自動的にログアウト処理を実行する。

**処理フロー**：
1. `useEffect`フックにより画面マウント時に`doLogout`関数を呼び出し
2. ログイン状態またはCSRFクッキーが存在する場合：
   - `DELETE /api/auth/v1/auth/session` APIを呼び出してサーバーセッションを終了
   - 「Logged Out / Successfully logged out」通知を表示
3. クライアント側のユーザー状態をクリア（`clearUserState`）
4. CSRFクッキーを削除（`clearCsrfCookie`）
5. 認証コンテキストをクリア（`setAuthContext(undefined)`）
6. `/login` へナビゲート

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ログアウト実行 | auth_session | DELETE | セッション情報の削除 |

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

#### auth_session

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | session_key = 現在のセッション | Djangoセッションテーブルから削除 |

## メッセージ仕様

| No | メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|----|-------------|---------------|---------------|----------|
| 1 | logout-success | 成功 | Logged Out / Successfully logged out | ログアウト成功時 |

## 例外処理

| No | 例外条件 | 処理内容 |
|----|----------|----------|
| 1 | セッション削除API失敗 | エラーを無視し、クライアント側の状態クリアとリダイレクトを続行 |
| 2 | 未認証状態でのアクセス | クライアント状態クリアのみ実行し、ログイン画面へリダイレクト |

## 備考

- ログアウト処理は非同期で実行されるが、画面遷移は処理完了を待たずに行われる可能性がある
- セッション削除APIの失敗はエラーとして表示されず、処理が続行される
- ブラウザの「戻る」ボタンでログアウト画面に戻った場合も、再度ログアウト処理が実行される

---

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

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

### 推奨読解順序

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

ログアウト処理に関連する状態管理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | UserState.tsx | `src/frontend/src/states/UserState.tsx` | `clearUserState`関数の実装、認証状態の管理 |
| 1-2 | ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | `auth_session`エンドポイント定義 |

**読解のコツ**: `clearUserState`がユーザー情報と認証フラグの両方をクリアすることを確認する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Logout.tsx | `src/frontend/src/pages/Auth/Logout.tsx` | 非常にシンプルな構造、useEffectでの自動実行 |

**主要処理フロー**:
1. **行8-9**: コンポーネント定義と`useNavigate`フックの取得
2. **行11-13**: `useEffect`で画面マウント時に`doLogout`を呼び出し
3. **行15**: Wrapperコンポーネントでローディング表示

#### Step 3: ログアウト処理関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | auth.tsx | `src/frontend/src/functions/auth.tsx` | `doLogout`関数の実装詳細 |

**主要処理フロー**:
- **行206-225**: `doLogout`関数
  - 行207-208: ユーザー状態と認証コンテキストの取得
  - 行211: ログイン状態またはCSRFクッキー存在の確認
  - 行212-214: セッション削除API呼び出し
  - 行215-218: ログアウト成功通知表示
  - 行221-224: クライアント状態のクリアとリダイレクト

#### Step 4: レイアウトコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Layout.tsx | `src/frontend/src/pages/Auth/Layout.tsx` | Wrapperコンポーネントの`loader`プロパティ |

**主要処理フロー**:
- **行49-53**: `loader`プロパティが`true`の場合、中央にLoaderを表示

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

```
Logout.tsx (エントリーポイント)
    │
    ├─ useNavigate()
    │
    ├─ useEffect() [マウント時]
    │      │
    │      └─ doLogout(navigate)
    │             │
    │             ├─ useUserState.getState()
    │             │      ├─ clearUserState
    │             │      └─ isLoggedIn
    │             │
    │             ├─ useServerApiState.getState()
    │             │      └─ setAuthContext
    │             │
    │             ├─ getCsrfCookie()
    │             │
    │             ├─ authApi(DELETE auth/session)
    │             │
    │             ├─ showLoginNotification()
    │             │
    │             ├─ clearUserState()
    │             │
    │             ├─ clearCsrfCookie()
    │             │
    │             └─ navigate('/login')
    │
    └─ Wrapper (loader=true)
           └─ Loader (中央表示)
```

### データフロー図

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

画面マウント ───▶ doLogout()
                    │
                    ├─ DELETE auth/session ─────────▶ サーバーセッション削除
                    │
                    ├─ clearUserState() ────────────▶ ユーザー状態クリア
                    │
                    ├─ clearCsrfCookie() ───────────▶ クッキー削除
                    │
                    └─ navigate('/login') ──────────▶ ログイン画面へ遷移
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Logout.tsx | `src/frontend/src/pages/Auth/Logout.tsx` | ソース | ログアウト画面メインコンポーネント |
| auth.tsx | `src/frontend/src/functions/auth.tsx` | ソース | ログアウト処理関数（doLogout） |
| Layout.tsx | `src/frontend/src/pages/Auth/Layout.tsx` | ソース | 認証画面レイアウト |
| UserState.tsx | `src/frontend/src/states/UserState.tsx` | ソース | ユーザー状態管理 |
| ServerApiState.tsx | `src/frontend/src/states/ServerApiState.tsx` | ソース | サーバーAPI状態管理 |
| ApiEndpoints.tsx | `src/frontend/lib/enums/ApiEndpoints.tsx` | ソース | APIエンドポイント定義 |
| router.tsx | `src/frontend/src/router.tsx` | ソース | ルーティング定義 |
