# 機能設計書 34-通知センター

## 概要

本ドキュメントは、Wikipedia iOSアプリにおける通知センター（Notifications Center）機能について、その設計仕様を詳細に記載したものである。

### 本機能の処理概要

通知センターは、ユーザーに関連するWikipedia上の活動（編集への反応、議論への返信、言及など）をまとめて表示・管理する機能である。

**業務上の目的・背景**：Wikipediaでは、ユーザーの投稿に対する反応や、トークページでの議論など、さまざまなアクティビティが発生する。通知センターは、これらのアクティビティをユーザーに通知し、Wikipediaコミュニティへの参加を促進する。Echo通知システムと連携し、複数のWikipediaプロジェクト横断で通知を一元管理できる。

**機能の利用シーン**：
- 自分の編集への反応（感謝、取り消しなど）を確認したい場合
- トークページでの議論の更新を確認したい場合
- 他のユーザーからのメンションを確認したい場合
- ウォッチリストの記事の変更を確認したい場合

**主要な処理内容**：
1. 通知一覧の取得と表示（ページネーション対応）
2. 通知の既読/未読状態の管理
3. 通知のフィルタリング（種類別、プロジェクト別）
4. 通知の詳細表示とアクション実行
5. プッシュ通知との連携

**関連システム・外部連携**：MediaWiki Echo通知APIと連携。RemoteNotificationsControllerを介してサーバーから通知を取得し、Core Dataにキャッシュする。

**権限による制御**：ログイン済みユーザーのみ利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | NotificationsCenterViewController | 主画面 | 通知一覧表示、編集モード、フィルター |
| - | NotificationsCenterDetailViewController | 詳細画面 | 通知詳細とアクション |
| - | NotificationsCenterFilterView | フィルター画面 | 通知種類でのフィルタリング |
| - | NotificationsCenterInboxView | インボックス画面 | プロジェクト別フィルタリング |

## 機能種別

データ表示 / CRUD操作（Read, Update） / データ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | 自動取得（ユーザーの通知） | - |

### 入力データソース

- MediaWiki Echo API（通知データ）
- Core Data（ローカルキャッシュ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| cellViewModels | [NotificationsCenterCellViewModel] | 表示用の通知ビューモデル配列 |
| isEmpty | Bool | 通知が空かどうか |
| isLoading | Bool | 読み込み中かどうか |

### 出力先

- 画面表示（通知一覧）

## 処理フロー

### 処理シーケンス

```
1. 画面表示時に初期化
   └─ NotificationsCenterViewModel.setup()
2. 最初のページを取得
   └─ viewModel.fetchFirstPage()
3. 通知データをCore Dataから取得
   └─ RemoteNotificationsController.fetchNotifications()
4. セルビューモデルを生成してスナップショット更新
   └─ applySnapshot()
5. Pull-to-Refreshで最新通知を取得
   └─ viewModel.refreshNotifications()
6. スクロール時に次のページを取得
   └─ viewModel.fetchNextPage()
7. 編集モードで既読/未読を一括管理
   └─ viewModel.markAsReadOrUnread()
8. フィルター変更時にデータをリセット
   └─ viewModel.resetAndRefreshData()
```

### フローチャート

