# 画面設計書 26-投稿分析画面

## 概要

Ghost管理画面における個別投稿のアナリティクス画面（apps/posts）のメイン画面設計書である。特定の投稿に対するWebトラフィック、成長貢献、ニュースレター配信パフォーマンスを詳細に分析できる。

### 本画面の処理概要

投稿分析画面は、個別の投稿/ページのパフォーマンスを多角的に分析するためのReactアプリケーションである。

**業務上の目的・背景**：コンテンツ制作者が個々の投稿のパフォーマンスを把握し、どのコンテンツが読者に響いているかを理解するために使用する。投稿ごとのWebトラフィック、メンバー獲得への貢献、ニュースレターとしての配信効果を一元的に確認でき、コンテンツ戦略の改善に活用できる。

**画面へのアクセス方法**：投稿一覧画面の投稿メニューから「Analytics」を選択、またはサイト統計画面のトップコンテンツ一覧から投稿をクリックすることでアクセスする。URLは `/posts/analytics/:postId` となり、Ember.js管理画面からReactアプリ（apps/posts）がマイクロフロントエンドとして埋め込まれる。

**主要な操作・処理内容**：
1. Overview（概要）、Web（トラフィック）、Growth（成長）、Newsletter（ニュースレター）の各タブへの切り替え
2. 日付範囲の選択による分析期間の変更
3. 各種KPI（訪問者数、メンバー獲得数、開封率など）の確認
4. 投稿公開成功時のシェアモーダル表示

**画面遷移**：
- 遷移元：投稿一覧画面、統計概要画面、成長分析画面、ニュースレター分析画面
- 遷移先：投稿分析概要画面（/posts/analytics/:postId）、投稿Webトラフィック画面（/posts/analytics/:postId/web）、投稿成長分析画面（/posts/analytics/:postId/growth）、投稿ニュースレター分析画面（/posts/analytics/:postId/newsletter）、メンバー一覧画面（/members）

**権限による表示制御**：投稿の公開状態により表示内容が変わる。メールのみの投稿（email_only）の場合、Web分析画面は非表示。ニュースレター配信されていない投稿の場合、Newsletter画面は非表示。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 52 | 記事分析 | 主機能 | 個別投稿のアナリティクス表示 |
| 55 | Tinybird連携 | 補助機能 | Tinybirdからのアナリティクスデータ取得 |

## 画面種別

ダッシュボード / 分析

## URL/ルーティング

| パス | コンポーネント | 説明 |
|------|---------------|------|
| `/ghost/#/posts-x/posts/analytics/:postId` | PostAnalytics | 投稿分析画面（Ember側） |
| `/posts/analytics/:postId` | PostAnalytics | 投稿分析概要画面（デフォルト） |
| `/posts/analytics/:postId/web` | Web | 投稿Webトラフィック画面 |
| `/posts/analytics/:postId/growth` | Growth | 投稿成長分析画面 |
| `/posts/analytics/:postId/newsletter` | Newsletter | 投稿ニュースレター分析画面 |

## 入出力項目

### 入力項目

| 項目名 | 項目ID | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| 投稿ID | postId | string | Yes | URLパラメータ（投稿のID） |
| 日付範囲 | range | number | No | 分析期間 |

### 出力項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| 投稿情報 | Post | 投稿の詳細データ |
| 訪問者数 | number | 投稿への訪問者数 |
| メンバー獲得数 | number | 投稿から獲得したメンバー数 |
| 開封率 | number | ニュースレター開封率 |
| クリック率 | number | ニュースレターリンククリック率 |

## 表示項目

### 投稿データ（Post型）

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| id | string | 投稿ID |
| uuid | string | 投稿UUID（Tinybirdクエリ用） |
| title | string | 投稿タイトル |
| published_at | string | 公開日時 |
| email_only | boolean | メールのみ配信フラグ |
| email | object | メール配信情報（opened_count, email_count等） |
| newsletter | object | ニュースレター設定 |
| count | object | 各種カウント（feedback, clicks等） |
| authors | array | 著者一覧 |
| tags | array | タグ一覧 |

## イベント仕様

### 1-タブ切り替え

