# 機能設計書 8-今日の出来事

## 概要

本ドキュメントは、Wikipedia iOSアプリにおける「今日の出来事（On This Day）」機能の設計仕様を記述する。過去の同じ日に起きた歴史的なイベントを表示する。

### 本機能の処理概要

**業務上の目的・背景**：歴史への興味を喚起し、Wikipediaの豊富な歴史コンテンツへのエンゲージメントを高める。毎日変わる「今日の出来事」コンテンツにより、ユーザーに定期的なアプリ訪問の動機を提供する。

**機能の利用シーン**：
- 探索フィードの「On This Day」カードをタップした時
- 「On This Day」カードの「もっと見る」をタップした時
- カード内のイベントをタップして詳細を見る時

**主要な処理内容**：
1. Wikipedia Feed APIから今日の出来事データを取得
2. イベントリストをコレクションビューで表示
3. タイムライン形式のUIで視覚的な歴史体験を提供
4. 各イベントに関連する記事へのナビゲーション
5. 記事のコンテキストメニュープレビュー

**関連システム・外部連携**：
- Wikipedia Feed API（On This Day コンテンツ）
- Core Data（WMFFeedOnThisDayEvent）

**権限による制御**：
- 特別な権限は不要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 11 | OnThisDay画面 | 主画面 | 今日の出来事リストの表示 |
| 1 | Explore画面 | 呼び出し元 | フィードカードからの遷移 |
| 5 | Article画面 | 遷移先 | 関連記事への遷移 |

## 機能種別

表示処理 / データ取得 / ナビゲーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| events | [WMFFeedOnThisDayEvent] | Yes | 今日の出来事イベント配列 | 空配列不可 |
| dataStore | MWKDataStore | Yes | データストアインスタンス | nil不可 |
| midnightUTCDate | Date | Yes | 対象日（UTC深夜0時） | 有効な日付 |
| contentGroup | WMFContentGroup | Yes | フィードコンテンツグループ | nil不可 |
| theme | Theme | Yes | 適用するテーマ | 有効なThemeオブジェクト |

### WMFFeedOnThisDayEventの構造

| プロパティ | 型 | 説明 |
|-----------|-----|------|
| year | Int | イベント発生年 |
| text | String | イベントの説明テキスト |
| pages | [WMFFeedPageSummary] | 関連記事のサマリー配列 |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| イベントリスト | UICollectionView | タイムライン形式のイベント表示 |
| ヘッダー | OnThisDayViewControllerHeader | 日付とイベント数を表示 |

### 出力先

- UICollectionView（メインコンテンツ）
- ナビゲーションバー（タイトル）

## 処理フロー

### 処理シーケンス

```
1. OnThisDayViewController初期化
   └─ events、dataStore、midnightUTCDate、contentGroupを受け取り
   └─ themeを設定

2. viewDidLoad
   └─ OnThisDayCollectionViewCellを登録
   └─ OnThisDayViewControllerHeaderを登録
   └─ layoutManagerのセットアップ

3. viewWillAppear
   └─ scrollToInitialEvent()で初期イベントまでスクロール
   └─ configureNavigationBar()でナビバー設定

4. セクション表示
   └─ numberOfSections = events.count + 1（ヘッダー用+1）
   └─ 各セクションに1つのイベントセルを表示

5. ヘッダー表示
   └─ section == 1でOnThisDayViewControllerHeader表示
   └─ イベント数、最初/最後のイベントの年を表示

6. セル選択
   └─ SideScrollingCollectionViewCellDelegateで記事タップを検出
   └─ ArticleCoordinatorで記事画面に遷移
```

### フローチャート