```mermaid
flowchart TD
    A[画面表示] --> B[初期化処理]
    B --> C[最初のページ取得]
    C --> D[スナップショット更新]
    D --> E[通知一覧表示]
    E --> F{ユーザー操作}
    F -->|Pull-to-Refresh| G[最新通知取得]
    F -->|スクロール| H[次ページ取得]
    F -->|セルタップ| I[詳細画面表示]
    F -->|編集モード| J[一括操作]
    F -->|フィルターボタン| K[フィルター画面表示]
    G --> D
    H --> D
    I --> L[既読マーク]
    J --> M[既読/未読更新]
    K --> N{フィルター変更?}
    N -->|Yes| O[データリセット]
    O --> C
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-34-01 | ログイン必須 | ログイン済みユーザーのみ通知を表示 | 常時 |
| BR-34-02 | 自動既読 | 通知センター表示時にすべての通知をseen（閲覧済み）に | 画面表示時 |
| BR-34-03 | タップ時既読 | 通知をタップして詳細表示時にread（既読）に | 通知タップ時 |
| BR-34-04 | ページネーション | 画面下部に到達したら次のページを自動取得 | スクロール時 |
| BR-34-05 | 全デバイス同期 | 既読状態はすべてのデバイスで同期 | 既読/未読変更時 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 通知取得 | RemoteNotification (Core Data) | SELECT | ローカルキャッシュから通知を取得 |
| 通知挿入 | RemoteNotification (Core Data) | INSERT | APIから取得した新規通知を保存 |
| 既読更新 | RemoteNotification (Core Data) | UPDATE | 既読/未読状態を更新 |

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

Core Dataエンティティ`RemoteNotification`を使用。`NSManagedObjectContextObjectsDidChangeNotification`を監視して変更を検知。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ネットワークエラー | 通信失敗時 | WMFAlertManagerでエラー表示 |
| - | 認証エラー | セッション切れ時 | 再ログインを促す |
| attemptingToRefreshBeforeDeadline | リフレッシュ制限 | リフレッシュ間隔が短すぎる場合 | サイレント無視 |

### リトライ仕様

Pull-to-Refreshによる手動リトライ。自動リトライなし。

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

Core Dataのコンテキストを使用。viewContextとbackgroundContextの分離。

## パフォーマンス要件

- DiffableDataSourceによる効率的なUI更新
- バックグラウンドキューでのスナップショット生成
- ページネーションによる段階的データ取得

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

- 認証トークンを使用したAPI呼び出し
- ユーザー固有のデータのみ表示

## 備考

- オンボーディング画面でプッシュ通知の許可を促す
- セルのスワイプアクションで既読/未読を切り替え可能
- RTL言語対応

---

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

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

### 推奨読解順序

#### Step 1: ビューモデルを理解する

まず、通知センターのビューモデルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | NotificationsCenterViewModel.swift | `Wikipedia/Code/NotificationsCenterViewModel.swift` | 全体のデータ管理とビジネスロジック |

**主要処理フロー**:
- **62-73行目**: 初期化とNSNotificationの購読
- **152-155行目**: setup()でUI初期状態設定
- **157-170行目**: refreshNotifications()でサーバーから最新取得
- **217-244行目**: fetchFirstPage()で初回データ取得
- **246-277行目**: fetchNextPage()でページネーション

#### Step 2: ビューコントローラーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | NotificationsCenterViewController.swift | `Wikipedia/Code/NotificationsCenterViewController.swift` | UI制御とユーザーインタラクション |

**主要処理フロー**:
- **101-120行目**: viewDidLoad()で初期化
- **244-261行目**: setupDataSource()でDiffableDataSource設定
- **263-277行目**: applySnapshot()でUI更新
- **650-711行目**: UICollectionViewDelegateの実装

#### Step 3: データコントローラーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RemoteNotificationsController.swift | `WMF Framework/Remote Notifications/RemoteNotificationsController.swift` | Echo APIとの連携、Core Dataキャッシュ管理 |

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

```
NotificationsCenterViewController
    │
    ├─ viewDidLoad()
    │      ├─ setupDataSource()
    │      └─ viewModel.setup()
    │              └─ viewModel.fetchFirstPage()
    │
    ├─ NotificationsCenterViewModelDelegate.update()
    │      ├─ applySnapshot()
    │      ├─ updateEmptyDisplayState()
    │      └─ updateToolbarDisplayState()
    │
    ├─ UICollectionViewDelegate
    │      ├─ didSelectItemAt → 詳細画面遷移
    │      └─ willDisplay → fetchNextPage()
    │
    └─ ToolbarActions
           ├─ userDidTapTypeFilterButton() → フィルター画面
           └─ userDidTapProjectFilterButton() → インボックス画面
```

### データフロー図

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

Echo API ──────────────────▶  RemoteNotificationsController      ▶ Core Data
                             ┌─────────────────────────────┐
Core Data ─────────────────▶ │  NotificationsCenterViewModel  │  ▶ CellViewModels
                             │  ・データ取得                    │
フィルター設定 ────────────▶  │  ・フィルタリング                │  ▶ Snapshot
                             │  ・既読/未読管理                 │
                             └─────────────────────────────┘  ▶ UI更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| NotificationsCenterViewController.swift | `Wikipedia/Code/NotificationsCenterViewController.swift` | ソース | メインビューコントローラー |
| NotificationsCenterViewModel.swift | `Wikipedia/Code/NotificationsCenterViewModel.swift` | ソース | ビューモデル、ビジネスロジック |
| NotificationsCenterCellViewModel.swift | `Wikipedia/Code/NotificationsCenterCellViewModel.swift` | ソース | セル用ビューモデル |
| NotificationsCenterCell.swift | `Wikipedia/Code/NotificationsCenterCell.swift` | ソース | 通知セルUI |
| RemoteNotificationsController.swift | `WMF Framework/Remote Notifications/RemoteNotificationsController.swift` | ソース | 通知データコントローラー |
| NotificationsCenterFilterView.swift | `Wikipedia/Code/NotificationsCenterFilterView.swift` | ソース | フィルター画面（SwiftUI） |
| NotificationsCenterInboxView.swift | `Wikipedia/Code/NotificationsCenterInboxView.swift` | ソース | インボックス画面（SwiftUI） |
| NotificationsCenterDetailViewController.swift | `Wikipedia/Code/NotificationsCenterDetailViewController.swift` | ソース | 詳細画面 |