**トリガー**: Overview/Web/Growth/Newsletterタブをクリック

**処理フロー**:
1. React RouterのNavLinkがクリックされる
2. URLが更新される（/posts/analytics/:postId/[web|growth|newsletter]）
3. Outletコンポーネントが対応するビューをレンダリング

### 2-日付範囲変更

**トリガー**: DateRangeSelectで期間を選択

**処理フロー**:
1. PostAnalyticsContextのsetRange関数が呼び出される
2. rangeステートが更新される
3. 各ビューのuseTinybirdQueryが新しいparamsで再実行

### 3-投稿シェアモーダル表示

**トリガー**: 投稿公開成功後のURLパラメータ検知

**処理フロー**:
1. usePostSuccessModalフックがURLパラメータを検知
2. isModalOpenがtrueになる
3. PostShareModalコンポーネントが表示される

**関連コード**: `apps/posts/src/views/PostAnalytics/post-analytics.tsx` 7-8, 12-14行目

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | posts | SELECT | 投稿詳細データ取得 |
| 画面表示 | - | SELECT | Tinybird APIからアナリティクスデータ取得 |

### API呼び出し詳細

#### Ghost API

| エンドポイント | パラメータ | 用途 |
|---------------|-----------|------|
| /ghost/api/admin/posts/ | filter:id, include:email,authors,tags,tiers,count.* | 投稿詳細取得 |
| /ghost/api/admin/stats/referrers/posts/:postId | - | 投稿リファラー取得 |
| /ghost/api/admin/links/ | filter:post_id | リンククリック統計取得 |

#### Tinybird API

| エンドポイント | パラメータ | 用途 |
|---------------|-----------|------|
| api_kpis | site_uuid, post_uuid, date_from, date_to | 投稿KPIデータ |
| api_top_sources | site_uuid, post_uuid, date_from, date_to | 投稿ソース別データ |
| api_top_locations | site_uuid, post_uuid, date_from, date_to | 投稿地域別データ |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| - | 情報 | No visitors {period} | Webデータがない場合 |
| - | 情報 | You have no links in your post | ニュースレターにリンクがない場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 投稿IDなし | PostAnalyticsProviderでエラーthrow |
| 投稿が見つからない | ErrorPageコンポーネント表示 |
| email_only投稿でWeb画面アクセス | Overviewにリダイレクト |
| ニュースレター未配信でNewsletter画面アクセス | Overviewにリダイレクト |
| webAnalytics無効でpublished_only投稿 | Growthにリダイレクト |

## 備考

- 投稿データはPostAnalyticsContextで一元管理され、すべての子画面で共有される
- チャートの日付範囲は投稿の公開日から自動計算される（getRangeForStartDate）
- statsConfigがない場合（Tinybird未設定）、一部のデータは表示されない
- PostShareModalは投稿公開直後のみ表示される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | post-analytics-context.tsx | `apps/posts/src/providers/post-analytics-context.tsx` | Post型、PostAnalyticsContextType定義（11-52行目） |
| 1-2 | constants.ts | `apps/posts/src/utils/constants.ts` | STATS_RANGES定数 |

**読解のコツ**: Post型がPostBaseを拡張しており、email/newsletter/count等のincludeフィールドを含む。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | routes.tsx | `apps/posts/src/routes.tsx` | /posts/analytics/:postIdルート定義（18-54行目） |
| 2-2 | post-analytics.tsx | `apps/posts/src/views/PostAnalytics/post-analytics.tsx` | PostAnalyticsコンポーネント |
| 2-3 | post-analytics-context.tsx | `apps/posts/src/providers/post-analytics-context.tsx` | PostAnalyticsProvider |

**主要処理フロー**:
1. **routes.tsx 20-34行目**: PostAnalyticsProviderとPostAnalyticsを動的インポート
2. **post-analytics-context.tsx 64-127行目**: postId取得、設定/サイト/投稿データ取得
3. **post-analytics.tsx 6-18行目**: PostAnalyticsLayoutでラップし、Outletで子ルート表示

