# 画面設計書 76-マイグレーション画面

## 概要

本ドキュメントは、他プラットフォームからGhostへのデータ移行画面の設計書です。

### 本画面の処理概要

この画面は、他のブログ・CMSプラットフォーム（WordPress、Substack等）からGhostへコンテンツを移行するためのセルフサービスマイグレーションツールを提供します。外部サービス（migrate.ghost.org）をiframeで埋め込み、ステップバイステップでマイグレーションを実行します。

**業務上の目的・背景**：既存のブログやニュースレターサービスからGhostへの移行を促進するため、本画面は包括的なセルフサービスマイグレーション機能を提供します。技術的な知識なしに、ユーザーは投稿、ページ、購読者、購読情報などを既存プラットフォームからインポートできます。これにより、新規ユーザーの獲得と、他プラットフォームからの移行障壁を低減します。

**画面へのアクセス方法**：設定画面のマイグレーションツールから、またはURLに直接 `/migrate` と入力してアクセスします。プラットフォームパラメータを指定して特定のマイグレーションツールを起動できます。

**主要な操作・処理内容**：
1. マイグレーションプラットフォームの選択
2. 移行元データのアップロード/接続
3. マイグレーションの実行
4. 完了後の確認

**画面遷移**：
- 遷移元：設定画面のマイグレーションツール
- 遷移先：設定画面のマイグレーションセクション（/settings/migration）

**権限による表示制御**：オーナーまたは管理者（isAdmin）のみがこの画面にアクセス可能です。それ以外のユーザーはホーム画面にリダイレクトされます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 65 | データベース管理 | 主機能 | 他プラットフォームからのデータ移行 |

## 画面種別

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

## URL/ルーティング

- パス: `/migrate`
- パス（プラットフォーム指定）: `/migrate?platform=wordpress`
- ルート定義: `ghost/admin/app/routes/migrate.js`

## 入出力項目

| 項目名 | 入出力 | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| platform | 入力 | string | - | 移行元プラットフォーム（クエリパラメータ） |
| apiUrl | 出力 | string | - | GhostサイトのAPI URL |
| apiKey | 出力 | string | - | self-serve-migrationインテグレーションのAPIキー |
| ownerEmail | 出力 | string | - | オーナーユーザーのメールアドレス |
| stripe | 出力 | boolean | - | Stripe連携の有無 |
| ghostVersion | 出力 | string | - | Ghostのバージョン |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| 閉じるボタン | - | マイグレーション画面を閉じる |
| gh-migrate-modal | component | マイグレーションモーダル（iframe埋め込み） |
| migrate-frame | iframe | migrate.ghost.org埋め込みiframe |

## イベント仕様

### 1-マイグレーション画面表示

- トリガー: `/migrate` ルートへのアクセス
- 前提条件: ユーザーがisAdmin（オーナーまたは管理者）
- 処理:
  1. `beforeModel()` で権限チェック
  2. 非管理者の場合はホーム画面へリダイレクト
  3. iframeのsrcを設定（プラットフォームパラメータ含む）
  4. postMessageでマイグレーションサービスにペイロードを送信

### 2-postMessageペイロード送信

- トリガー: iframe読み込み完了
- 処理:
  1. `apiKey()` でself-serve-migrationインテグレーションのキーを取得
  2. `getOwnerUser()` でオーナーユーザー情報を取得
  3. ペイロードを構築（apiUrl, apiKey, stripe, ghostVersion, ownerEmail）
  4. `postMessage` でiframeにペイロードを送信

### 3-マイグレーション画面クローズ

- トリガー: 閉じるボタンクリック
- 処理:
  1. `closeMigrateWindow()` を呼び出し
  2. `/settings/migration` へ遷移
  3. `migrateWindowOpen` を `false` に設定

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | integrations | SELECT | self-serve-migrationインテグレーションの取得 |
| 画面表示 | users | SELECT | オーナーユーザー情報の取得 |

※ 実際のマイグレーション処理はmigrate.ghost.orgサービス側およびGhost Admin APIで処理

## メッセージ仕様

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

## 例外処理

