# 通知設計書 24-Cookieエラー通知

## 概要

本ドキュメントは、Etherpadにおいてブラウザでクッキーが有効でない場合に表示される「noCookie」エラー通知の設計について記載する。

### 本通知の処理概要

この通知は、パッドの初期化時にクッキーの読み書きテストを行い、クッキーが正常に機能しない場合に表示される警告メッセージである。Gritterライブラリを使用したスティッキー（常時表示）通知として画面に表示される。

**業務上の目的・背景**：Etherpadはユーザーの設定やセッション情報をクッキーに保存するため、クッキーが無効な環境では正常に動作しない。この通知により、ユーザーに対してクッキーが無効であることを明確に伝え、ブラウザ設定の変更を促す。また、iFrame内での使用時に発生しやすいサードパーティクッキー問題についても注意を喚起する。

**通知の送信タイミング**：パッドページの読み込み時、padcookie.init()関数が実行される際に、クッキーの書き込み・読み込みテストを行い、読み込みがnullを返した場合に即座に表示される。

**通知の受信者**：パッドを閲覧しようとしているブラウザセッションのユーザー。クライアントサイドのJavaScriptによって表示されるため、当該ブラウザのユーザーのみが受信する。

**通知内容の概要**：「クッキーが見つかりませんでした。ブラウザでクッキーを許可してください。セッションと設定は訪問間で保存されません。これは一部のブラウザでiFrame内にEtherpadが含まれていることが原因かもしれません。」という趣旨の警告メッセージが表示される。

**期待されるアクション**：ユーザーはブラウザ設定でクッキーを有効にするか、プライベートブラウジングモードを解除するか、またはiFrame内での使用を避けて直接Etherpadにアクセスすることが期待される。

## 通知種別

アプリ内通知（Gritter スティッキー通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（クライアントサイド処理） |
| 優先度 | 高 |
| リトライ | なし |

### 送信先決定ロジック

パッド初期化時にクッキーテストが失敗したユーザーに対して表示する。完全にクライアントサイドで処理される。

## 通知テンプレート

### Gritter通知

| 項目 | 内容 |
|-----|------|
| タイトル | Error |
| スタイルクラス | error |
| スティッキー | true（自動消去なし、ユーザーが閉じるまで表示） |

### 本文テンプレート

```
Cookie could not be found. Please allow cookies in your browser! Your session and settings will not be saved between visits. This may be due to Etherpad being included in an iFrame in some Browsers. Please ensure Etherpad is on the same subdomain/domain as the parent iFrame
```

