# 機能設計書 63-日別イベント表示

## 概要

本ドキュメントは、Fizzyアプリケーションにおける特定の日のイベント詳細を表示する機能の設計を詳述する。

### 本機能の処理概要

**業務上の目的・背景**：タイムライン表示（機能No.62）でのページネーションをサポートするために、特定の日付のイベントを取得して表示する機能が必要である。これにより、ユーザーは過去のアクティビティを遡って閲覧でき、プロジェクトの履歴を効率的に確認できる。

**機能の利用シーン**：ホーム画面のタイムラインで無限スクロールによりページネーションが発生した際に、過去の日付のイベントを動的に取得するために利用される。Turbo Framesを使用した非同期リクエストとして呼び出される。

**主要な処理内容**：
1. URLパラメータから指定された日付を解析
2. 現在のユーザーがアクセス可能なボードのイベントを取得
3. 指定された日のイベントをフィルタリングして取得
4. Turbo Frameとして部分的なHTMLを返却

**関連システム・外部連携**：タイムライン表示（機能No.62）と密接に連携。同じUser::DayTimelineクラスとDayTimelinesScopedを使用する。Turbo Framesによる非同期更新を前提とした設計。

**権限による制御**：認証必須。ユーザーがアクセス権を持つボードのイベントのみ表示される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | 日別アクティビティ画面 | 主画面 | 特定の日のイベント詳細を表示 |

## 機能種別

データ参照処理（READ）/ Turbo Frame部分更新

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | String | Yes | 表示対象日（YYYY-MM-DD形式）。ルーティングでは:idとしてマッピング | Time.zone.parseで解析可能な形式。無効な場合は404 |
| board_ids | Array[UUID] | No | フィルタリング対象のボードID | ユーザーがアクセス可能なボードのみ |
| creator_ids | Array[UUID] | No | フィルタリング対象の作成者ID | アカウント内のユーザーのみ |

### 入力データソース

- URLパラメータ（id → day）
- FilterScopedのセッション/パラメータからのフィルター情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| @day_timeline | User::DayTimeline | 指定日の日次タイムラインオブジェクト |
| @day_timeline.events | Event::Relation | 指定日のイベント一覧 |
| Turbo Frame HTML | String | day-timeline-paginationのTurbo Frame |

### 出力先

- Turbo Frame部分更新（index.html.erb）
- HTTPキャッシュヘッダー（fresh_whenによるETagキャッシュ）

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信（GET /events/days/:id）
   └─ Events::DaysController#index
2. フィルター設定
   └─ FilterScopedによる@filterの設定
3. 日付解析
   └─ params[:id]をdayとして解析
4. タイムライン生成
   └─ DayTimelinesScopedによる@day_timelineの設定
5. キャッシュ判定
   └─ fresh_when @day_timelineでETagベースのキャッシュ制御
6. Turbo Frameレンダリング
   └─ ページネーション用のTurbo Frameを返却
```

### フローチャート

```mermaid
flowchart TD
    A[GET /events/days/:id] --> B[FilterScopedで@filter設定]
    B --> C[params:idをdayとして解析]
    C --> D{日付が有効?}
    D -->|無効| E[404 Not Found]
    D -->|有効| F[DayTimelinesScopedで@day_timeline設定]
    F --> G[fresh_when でキャッシュ判定]
    G -->|キャッシュ有効| H[304 Not Modified]
    G -->|キャッシュ無効| I[Turbo Frameをレンダリング]
    I --> J[day_timeline_pagination_frame_tag生成]
    J --> K[_day.html.erbで日次イベント表示]
    K --> L[次のページネーションリンク生成]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-63-01 | 日付パラメータ必須 | idパラメータで表示対象日を指定 | 常に |
| BR-63-02 | 継続ページネーション | 前のページのイベントがある場合、さらに過去へのリンクを表示 | next_dayが存在する場合 |
| BR-63-03 | フィルター継承 | 親画面（タイムライン表示）のフィルター条件を継承 | 常に |

### 計算ロジック

