# 画面設計書 74-Explore画面

## 概要

本ドキュメントは、Ghost Exploreとの連携画面の設計書です。

### 本画面の処理概要

この画面は、Ghost Exploreディレクトリサービスとの連携を管理する画面です。Ghost Exploreは、Ghostで構築されたサイトのディレクトリであり、サイトの露出を増やすためのマーケティングツールとして機能します。本画面はiframeを通じてGhost Exploreの外部サービスを埋め込み表示します。

**業務上の目的・背景**：Ghost Exploreは、Ghostエコシステム全体でサイトを宣伝するためのディレクトリサービスです。サイト管理者はこの機能を使ってGhostコミュニティ内でのサイトの露出を高め、新しい読者・購読者を獲得できます。本画面は、ExploreサービスへのシームレスなアクセスをGhost管理画面内から提供します。

**画面へのアクセス方法**：管理画面のメニューから「Explore」を選択するか、URLに直接 `/explore` と入力してアクセスします。

**主要な操作・処理内容**：
1. Ghost Exploreサービスのiframeでの表示
2. サイト情報のExploreへの送信（接続時）
3. iframe内でのルーティング同期

**画面遷移**：
- 遷移元：管理画面のナビゲーション、統計画面
- 遷移先：Explore接続画面（/explore/connect）
- iframe内部：Ghost Exploreの各種ページ

**権限による表示制御**：認証済みユーザーのみがアクセス可能です。Force Upgrade状態の場合はExplore iframeは開きません。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 91 | Explore連携 | 主機能 | Ghost Exploreとの連携・閲覧 |

## 画面種別

iframe埋め込み（外部サービス連携）

## URL/ルーティング

- パス: `/explore`
- ルート定義: `ghost/admin/app/routes/explore.js`

## 入出力項目

| 項目名 | 入出力 | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| integrations | 出力 | Integration[] | - | サイトのインテグレーション一覧（ghost-explore含む） |

## 表示項目

### メイン画面

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| explore-frame | iframe | Ghost Explore埋め込みiframe |

## イベント仕様

### 1-Exploreウィンドウ表示

- トリガー: `/explore` ルートへのアクセス
- 処理:
  1. ExploreServiceの`openExploreWindow()` を呼び出し
  2. iframeのsrcを設定（未設定の場合）
  3. `exploreWindowOpen` を `true` に設定
  4. ブラウザURLを `/explore` に同期

### 2-iframe内ルート変更

- トリガー: iframe内でのナビゲーション（postMessage経由）
- 処理:
  1. `handleRouteChangeInIframe()` でルート情報を受信
  2. ブラウザの履歴を更新（`window.history.replaceState`）
  3. Ghost Admin側のURLを同期

### 3-Exploreウィンドウクローズ

- トリガー: 別のルートへの遷移
- 処理:
  1. `toggleExploreWindow(false)` を呼び出し
  2. `exploreWindowOpen` を `false` に設定

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Explore画面表示 | integrations | SELECT | ghost-exploreインテグレーションの取得 |

※ 主な操作はiframe内のGhost Exploreサービス側で処理

## メッセージ仕様

本画面固有のメッセージはありません（iframeコンテンツはGhost Exploreサービスが管理）。

## 例外処理

| 例外状況 | 対応内容 |
|---------|---------|
| Force Upgrade状態 | Explore iframeを開かない |
| iframe読み込みエラー | Ghost Exploreサービス側のエラー処理に依存 |

## 備考

- Ghost Exploreは外部サービス（https://ghost.org/explore/）として動作
- postMessage APIを使用してiframeとの通信を実現
- ルーティングはGhost AdminとExplore間で同期される
- セキュリティのためメッセージ送受信はイベントベースで制御

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | explore.js (service) | `ghost/admin/app/services/explore.js` | ExploreServiceの状態管理プロパティ |

**読解のコツ**: `exploreWindowOpen`, `isIframeTransition`, `siteData` の追跡プロパティが重要です。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | explore.js (route) | `ghost/admin/app/routes/explore.js` | ルート定義とモデル取得 |

**主要処理フロー**:
1. **L4-5**: AuthenticatedRouteを継承
2. **L7-9**: `model()` でインテグレーション一覧を取得

#### Step 3: サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | explore.js (service) | `ghost/admin/app/services/explore.js` | iframeの制御とルーティング |

**主要処理フロー**:
- **L12-15**: 定数定義（exploreUrl, exploreRouteRoot, submitRoute）
- **L20-27**: apiUrlの生成
- **L29-42**: iframeURLの生成
- **L44-53**: postMessage受信リスナーの設定
- **L56-71**: iframe内ルート変更ハンドラー
- **L74-81**: sendRouteUpdate - iframe へのルート更新送信
- **L93-104**: toggleExploreWindow - ウィンドウ表示制御
- **L106-125**: openExploreWindow - ウィンドウオープン処理
- **L127-131**: ensureIframeIsLoaded - iframe初期化

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

```
ExploreRoute (Ember Route)
    |
    +-- model()
    |       +-- store.findAll('integration')
    |
    +-- ExploreService
            |
            +-- openExploreWindow()
            |       +-- ensureIframeIsLoaded()
            |       +-- toggleExploreWindow(true)
            |       +-- router.transitionTo('/explore')
            |
            +-- handleRouteChangeInIframe(route)
            |       +-- window.history.replaceState()
            |
            +-- toggleExploreWindow(value)
            |
            +-- sendRouteUpdate(route)
                    +-- iframe.postMessage()
```

### データフロー図

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

/explore アクセス
    |
    +-- AuthenticatedRoute --> model() -----------------> integrations取得
    |
    +-- ExploreService ----> openExploreWindow() ------> iframeのsrc設定
                                 |                        exploreWindowOpen = true
                                 |
                                 +-- iframe表示
                                        |
                                        +-- postMessage <--> Ghost Explore
                                                |
                                                +-- handleRouteChangeInIframe()
                                                        |
                                                        +-- URL同期
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| explore.js (route) | `ghost/admin/app/routes/explore.js` | ソース | Exploreルート定義 |
| explore.js (service) | `ghost/admin/app/services/explore.js` | ソース | Exploreサービス（iframe制御） |
| explore.js (controller) | `ghost/admin/app/controllers/explore.js` | ソース | Exploreコントローラー |
| connect.hbs | `ghost/admin/app/templates/explore/connect.hbs` | テンプレート | 接続画面テンプレート |
| connect.js | `ghost/admin/app/routes/explore/connect.js` | ソース | 接続画面ルート |
