# 機能設計書 49-ストレージ・同期設定

## 概要

本ドキュメントは、Wikipedia iOSアプリにおけるストレージ・同期設定機能の設計を記載する。オフラインストレージの管理とリーディングリストの同期設定を管理する機能である。

### 本機能の処理概要

ストレージ・同期設定機能は、StorageAndSyncingSettingsViewControllerを通じて、保存済み記事とリーディングリストの同期設定、デフォルトリスト表示設定、保存データの削除を提供する。

**業務上の目的・背景**：ユーザーが複数デバイス間でリーディングリストを同期したり、デバイスのストレージを管理できるようにする。オフライン読書の利便性向上と、デバイス間のシームレスな体験を実現する。

**機能の利用シーン**：設定画面から「Storage and syncing」をタップして遷移。新しいデバイスでリーディングリストを同期、ストレージ容量の確保のため保存記事を削除、Androidデバイスとの互換性のためデフォルトリストを表示するなどに使用される。

**主要な処理内容**：
1. 保存記事・リーディングリスト同期の有効化/無効化
2. デフォルト（Saved）リーディングリストの表示設定
3. 保存済み記事の一括削除
4. サーバーとの手動同期

**関連システム・外部連携**：ReadingListsControllerでリーディングリスト同期を管理。CacheControllerでキャッシュサイズを取得。WMFAuthenticationManagerで認証状態を確認。

**権限による制御**：同期機能はログイン状態が必要。未ログイン状態で同期を有効化しようとするとログイン画面を表示。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 45 | StorageAndSyncingSettings画面 | 主画面 | オフラインストレージと同期の設定 |

## 機能種別

設定管理 / データ同期

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| syncEnabled | Bool | No | 同期の有効/無効 | - |
| isDefaultListEnabled | Bool | No | デフォルトリストの表示 | - |

### 入力データソース

- スイッチ操作（UISwitch）
- ReadingListsController（同期状態）
- WMFAuthenticationManager（認証状態）
- CacheController（キャッシュサイズ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| isSyncEnabled | Bool | 同期有効状態 |
| isDefaultListEnabled | Bool | デフォルトリスト表示状態 |

### 出力先

- ReadingListsController（同期設定）
- CacheController（キャッシュ削除）
- 画面表示（アラート、パネル）

## 処理フロー

### 処理シーケンス

```
1. viewDidLoad()
   ├─ テーブルビューセル登録
   └─ Notification監視（readingListsServerDidConfirmSyncWasEnabledForAccountNotification）
2. sections計算プロパティ
   ├─ syncSavedArticlesAndListsセクション
   ├─ showSavedReadingListセクション
   ├─ eraseSavedArticlesセクション
   └─ syncWithTheServerセクション
3. ユーザー操作
   ├─ 同期スイッチON（未ログイン）→ ログイン画面表示
   ├─ 同期スイッチON（ログイン済み）→ setSyncEnabled(true)
   ├─ 同期スイッチOFF → 確認パネル後にsetSyncEnabled(false)
   ├─ デフォルトリストスイッチ → isDefaultListEnabled設定
   ├─ 削除ボタン → 確認アラート後にeraseAllSavedArticlesAndReadingLists()
   └─ 同期ボタン → fullSync()
```

### フローチャート