タイムライン表示（機能No.62）と同じビジネスルールを適用。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| イベント取得 | events | SELECT | 指定日の条件に合致するイベントを取得 |
| 関連データプリロード | cards, comments, users, boards | SELECT | N+1防止のためのプリロード |

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

#### events

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | board_id IN (アクセス可能ボードID), action IN (TIMELINEABLE_ACTIONS), created_at IN (指定日.all_day) | タイムライン表示と同じクエリ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | Not Found | idパラメータが無効な日付形式 | head :not_found |

### リトライ仕様

読み取り専用のため、リトライ仕様は不要。

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

読み取り専用のため、トランザクション制御は不要。

## パフォーマンス要件

- レスポンス時間：500ms以内
- Turbo Frameによる部分更新で全体のレンダリングを回避
- fresh_whenによるETagキャッシュで不要なレンダリングを回避

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

- 認証必須
- ユーザーがアクセス可能なボードのイベントのみ表示

## 備考

- タイムライン表示（機能No.62）のページネーション機能として動作
- Intersection Observerによる無限スクロールのトリガーで自動的に呼び出される

---

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

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

### 推奨読解順序

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

タイムライン表示（機能No.62）と同じデータ構造を使用するため、そちらを先に理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | day_timeline.rb | `app/models/user/day_timeline.rb` | タイムラインクラス（機能No.62参照） |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | days_controller.rb | `app/controllers/events/days_controller.rb` | 日別イベントコントローラー |
| 2-2 | day_timelines_scoped.rb | `app/controllers/concerns/day_timelines_scoped.rb` | タイムライン生成concern |

**主要処理フロー**:
1. **1行目**: Events::DaysControllerはDayTimelinesScopedをinclude
2. **4-6行目**: indexアクションでfresh_whenを使用
3. (concern) **15-22行目**: dayメソッドでparams[:day]（実際にはparams[:id]がリダイレクトされる）を解析

#### Step 3: ルーティングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | routes.rb | `config/routes.rb` | events/daysのルーティング定義 |

**読解のコツ**: routes.rbの137-142行目でnamespace :events内にresources :daysが定義されている。URLは/events/days/:idとなり、:idは日付文字列。

#### Step 4: ビューを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.html.erb | `app/views/events/days/index.html.erb` | 日別イベントビュー |
| 4-2 | _day.html.erb | `app/views/events/_day.html.erb` | 日次イベントパーシャル（共通） |

**読解のコツ**: index.html.erbはTurbo Frameを返却するシンプルな構造。day_timeline_pagination_frame_tagとday_timeline_pagination_linkを使用してページネーションを実装。

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

```
Events::DaysController#index
    │
    ├─ DayTimelinesScoped (include)
    │      ├─ FilterScoped (include)
    │      │      └─ @filter設定
    │      └─ set_day_timeline (before_action)
    │             └─ Current.user.timeline_for(day, filter: @filter)
    │                    └─ day = Time.zone.parse(params[:id] or params[:day])
    │
    └─ fresh_when @day_timeline
           │
           └─ ビューレンダリング (index.html.erb)
                  ├─ day_timeline_pagination_frame_tag
                  ├─ render "events/day"
                  └─ day_timeline_pagination_link
```

### データフロー図

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

params[:id]         ───▶ Time.zone.parse ───▶ day
(URL: /events/days/:id)      │
                             ▼
                    DayTimelinesScopedで@day_timeline生成
                             │
                             ▼
                    events.where(created_at: day.all_day)
                             │
                             ▼
                    Turbo Frame HTML (部分更新)
                             │
                             ▼
                    タイムラインに追加表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| days_controller.rb | `app/controllers/events/days_controller.rb` | コントローラー | 日別イベント表示のエントリーポイント |
| day_timelines_scoped.rb | `app/controllers/concerns/day_timelines_scoped.rb` | concern | タイムライン生成ロジック |
| day_timeline.rb | `app/models/user/day_timeline.rb` | モデル | タイムラインのビジネスロジック |
| index.html.erb | `app/views/events/days/index.html.erb` | ビュー | 日別イベント表示（Turbo Frame） |
| _day.html.erb | `app/views/events/_day.html.erb` | ビュー（パーシャル） | 日次イベント表示（共通） |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（137-142行目） |
