# 画面設計書 34-通知トレイ画面

## 概要

本ドキュメントは、Fizzyアプリケーションにおける通知トレイ画面の設計仕様を記述したものです。

### 本画面の処理概要

通知トレイ画面は、ヘッダーの通知アイコンからポップアップ形式で表示される軽量な通知確認画面です。未読通知と最近の既読通知を素早く確認できるUIを提供します。

**業務上の目的・背景**：ユーザーは作業中に通知を確認したいケースが多いですが、通知一覧画面に遷移すると現在の作業コンテキストが失われます。通知トレイは、画面遷移なしに最新の通知を確認し、必要に応じて関連カードへアクセスできるようにすることで、作業効率を向上させます。

**画面へのアクセス方法**：ヘッダーの通知アイコン（ベルアイコン）をクリックすることでポップアップ表示されます。

**主要な操作・処理内容**：
1. 未読通知の一覧を確認
2. 既読通知の一覧を確認（include_readパラメータ指定時）
3. 通知をクリックして関連カードへ遷移
4. 通知を既読にする

**画面遷移**：
- 遷移元：各画面のヘッダー（ポップアップとして表示）
- 遷移先：カード詳細画面（通知クリック時）、通知一覧画面

**権限による表示制御**：ユーザー自身の通知のみが表示されます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 57 | 通知一覧表示 | 主機能 | 通知トレイをポップアップ表示 |
| 58 | 通知既読 | API連携 | 通知を既読にする |

## 画面種別

ポップアップ一覧

## URL/ルーティング

- **パス**: `/notifications/tray`
- **HTTPメソッド**: GET
- **コントローラ**: `Notifications::TraysController#show`

## 入出力項目

| 項目名 | 項目ID | 入出力 | データ型 | 必須 | 最大長 | 説明 |
|--------|--------|--------|----------|------|--------|------|
| 既読含むフラグ | include_read | 入力 | Boolean | 任意 | - | 既読通知も表示するか |

## 表示項目

| 項目名 | 説明 | データ取得元 |
|--------|------|-------------|
| 通知一覧 | 未読/既読通知のリスト | @notifications |

## イベント仕様

### 1-通知クリック

通知をクリックして関連カードへ遷移します。

- **トリガー**: 通知項目をクリック
- **処理フロー**:
  1. 通知に関連付けられたカードを取得
  2. カード詳細画面へ遷移
- **遷移先**: `/cards/:id`

### 2-既読処理

通知を既読にします。

- **トリガー**: 既読ボタンをクリック
- **処理フロー**:
  1. PATCH `/notifications/:id/reading` を送信
  2. 通知のread_atを更新
  3. Turbo Streamでトレイ内の表示を更新

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | notifications | SELECT | 未読・既読通知を取得 |

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

#### notifications

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | - | user_id = Current.user.id | 最大100件まで |

## メッセージ仕様

| 種別 | メッセージID | メッセージ内容 | 表示条件 |
|------|------------|---------------|---------|
| - | - | - | 特になし（通知アイテムのみ表示） |

## 例外処理

| 例外 | 発生条件 | 処理内容 |
|-----|---------|---------|
| 認証エラー | 未ログイン状態 | ログイン画面へリダイレクト |

## 備考

- 通知は最大100件まで表示
- HTTPキャッシュ（ETag）を使用して効率的に更新を検出
- Turbo Frameを使用したポップアップ表示
- include_readパラメータで既読通知の表示を制御

---

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

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

### 推奨読解順序

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

通知のデータモデルと取得条件を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | notification.rb | `app/models/notification.rb` | 通知モデルのスコープ（unread, read, ordered, preloaded） |

**読解のコツ**: `scope :preloaded`で関連データを一括取得し、N+1問題を防いでいます。

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

コントローラのshowアクションを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | trays_controller.rb | `app/controllers/notifications/trays_controller.rb` | showアクションの実装、キャッシュ制御 |

**主要処理フロー**:
1. **2行目**: MAX_ENTRIES_LIMIT = 100 で取得上限を設定
2. **4-8行目**: 未読通知を取得、include_readなら既読も追加
3. **12行目**: fresh_whenでHTTPキャッシュ（ETag）を設定

#### Step 3: ビューレイヤーを理解する

通知トレイのテンプレート構造を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.erb | `app/views/notifications/trays/show.html.erb` | トレイのテンプレート |
| 3-2 | _notification.html.erb | `app/views/notifications/_notification.html.erb` | 通知アイテムパーシャル |

**主要処理フロー**:
- **show.html.erb 1-3行目**: Turbo Frameで通知コレクションをレンダリング

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

```
Notifications::TraysController#show
    │
    ├─ unread_notifications
    │      │
    │      └─ Current.user.notifications.unread
    │             .preloaded.ordered.limit(100)
    │
    ├─ include_read? (params[:include_read])
    │      │
    │      └─ true の場合: read_notifications を追加
    │             │
    │             └─ Current.user.notifications.read
    │                    .preloaded.ordered.limit(100)
    │
    ├─ @notifications = unread + read (条件付き)
    │
    ├─ fresh_when (ETagキャッシュ設定)
    │
    └─ render show.html.erb
           │
           └─ render _notification.html.erb (collection, cached)
```

### データフロー図

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

パラメータ               TraysController#show
  include_read ─────────▶ 未読通知取得
                              │
                        include_read?
                              │
                        ┌─────┴─────┐
                       false      true
                        │           │
                        │      既読通知取得
                        │           │
                        └─────┬─────┘
                              │
                        @notifications合成
                              │
                        fresh_when (ETag)
                              │
                              ▼
                        show.html.erb
                              │
                              ▼
                        Turbo Frame
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| trays_controller.rb | `app/controllers/notifications/trays_controller.rb` | コントローラ | トレイ表示の制御 |
| show.html.erb | `app/views/notifications/trays/show.html.erb` | テンプレート | トレイ表示 |
| _notification.html.erb | `app/views/notifications/_notification.html.erb` | パーシャル | 通知アイテム |
| notification.rb | `app/models/notification.rb` | モデル | 通知データ定義 |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（114行目） |
