# 帳票設計書 1-Year in Review Standard Shareable

## 概要

本ドキュメントは、Wikipedia iOSアプリケーションにおける「Year in Review Standard Shareable」帳票の設計仕様を定義する。この帳票はユーザーの年間読書活動統計を共有可能な画像として生成する機能を提供する。

### 本帳票の処理概要

本帳票は、ユーザーの年間Wikipedia閲覧活動を視覚的に表現した共有可能な画像を生成する機能である。

**業務上の目的・背景**：Wikipediaアプリのユーザーエンゲージメント向上を目的として、年末に一年間の読書活動を振り返り、SNS等で共有できる画像を提供する。ユーザーは自身の学習活動を可視化し、コミュニティと共有することで、Wikipedia利用のモチベーション維持と新規ユーザーの獲得に貢献する。

**帳票の利用シーン**：年末年始のYear in Review機能において、ユーザーが各スライドの内容をソーシャルメディアや友人と共有したい場合に使用される。読書統計、編集統計、保存記事数などの年間活動サマリーを画像として出力し、TwitterやFacebook等でシェアできる。

**主要な出力内容**：
1. Wikipediaロゴ（W-share-logo）とヘッダー部
2. スライドに応じたGIF画像（puzzle-walk、clock、sky、duo等）
3. タイトルテキスト（例：読んだ記事数、編集数等）
4. サブタイトルテキスト（HTML/Markdown対応の詳細説明）
5. フッター部（globeアイコン、ハッシュタグ）

**帳票の出力タイミング**：Year in Review画面の各スライド表示中に、ユーザーが「Share」ボタンをタップした時点で画像が生成される。

**帳票の利用者**：Wikipediaアプリの一般ユーザー（ログイン・非ログイン問わず）

## 帳票種別

共有画像（ソーシャルメディア共有用カード画像）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | Year in Review Slide View | WMFYearInReviewView | Shareボタンタップ |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | PNG（UIImage） |
| 用紙サイズ | 402 x 847ポイント（最小高さ） |
| 向き | 縦 |
| ファイル名 | システム生成（UIActivityViewController経由） |
| 出力方法 | UIActivityViewController（共有シート） |
| 文字コード | UTF-8 |

### 画像固有設定

| 項目 | 内容 |
|-----|------|
| スケール | UIScreen.main.scale（デバイス解像度対応） |
| 背景色 | theme.paperBackground |
| レンダリング | SwiftUI ImageRenderer |

## 帳票レイアウト

### レイアウト概要

縦長のカード形式で、ヘッダー、コンテンツ、フッターの3部構成となっている。