```mermaid
flowchart TD
    A[viewDidLoad] --> B[セクション構成]
    B --> C[テーブルビュー表示]
    C --> D{ユーザー操作}
    D -->|同期スイッチON| E{ログイン済み?}
    E -->|No| F[ログイン画面表示]
    E -->|Yes| G[setSyncEnabled true]
    D -->|同期スイッチOFF| H[確認パネル表示]
    H --> I[setSyncEnabled false]
    D -->|デフォルトリストスイッチ| J[isDefaultListEnabled設定]
    D -->|削除ボタン| K[確認アラート]
    K --> L[eraseAllSavedArticlesAndReadingLists]
    D -->|同期ボタン| M{ログイン && 同期有効?}
    M -->|Yes| N[fullSync]
    M -->|No: 未ログイン| O[ログイン画面表示]
    M -->|No: 同期無効| P[同期有効化パネル]
    F --> Q[ログイン成功後にsetSyncEnabled]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-49-01 | 同期にはログイン必須 | 同期機能の有効化にはログインが必要 | 同期スイッチON時 |
| BR-49-02 | 同期無効化時の確認 | 同期無効化前にローカルデータ保持確認パネルを表示 | 同期スイッチOFF時 |
| BR-49-03 | 削除の確認 | 保存記事削除前に確認アラートを表示 | 削除ボタンタップ時 |
| BR-49-04 | 同期成功通知 | 同期後に「Reading lists will be synced in the background」を表示 | 同期実行後 |
| BR-49-05 | サーバー同期確認通知 | サーバーで同期有効化が確認されたらテーブル更新 | Notification受信時 |

### 計算ロジック

キャッシュサイズの計算：CacheController.totalCacheSizeInBytes を ByteCountFormatter でフォーマット

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 同期設定 | ReadingListsController | UPDATE | 同期有効/無効の設定 |
| デフォルトリスト設定 | ReadingListsController | UPDATE | デフォルトリスト表示設定 |
| 削除 | CoreData/Cache | DELETE | 全保存記事とリーディングリストの削除 |

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

#### ReadingListsController

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| UPDATE | isSyncEnabled | true/false | setSyncEnabled()経由 |
| UPDATE | isDefaultListEnabled | true/false | プロパティ直接設定 |
| DELETE | 全データ | - | eraseAllSavedArticlesAndReadingLists() |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 未ログイン | 同期有効化時にログインしていない | ログイン画面表示 |
| - | 同期無効 | 手動同期時に同期が無効 | 同期有効化パネル表示 |

### リトライ仕様

自動リトライは行わない。ユーザーが再度操作。

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

該当なし（ReadingListsControllerが内部で管理）

## パフォーマンス要件

- キャッシュサイズ計算は同期的に行う
- 同期処理はバックグラウンドで実行

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

- 同期機能はログイン状態を確認してから有効化
- 削除操作は確認アラートを表示
- 同期無効化時はリモートデータ削除のオプションあり

## 備考

- ItemType enum: syncSavedArticlesAndLists、showSavedReadingList、eraseSavedArticles、syncWithTheServer
- EraseSavedArticlesView: カスタムビュー（キャッシュサイズ表示と削除ボタン）
- SettingsFunnel: 同期有効/無効のイベントログ

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | StorageAndSyncingSettingsViewController.swift | `Wikipedia/Code/StorageAndSyncingSettingsViewController.swift` | Section、Item構造体、ItemType enum |

**読解のコツ**:
- **3-27行目**: Section構造体（type、footerText、items）
- **29-60行目**: Item構造体（disclosureType、type、title、isSwitchOn）
- **62-64行目**: ItemType enum（4種類の設定項目）

#### Step 2: セクション構成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | StorageAndSyncingSettingsViewController.swift | `Wikipedia/Code/StorageAndSyncingSettingsViewController.swift` | sections計算プロパティ |

**主要処理フロー**:
- **73-85行目**: sections計算プロパティ - 4つのセクションを構成

#### Step 3: スイッチ操作ハンドリングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | StorageAndSyncingSettingsViewController.swift | `Wikipedia/Code/StorageAndSyncingSettingsViewController.swift` | WMFSettingsTableViewCellDelegate実装 |

**主要処理フロー**:
- **293-340行目**: settingsTableViewCell(_:didToggleDisclosureSwitch:)
- **308-317行目**: 未ログイン時の同期スイッチON処理
- **318-333行目**: ログイン済み時の同期スイッチ処理
- **334-335行目**: デフォルトリストスイッチ処理

#### Step 4: 削除・同期処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | StorageAndSyncingSettingsViewController.swift | `Wikipedia/Code/StorageAndSyncingSettingsViewController.swift` | eraseSavedArticles、didSelectRowAt |

**主要処理フロー**:
- **157-172行目**: eraseSavedArticles() - 削除確認アラートと実行
- **246-271行目**: tableView(_:didSelectRowAt:) - 手動同期の処理

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

```
StorageAndSyncingSettingsViewController
    │
    ├─ viewDidLoad()
    │      │
    │      ├─ NotificationCenter.addObserver(readingListsServerDidConfirmSyncWasEnabledForAccountNotification)
    │      │
    │      └─ テーブルビュー設定
    │
    ├─ sections（計算プロパティ）
    │      │
    │      ├─ syncSavedArticlesAndListsSection
    │      ├─ showSavedReadingListSection
    │      ├─ eraseSavedArticlesSection
    │      └─ syncWithTheServerSection
    │
    ├─ settingsTableViewCell(_:didToggleDisclosureSwitch:)
    │      │
    │      ├─ syncSavedArticlesAndLists（未ログイン）
    │      │      └─ wmf_showLoginOrCreateAccountToSyncSavedArticlesToReadingListPanel()
    │      │
    │      ├─ syncSavedArticlesAndLists（ログイン済み）
    │      │      └─ readingListsController.setSyncEnabled()
    │      │
    │      └─ showSavedReadingList
    │             └─ readingListsController.isDefaultListEnabled = value
    │
    ├─ eraseSavedArticles()
    │      └─ UIAlertController
    │             └─ readingListsController.eraseAllSavedArticlesAndReadingLists()
    │
    └─ tableView(_:didSelectRowAt:) [syncWithTheServer]
           │
           ├─ ログイン && 同期有効
           │      └─ readingListsController.fullSync()
           │
           ├─ 未ログイン
           │      └─ wmf_showLoginOrCreateAccountToSyncSavedArticlesToReadingListPanel()
           │
           └─ 同期無効
                  └─ wmf_showEnableReadingListSyncPanel()
```

### データフロー図

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

同期スイッチ操作      ───▶ settingsTableViewCell delegate
                           │
                           ▼
                    {ログイン状態確認}
                           │
              ┌────────────┴────────────┐
              ▼                         ▼
        未ログイン                  ログイン済み
              │                         │
              ▼                         ▼
        ログイン画面          ReadingListsController.setSyncEnabled()
              │                         │
              └──────────┬──────────────┘
                         ▼
                  テーブルビュー更新

削除ボタン           ───▶ eraseSavedArticles()
                           │
                           ▼
                    確認アラート
                           │
                           ▼
                    ReadingListsController.eraseAllSavedArticlesAndReadingLists()
                           │
                           ▼
                    CacheController（キャッシュ削除）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| StorageAndSyncingSettingsViewController.swift | `Wikipedia/Code/StorageAndSyncingSettingsViewController.swift` | ソース | ストレージ・同期設定画面 |
| ReadingListsController.swift | `WMF Framework/ReadingListsController.swift` | ソース | リーディングリスト同期管理 |
| CacheController.swift | `WMF Framework/CacheController.swift` | ソース | キャッシュ管理 |
| EraseSavedArticlesView.swift | `Wikipedia/Code/EraseSavedArticlesView.swift` | ソース | 削除ボタンカスタムビュー |
| SettingsFunnel.swift | `Wikipedia/Code/SettingsFunnel.swift` | ソース | 設定イベントログ |