日本語（参考）:
```
クッキーが見つかりませんでした。ブラウザでクッキーを許可してください！セッションと設定は訪問間で保存されません。これは一部のブラウザでiFrame内にEtherpadが含まれていることが原因かもしれません。Etherpadが親iFrameと同じサブドメイン/ドメインにあることを確認してください。
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| なし | - | - | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面読み込み | padcookie.init()実行 | readPrefs_()がnullを返す | クッキーの読み取りテストが失敗 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| readPrefs_()が有効な値を返す | クッキーが正常に読み取れる場合は通知なし |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[パッドページ読み込み] --> B[padcookie.init実行]
    B --> C[readPrefs_でクッキー読み取り]
    C --> D[ユーザー固有情報を削除]
    D --> E[writePrefs_でクッキー書き込み]
    E --> F[readPrefs_で再読み取りテスト]
    F --> G{読み取り成功?}
    G -->|null| H[$.gritter.add呼び出し]
    G -->|成功| I[正常終了]
    H --> J[スティッキー通知表示]
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（クライアントサイドのみの処理）

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| クッキー無効 | ブラウザでクッキーが無効 | スティッキー通知を表示 |
| サードパーティクッキーブロック | iFrame内でサードパーティクッキーがブロックされている | スティッキー通知を表示 |

### リトライ仕様

該当なし

## 配信設定

### レート制限

該当なし（クライアントサイド処理のため）

### 配信時間帯

制限なし（24時間対応）

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

- クッキー名はHTTPSの場合'prefs'、HTTPの場合'prefsHttp'として区別される
- サードパーティiFrameの場合はSameSite=Noneが使用される
- セキュア属性はHTTPSの場合のみ有効
- ユーザー固有情報（userId, name, colorId）はクッキーテスト時に削除される

## 備考

- クッキーの有効期限は365 * 100日（約100年）に設定されている
- js-cookieライブラリを使用してクッキーの読み書きを行う
- iFrame内での使用時は親フレームと同じドメイン/サブドメインである必要がある
- プライベートブラウジングモードではクッキーが保存されない場合がある

---

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

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

### 推奨読解順序

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

クッキー管理の構造とクッキー名の決定ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | pad_cookie.ts | `src/static/js/pad_cookie.ts` | クラスコンストラクタ（23-25行目）でクッキー名を決定 |
| 1-2 | pad_utils.ts | `src/static/js/pad_utils.ts` | Cookiesオブジェクト（484-500行目）の設定 |

**読解のコツ**: HTTPSとHTTPでクッキー名が異なる点、SameSite属性の設定ロジックを確認する。

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

クッキー初期化と通知表示のトリガーを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | pad_cookie.ts | `src/static/js/pad_cookie.ts` | init関数（27-41行目）全体の流れ |
| 2-2 | pad.ts | `src/static/js/pad.ts` | padcookie.init()の呼び出し（420行目） |

**主要処理フロー**:
1. **27行目**: init関数開始
2. **28行目**: readPrefs_()で既存クッキーを読み取り
3. **29-31行目**: ユーザー固有情報を削除
4. **32行目**: writePrefs_()でクッキーを書き込み
5. **34-41行目**: 再読み取りテストとエラー通知

#### Step 3: 通知表示処理を理解する

Gritterライブラリを使用した通知表示を追跡する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | pad_cookie.ts | `src/static/js/pad_cookie.ts` | $.gritter.add呼び出し（35-40行目） |
| 3-2 | gritter.ts | `src/static/js/vendors/gritter.ts` | Gritterライブラリの動作（全体） |

**主要処理フロー**:
- **35行目**: $.gritter.add()呼び出し
- **36行目**: title: 'Error' 設定
- **37行目**: html10n.get('pad.noCookie')でローカライズされたメッセージ取得
- **38行目**: sticky: true でスティッキー表示
- **39行目**: class_name: 'error' でエラースタイル適用

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

```
[Client] pad.ts
    │
    ├─ pad.init() [410行目]
    │      │
    │      └─ padcookie.init() [420行目]
    │
    └─ [Client] pad_cookie.ts
           │
           ├─ init() [27行目]
           │      │
           │      ├─ readPrefs_() [28行目]
           │      │
           │      ├─ writePrefs_() [32行目]
           │      │
           │      ├─ readPrefs_() [34行目] 再テスト
           │      │
           │      └─ $.gritter.add() [35行目]
           │             │
           │             └─ html10n.get('pad.noCookie')
           │
           ├─ readPrefs_() [44-51行目]
           │      └─ Cookies.get()
           │
           └─ writePrefs_() [54-56行目]
                  └─ Cookies.set()
```

### データフロー図

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

パッド読み込み ───────▶ padcookie.init() ───────▶ クッキーテスト
                              │
                              ├─ readPrefs_()
                              │
                              ├─ writePrefs_()
                              │
                              └─ readPrefs_() (再テスト)
                                      │
                                      ▼
                              null? ───────▶ $.gritter.add()
                                                    │
                                                    ▼
                                            スティッキー通知
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| pad_cookie.ts | `src/static/js/pad_cookie.ts` | ソース | クッキー管理とエラー通知 |
| pad_utils.ts | `src/static/js/pad_utils.ts` | ソース | Cookiesオブジェクトの設定 |
| pad.ts | `src/static/js/pad.ts` | ソース | パッド初期化でpadcookie.init()を呼び出し |
| gritter.ts | `src/static/js/vendors/gritter.ts` | ソース | 通知表示ライブラリ |
| en.json | `src/locales/en.json` | 設定 | 国際化メッセージ定義（83行目: pad.noCookie） |
| html10n.ts | `src/static/js/vendors/html10n.ts` | ソース | 国際化ライブラリ |