```
┌─────────────────────────────────────┐
│         W-share-logo (50pt)         │
│              ヘッダー部               │
├─────────────────────────────────────┤
│                                     │
│         GIF画像（スライド内容）         │
│                                     │
├─────────────────────────────────────┤
│         タイトル（boldTitle1）        │
│         サブタイトル（body）           │
│              明細部                  │
├─────────────────────────────────────┤
│  [globe]  #WikipediaYearInReview    │
│              フッター部               │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | Wikipediaロゴ | W-share-logoアセット | Bundle.module | Image 50pt高さ |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | GIF画像 | スライド種別に応じた画像 | viewModel.gifName | 可変幅、アスペクト比維持 | 全幅 |
| 2 | タイトル | スライドのメインタイトル | viewModel.title | boldTitle1フォント | 全幅-56pt |
| 3 | サブタイトル | 詳細説明テキスト | viewModel.subtitle | body/HTML/Markdown | 全幅-56pt |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | Globeアイコン | 地球儀アイコン | Bundle.module | 50x50pt |
| 2 | ハッシュタグ | キャンペーンタグ | hashtag | boldTitle3、リンク色 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| viewModel | WMFYearInReviewSlideViewModelProtocol準拠のデータ | Yes |
| hashtag | 共有用ハッシュタグ文字列 | Yes |
| needsMarkdownSubtitle | Markdownサブタイトル使用フラグ | No |

### ソート順

該当なし（単一画像出力のため）

### 改ページ条件

該当なし（単一画像出力のため）

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| CDYearInReviewReport | 年間レポートデータ | year = 対象年 |
| CDYearInReviewSlide | スライドデータ | report.year = 対象年 |

### テーブル別参照項目詳細

#### CDYearInReviewReport

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| year | 対象年度 | Int32 | WMFYearInReviewDataController.targetYear |
| slides | スライド一覧 | relationship | Cascade削除 |

#### CDYearInReviewSlide

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| id | スライドID | String | WMFYearInReviewPersonalizedSlideID.rawValue |
| data | スライドデータ | Binary | JSON形式でエンコード |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| 画像スケール | UIScreen.main.scale | - | デバイス解像度に応じた値 |
| 提案サイズ幅 | 402ポイント固定 | - | レンダラー設定 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[Shareボタンタップ] --> B[tappedShare呼び出し]
    B --> C{スライドタイプ判定}
    C -->|standard| D[WMFYearInReviewSlideStandardShareableView生成]
    D --> E[ImageRenderer初期化]
    E --> F[proposedSize設定 402x nil]
    F --> G[scale設定 UIScreen.main.scale]
    G --> H[renderer.uiImage取得]
    H --> I{画像生成成功?}
    I -->|Yes| J[coordinatorDelegate.share呼び出し]
    I -->|No| K[処理終了]
    J --> L[UIActivityViewController表示]
    L --> M[終了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 画像生成失敗 | renderer.uiImageがnil | なし（サイレント失敗） | 処理を中断、ユーザー操作を待つ |
| viewModel不正 | 必須プロパティ欠落 | なし | コンパイル時に検出 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1件/回 |
| 目標出力時間 | 1秒以内 |
| 同時出力数上限 | 1件 |

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

- 個人情報：ユーザーの読書統計を含むが、ユーザー自身が共有を選択した場合のみ出力される
- アクセス制御：ユーザーの明示的な操作（Shareボタンタップ）が必要
- 出力ログ：loggingDelegateを通じてlogYearInReviewDidTapShareで記録

## 備考

- SwiftUI ImageRendererを使用してビューを画像に変換
- テーマに応じた色設定（light/dark mode対応）
- HTML/Markdown形式のサブタイトルに対応
- needsMarkdownSubtitleフラグにより表示形式を切り替え

---

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

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

### 推奨読解順序

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

まず、プログラム間で受け渡されるデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | WMFYearInReviewSlideStandardViewModel.swift | `WMFComponents/Sources/WMFComponents/Components/Year in Review/View Models/WMFYearInReviewSlideStandardViewModel.swift` | ViewModelのプロパティ構成（gifName, title, subtitle, subtitleType）を理解する |
| 1-2 | WMFYearInReviewSlideViewModelProtocol | `WMFComponents/Sources/WMFComponents/Components/Year in Review/Views/Shareable Slide Views/WMFYearInReviewSlideStandardShareableView.swift` 行105-109 | プロトコル定義（gifName, subtitle, title）を確認 |

**読解のコツ**: SwiftUIのViewModelパターンを理解し、プロトコル準拠による多態性を把握する。

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

処理の起点となるファイル・関数を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | WMFYearInReviewViewModel.swift | `WMFComponents/Sources/WMFComponents/Components/Year in Review/View Models/WMFYearInReviewViewModel.swift` | tappedShare()関数（行953-1018）が共有処理のエントリーポイント |

**主要処理フロー**:
1. **行953-954**: @MainActor tappedShare()関数開始、currentSlideを取得
2. **行955-964**: standardスライドの場合、needsMarkdownSubtitleフラグを判定
3. **行965-971**: WMFYearInReviewSlideStandardShareableViewを生成し、ImageRendererで画像化

#### Step 3: 共有可能ビューの構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | WMFYearInReviewSlideStandardShareableView.swift | `WMFComponents/Sources/WMFComponents/Components/Year in Review/Views/Shareable Slide Views/WMFYearInReviewSlideStandardShareableView.swift` | SwiftUIビューの構造（body、レイアウト）を理解 |

**主要処理フロー**:
- **行34-101**: body定義 - VStackによる縦並びレイアウト
- **行36-51**: ヘッダー部（ロゴ、GIF画像）
- **行53-71**: コンテンツ部（タイトル、サブタイトル）
- **行78-96**: フッター部（globe、ハッシュタグ）

#### Step 4: 画像レンダリング処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | WMFYearInReviewViewModel.swift | `WMFComponents/Sources/WMFComponents/Components/Year in Review/View Models/WMFYearInReviewViewModel.swift` 行966-971 | ImageRenderer使用方法 |

**主要処理フロー**:
- **行966**: ImageRenderer(content: view)でレンダラー初期化
- **行967**: proposedSize設定（幅402、高さ自動）
- **行968**: scale設定（デバイス解像度）
- **行969-971**: uiImage取得、成功時にcoordinatorDelegate.share呼び出し

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

```
WMFYearInReviewView (UI)
    │
    ├─ WMFYearInReviewViewModel.tappedShare()
    │      │
    │      ├─ WMFYearInReviewSlideStandardShareableView(viewModel:hashtag:needsMarkdownSubtitle:)
    │      │      │
    │      │      └─ body: View
    │      │             ├─ Image("W-share-logo")
    │      │             ├─ Image(viewModel.gifName)
    │      │             ├─ Text(viewModel.title)
    │      │             ├─ Text(viewModel.subtitle) or Text(attributedString)
    │      │             └─ HStack [globe + hashtag]
    │      │
    │      ├─ ImageRenderer(content: view)
    │      │      └─ renderer.uiImage
    │      │
    │      └─ coordinatorDelegate.handleYearInReviewAction(.share(image:))
    │
    └─ UIActivityViewController (システム共有シート)
```

### データフロー図

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

viewModel ─────────────▶ WMFYearInReviewSlide             ユーザー共有先
  │                      StandardShareableView ─────────▶ (Twitter/Facebook等)
  ├─ gifName                    │
  ├─ title                      ▼
  └─ subtitle            ImageRenderer
                               │
hashtag ──────────────────────▶│
                               ▼
                          UIImage
                               │
                               ▼
                    UIActivityViewController
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| WMFYearInReviewSlideStandardShareableView.swift | `WMFComponents/Sources/WMFComponents/Components/Year in Review/Views/Shareable Slide Views/` | ソース | 共有用ビュー定義 |
| WMFYearInReviewSlideStandardViewModel.swift | `WMFComponents/Sources/WMFComponents/Components/Year in Review/View Models/` | ソース | スライドデータモデル |
| WMFYearInReviewViewModel.swift | `WMFComponents/Sources/WMFComponents/Components/Year in Review/View Models/` | ソース | 共有処理ロジック |
| View+SnapshotUIImage.swift | `WMFComponents/Sources/WMFComponents/Extensions/` | ソース | UIImage変換拡張 |
| WMFYearInReviewReport.swift | `WMFData/Sources/WMFData/Models/Year In Review/` | ソース | レポートモデル |
| WMFData 5.xcdatamodel | `WMFData/Sources/WMFData/Resources/WMFData.xcdatamodeld/` | 設定 | Core Dataモデル定義 |