```mermaid
flowchart TD
    A[フィードカードタップ] --> B[OnThisDayViewController初期化]
    B --> C[viewDidLoad]
    C --> D[セル/ヘッダー登録]
    D --> E[viewWillAppear]
    E --> F[initialEventへスクロール]
    F --> G[イベントリスト表示]
    G --> H{ユーザーアクション}
    H -->|スクロール| I[追加イベント表示]
    H -->|記事タップ| J[ArticleCoordinator.start]
    H -->|長押し| K[コンテキストメニュー表示]
    J --> L[Article画面]
    K --> M[ArticlePeekPreviewViewController]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | セクション構成 | section 0はヘッダー用、section 1以降がイベント | 常時 |
| BR-002 | 初期スクロール | initialEventが指定されていれば該当セクションにスクロール | initialEvent != nil |
| BR-003 | タイムライン表示 | 最初のイベント以外はタイムライン線を上に延長 | section > 0 |
| BR-004 | イベント順序 | イベントは年の降順で表示 | 常時 |
| BR-005 | 選択無効 | セルの選択/ハイライトは無効 | 常時 |

### 計算ロジック

- セクション数: `events.count + 1`
- イベントインデックス: `section - 1`（section > 0の場合）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| イベント取得 | WMFFeedOnThisDayEvent | SELECT | イベントデータの取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 空イベント | eventsが空配列 | フィード画面に戻る |

### リトライ仕様

- フィード画面でのPull-to-Refreshで更新

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

- 読み取り専用、トランザクション処理なし

## パフォーマンス要件

- 画面表示：1秒以内
- スクロール：60fps維持

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

- 特別なセキュリティ要件なし

## 備考

- タイムラインのドットアニメーションはセル表示時に開始、非表示時に停止
- VoiceOver対応でaccessibilityTraits設定

---

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

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

### 推奨読解順序

#### Step 1: メインViewControllerを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | OnThisDayViewController.swift | `Wikipedia/Code/OnThisDayViewController.swift` | メインViewController |

**主要コード**:
- **4-6行目**: cellReuseIdentifier、headerReuseIdentifier定義
- **9-12行目**: プロパティ（events, dataStore, midnightUTCDate, initialEvent）
- **16-25行目**: init - 初期化処理
- **35-40行目**: viewDidLoad - セル/ヘッダー登録
- **42-52行目**: viewWillAppear - スクロール/ナビバー設定
- **54-60行目**: scrollToInitialEvent - 初期イベントへスクロール
- **128-141行目**: numberOfSections/numberOfItemsInSection
- **143-157行目**: cellForItemAt - セル構成

#### Step 2: セルコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | OnThisDayCollectionViewCell | `Wikipedia/Code/` | イベントセル |
| 2-2 | OnThisDayViewControllerHeader | `Wikipedia/Code/` | ヘッダービュー |

#### Step 3: コンテキストメニュー対応を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | OnThisDayViewController.swift | `Wikipedia/Code/OnThisDayViewController.swift` | NestedCollectionViewContextMenuDelegate |

**主要コード**:
- **237-259行目**: contextMenu - コンテキストメニュー生成
- **261-276行目**: willCommitPreview - プレビューからの遷移

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

```
OnThisDayViewController
    │
    ├─ UICollectionView
    │      ├─ OnThisDayCollectionViewCell
    │      │      └─ SideScrollingCollectionView（関連記事）
    │      │
    │      └─ OnThisDayViewControllerHeader
    │
    ├─ SideScrollingCollectionViewCellDelegate
    │      └─ sideScrollingCollectionViewCell:didSelectArticleWithURL
    │             └─ ArticleCoordinator.start()
    │
    └─ NestedCollectionViewContextMenuDelegate
           └─ contextMenu() -> UIContextMenuConfiguration
                  └─ ArticlePeekPreviewViewController
```

### データフロー図

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

WMFFeedOnThisDayEvent[] ─▶ OnThisDayViewController
    │                          │
    ├─ year ──────────────▶    │ (セル構成)
    ├─ text ──────────────▶    │
    └─ pages ─────────────▶    │ (関連記事表示)
                               │
midnightUTCDate ──────────▶    │ (ヘッダー日付)
                               │
                               ▼
                         UICollectionView
                               │
                               ▼
                         [イベントリスト表示]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| OnThisDayViewController.swift | `Wikipedia/Code/` | ソース | メインVC |
| OnThisDayCollectionViewCell.swift | `Wikipedia/Code/` | ソース | イベントセル |
| OnThisDayViewControllerHeader.swift | `Wikipedia/Code/` | ソース | ヘッダー |
| OnThisDayViewControllerHeader.xib | `Wikipedia/Code/` | リソース | ヘッダーレイアウト |
| OnThisDayTimelineView.swift | `Wikipedia/Code/` | ソース | タイムラインビュー |
| WMFFeedOnThisDayEvent | `WMF Framework/` | ソース | イベントモデル |
| SideScrollingCollectionViewCell.swift | `Wikipedia/Code/` | ソース | 横スクロールセル |