| 例外状況 | 対応内容 |
|---------|---------|
| 非管理者アクセス | ホーム画面へリダイレクト |
| インテグレーション未設定 | エラー（self-serve-migrationインテグレーションが必須） |
| iframe読み込みエラー | migrate.ghost.orgサービス側のエラー処理に依存 |

## 備考

- マイグレーションサービスは外部サービス（https://migrate.ghost.org）として動作
- postMessage APIを使用してiframeとの認証情報共有を実現
- Stripe連携状態を送信し、有料購読のマイグレーション可否を判定
- オーナーメールアドレスは、マイグレーション完了通知等に使用

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | migrate.js (service) | `ghost/admin/app/services/migrate.js` | postMessagePayloadの構造（L43-56） |

**読解のコツ**: `postMessagePayload`で送信されるデータ構造（apiUrl, apiKey, stripe, ghostVersion, ownerEmail）を理解することが重要です。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | migrate.js (route) | `ghost/admin/app/routes/migrate.js` | ルート定義と権限チェック |
| 2-2 | migrate.hbs | `ghost/admin/app/templates/migrate.hbs` | テンプレート構造 |

**主要処理フロー**:
1. **migrate.js (route) L8-14**: beforeModelで権限チェック（isAdmin以外はリダイレクト）
2. **migrate.hbs L1-8**: 閉じるボタンとマイグレーションモーダル表示

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | migrate.js (service) | `ghost/admin/app/services/migrate.js` | マイグレーションサービスの実装 |

**主要処理フロー**:
- **L12-13**: 定数定義（migrateUrl, migrateRouteRoot）
- **L21-28**: apiUrlの生成
- **L30-41**: apiKey()でインテグレーションキー取得
- **L43-56**: postMessagePayload()でペイロード構築
- **L58-59**: isStripeConnectedでStripe連携状態確認
- **L70-78**: getIframeURL()でiframe URL生成
- **L80-87**: sendRouteUpdate()でルート更新
- **L92-98**: toggleMigrateWindow()で表示制御
- **L104-118**: openMigrateWindow()でウィンドウオープン
- **L120-124**: closeMigrateWindow()でウィンドウクローズ

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

```
MigrateRoute (Ember Route)
    |
    +-- beforeModel()
    |       +-- session.user.isAdmin check
    |       +-- (if not admin) transitionTo('home')
    |
    +-- MigrateService
            |
            +-- postMessagePayload()
            |       +-- apiKey()
            |       |       +-- ajax.request('/integrations')
            |       |       +-- find 'self-serve-migration'
            |       |
            |       +-- billing.getOwnerUser()
            |       +-- isStripeConnected
            |       +-- ghostVersion
            |
            +-- getIframeURL()
            |       +-- router.currentRoute.params.platform
            |
            +-- closeMigrateWindow()
                    +-- router.transitionTo('/settings/migration')
                    +-- toggleMigrateWindow(false)
```

### データフロー図

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

/migrate?platform=wordpress アクセス
    |
    +-- isAdmin チェック --> (false) --> /home リダイレクト
    |
    +-- (true) --> getIframeURL() -----------------> iframe URL生成
                        |
                        +-- postMessagePayload() --> apiKey取得
                                |                    ownerUser取得
                                |                    Stripe状態確認
                                |
                                +-- iframe.postMessage() --> migrate.ghost.org
                                                                |
                                                                +-- マイグレーション処理
                                                                        |
閉じるボタンクリック                                                     |
    |                                                                   |
    +-- closeMigrateWindow() --> /settings/migration へ遷移
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| migrate.js (route) | `ghost/admin/app/routes/migrate.js` | ソース | マイグレーションルート定義 |
| migrate.hbs | `ghost/admin/app/templates/migrate.hbs` | テンプレート | マイグレーション画面テンプレート |
| migrate.js (service) | `ghost/admin/app/services/migrate.js` | ソース | マイグレーションサービス（iframe制御） |
| gh-migrate-modal.js | `ghost/admin/app/components/gh-migrate-modal.js` | ソース | マイグレーションモーダルコンポーネント |
| billing.js (service) | `ghost/admin/app/services/billing.js` | ソース | オーナーユーザー取得に使用 |