#### Step 3: レイアウトコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | post-analytics-layout.tsx | `apps/posts/src/views/PostAnalytics/components/layout/post-analytics-layout.tsx` | 全体レイアウト |
| 3-2 | post-analytics-header.tsx | `apps/posts/src/views/PostAnalytics/components/post-analytics-header.tsx` | ヘッダー・タブナビゲーション |
| 3-3 | post-analytics-content.tsx | `apps/posts/src/views/PostAnalytics/components/post-analytics-content.tsx` | コンテンツエリア |
| 3-4 | sidebar.tsx | `apps/posts/src/views/PostAnalytics/components/sidebar.tsx` | サイドバー（投稿情報） |

#### Step 4: カスタムフックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | use-post-referrers.ts | `apps/posts/src/hooks/use-post-referrers.ts` | 投稿リファラーデータ取得 |
| 4-2 | use-post-newsletter-stats.ts | `apps/posts/src/hooks/use-post-newsletter-stats.ts` | 投稿ニュースレター統計取得 |
| 4-3 | use-post-success-modal.ts | `apps/posts/src/hooks/use-post-success-modal.ts` | シェアモーダル制御 |

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

```
Route: /posts/analytics/:postId
    │
    ├─ PostAnalyticsProvider (context)
    │      ├─ useBrowseConfig()
    │      ├─ useBrowseSite()
    │      ├─ useBrowseSettings()
    │      ├─ useTinybirdToken()
    │      └─ useBrowsePosts({filter: `id:${postId}`})
    │
    └─ PostAnalytics (component)
           ├─ usePostSuccessModal()
           ├─ PostAnalyticsLayout
           │      ├─ PostAnalyticsHeader
           │      │      └─ Tab Navigation (Overview/Web/Growth/Newsletter)
           │      ├─ PostAnalyticsSidebar
           │      │      └─ 投稿情報表示
           │      └─ PostAnalyticsContent
           │             └─ Outlet (子ルート)
           │
           └─ PostShareModal (条件付き表示)
```

### データフロー図

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

postId (URLパラメータ) ────▶ PostAnalyticsProvider ────▶ Context Value
                                    │
                           useBrowsePosts({filter})
                                    │
                                    ▼
                              post, isPostLoading
                                    │
                           useTinybirdToken()
                                    │
                                    ▼
                              statsConfig, token
                                    │
                                    ▼
                        useGlobalData() (各子コンポーネント)
                                    │
                                    ▼
                        各ビュー（Overview/Web/Growth/Newsletter）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| app.tsx | `apps/posts/src/app.tsx` | ソース | アプリケーションルート |
| routes.tsx | `apps/posts/src/routes.tsx` | ソース | ルーティング定義 |
| post-analytics-context.tsx | `apps/posts/src/providers/post-analytics-context.tsx` | ソース | 投稿分析コンテキスト |
| post-analytics.tsx | `apps/posts/src/views/PostAnalytics/post-analytics.tsx` | ソース | 投稿分析メイン |
| post-analytics-layout.tsx | `apps/posts/src/views/PostAnalytics/components/layout/post-analytics-layout.tsx` | ソース | レイアウト |
| post-analytics-header.tsx | `apps/posts/src/views/PostAnalytics/components/post-analytics-header.tsx` | ソース | ヘッダー |
| post-analytics-content.tsx | `apps/posts/src/views/PostAnalytics/components/post-analytics-content.tsx` | ソース | コンテンツ |
| sidebar.tsx | `apps/posts/src/views/PostAnalytics/components/sidebar.tsx` | ソース | サイドバー |
| overview.tsx | `apps/posts/src/views/PostAnalytics/Overview/overview.tsx` | ソース | 概要画面 |
| web.tsx | `apps/posts/src/views/PostAnalytics/Web/web.tsx` | ソース | Web画面 |
| growth.tsx | `apps/posts/src/views/PostAnalytics/Growth/growth.tsx` | ソース | 成長画面 |
| newsletter.tsx | `apps/posts/src/views/PostAnalytics/Newsletter/newsletter.tsx` | ソース | ニュースレター画面 |
| posts-x.hbs | `ghost/admin/app/templates/posts-x.hbs` | テンプレート | Ember側エントリーポイント |
