# 画面設計書 73-ウェルカム画面

## 概要

本ドキュメントは、ActivityPub連携機能におけるオンボーディング（ウェルカム）画面の設計書です。

### 本画面の処理概要

この画面は、ActivityPub（ソーシャルWeb）連携を初めて使用するユーザー向けのオンボーディングフローを提供します。3つのステップで構成され、ソーシャルウェブの概念と機能を視覚的に説明します。

**業務上の目的・背景**：ActivityPub連携はGhostの新機能であり、従来のブログ・ニュースレターとは異なる概念（フェディバース、分散型ソーシャルメディア）を含んでいます。本画面は、ユーザーがこれらの概念を理解し、自サイトがソーシャルウェブの一部となることのメリットを把握できるよう、段階的なガイドを提供します。美しいビジュアルとアニメーションにより、機能の魅力を効果的に伝えます。

**画面へのアクセス方法**：ActivityPub機能を初めて利用するユーザーは、自動的にこのオンボーディングフローにリダイレクトされます。URLパスは `/activitypub/welcome/1` から始まります。

**主要な操作・処理内容**：
1. Step 1: ソーシャルウェブハンドルの紹介とコピー機能
2. Step 2: フォロワーからのインタラクション（いいね、リプライ、リポスト）の説明
3. Step 3: コンテンツタイプ（長文、短文、リーダー）の紹介とオンボーディング完了

**画面遷移**：
- 遷移元：ActivityPubトップ（初回アクセス時）
- Step 1 → Step 2 → Step 3 の順で遷移
- 遷移先：Exploreページ（トピックがある場合）またはActivityPubリーダー

**権限による表示制御**：ActivityPub機能へのアクセス権限を持つ管理者ユーザーのみがこの画面にアクセス可能です。オンボーディング完了後は直接アクセスできますが、通常はスキップされます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 57 | ActivityPub | 主機能 | ActivityPubオンボーディングの案内 |

## 画面種別

ウィザード形式（3ステップのオンボーディング）

## URL/ルーティング

- Step 1: `/activitypub/welcome/1`
- Step 2: `/activitypub/welcome/2`
- Step 3: `/activitypub/welcome/3`
- ベースパス: `/activitypub/welcome`（自動的に `/1` へリダイレクト）
- ルート定義: `apps/activitypub/src/routes.tsx` (L110-134)

## 入出力項目

| 項目名 | 入出力 | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| account | 出力 | Account | - | ユーザーのソーシャルウェブアカウント情報 |
| users | 出力 | User[] | - | サイトの著者一覧（Step 1表示用） |
| topics | 出力 | Topic[] | - | 利用可能なトピック一覧（Step 3完了時の遷移先判定用） |

## 表示項目

### Step 1: ソーシャルウェブの紹介

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| ヘッドライン | string | "Increase your reach, with the social web." |
| 説明テキスト | string | フェディバース（Flipboard、Mastodon、Threads、Bluesky、WordPress）の説明 |
| プロフィールカード | - | アバター、名前、ハンドル、bio、著者情報 |
| ハンドル | string | ソーシャルウェブハンドル（コピー可能） |
| コピーボタン | - | ハンドルをクリップボードにコピー |
| Nextボタン | - | Step 2へ進む |
| 背景画像 | image | ネットワークノードのビジュアル |

### Step 2: ネットワーク効果の説明

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| ヘッドライン | string | "Feel the network effect." |
| 説明テキスト | string | いいね、リプライ、リポストの説明 |
| サンプル通知カード | - | リプライ、いいね、リポストのモックアップ |
| フォロワー数バッジ | - | "270 followers this week"のアニメーション表示 |
| Nextボタン | - | Step 3へ進む |
| 背景画像 | image | 破線のネットワークビジュアル |

### Step 3: コンテンツタイプの紹介

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| ヘッドライン | string | "Find inspiration & follow what you love." |
| 説明テキスト | string | ソーシャルウェブリーダーの説明 |
| タブ切替 | - | Long form / Short form / Integrated reader |
| コンテンツプレビュー | - | 各タブに対応したコンテンツモックアップ |
| Nextボタン | - | オンボーディング完了 |

## イベント仕様

### 1-ハンドルコピー（Step 1）

- トリガー: コピーボタンクリック
- 処理:
  1. `navigator.clipboard.writeText(account.handle)` を実行
  2. アイコンをチェックマークに変更（2秒間）

### 2-次のステップへ進む

- トリガー: 「Next」ボタンクリック
- 処理: `navigate` で次のステップへ遷移
  - Step 1 → `/welcome/2`
  - Step 2 → `/welcome/3`

### 3-オンボーディング完了（Step 3）

- トリガー: 「Next」ボタンクリック
- 処理:
  1. `setOnboarded(true)` でオンボーディング完了フラグを設定
  2. トピックの有無に応じて遷移先を決定
     - トピックあり: `/explore` へ遷移
     - トピックなし: `/` へ遷移

### 4-タブ切替（Step 3）

- トリガー: タブボタンクリック、または3秒ごとの自動切替
- 処理: 対応するコンテンツプレビューを表示
- 自動切替: ホバー中は一時停止

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| オンボーディング完了 | users | UPDATE | accessibilityフィールドのapOnboarding.welcomeStepsFinishedをtrueに更新 |

### テーブル別更新項目詳細

#### users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | accessibility | JSON更新（apOnboarding.welcomeStepsFinished = true） | ユーザー設定の永続化 |

## メッセージ仕様

| 種別 | メッセージ | 表示タイミング |
|------|-----------|---------------|
| 情報 | Increase your reach, with the social web. | Step 1のヘッドライン |
| 情報 | {name} is now part of the world's largest open network. | Step 1でアカウント名表示時 |
| 情報 | Feel the network effect. | Step 2のヘッドライン |
| 情報 | Find inspiration & follow what you love. | Step 3のヘッドライン |
| 情報 | Your social web handle | Step 1でハンドル強調表示時（アニメーション） |

## 例外処理

| 例外状況 | 対応内容 |
|---------|---------|
| アカウント情報読み込み中 | Skeletonローダーを表示 |
| ユーザー一覧読み込み中 | 著者表示部分をスキップ |
| 無効なステップ番号 | Step 1へリダイレクト |

## 備考

- CSSアニメーションを多用した視覚的に魅力的なオンボーディング
- ダークモード対応（背景画像も切り替え）
- レスポンシブデザイン（最小幅1240pxの背景画像）
- オンボーディング完了状態はユーザーのaccessibility設定に永続化
- Step 3のタブは3秒ごとに自動切替（ホバー中は停止）

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | accessibility.ts | `apps/activitypub/src/utils/accessibility.ts` | ApOnboardingSettings型とユーザー設定の構造 |
| 1-2 | onboarding.tsx | `apps/activitypub/src/components/layout/onboarding/onboarding.tsx` | useOnboardingStatusフックの実装（L7-47） |

**読解のコツ**: オンボーディング状態は`currentUser.accessibility`にJSON形式で保存されます。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | routes.tsx | `apps/activitypub/src/routes.tsx` | ルーティング定義（L110-134） |
| 2-2 | onboarding.tsx | `apps/activitypub/src/components/layout/onboarding/onboarding.tsx` | Onboardingラッパーコンポーネント |

**主要処理フロー**:
1. **routes.tsx L110-134**: welcomeルートの定義とサブルート（1, 2, 3）
2. **onboarding.tsx L49-56**: Outletを使用したサブルートのレンダリング

#### Step 3: 各ステップを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | step-1.tsx | `apps/activitypub/src/components/layout/onboarding/step-1.tsx` | ハンドル表示とコピー機能 |
| 3-2 | step-2.tsx | `apps/activitypub/src/components/layout/onboarding/step-2.tsx` | インタラクションのモックアップ |
| 3-3 | step-3.tsx | `apps/activitypub/src/components/layout/onboarding/step-3.tsx` | コンテンツタイプ紹介とオンボーディング完了 |

**主要処理フロー（Step 3）**:
- **L301-325**: useEffect でタブの自動切替（3秒間隔）
- **L321-324**: handleComplete でオンボーディング完了処理

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

```
Onboarding (Layout Component)
    |
    +-- <Outlet /> (React Router)
            |
            +-- Step1 Component
            |       +-- useAccountForUser('index', 'me')
            |       +-- useBrowseUsers()
            |       +-- handleCopy()
            |       +-- navigate('/welcome/2')
            |
            +-- Step2 Component
            |       +-- navigate('/welcome/3')
            |
            +-- Step3 Component
                    +-- useOnboardingStatus()
                    |       +-- useCurrentUser()
                    |       +-- useEditUser()
                    |
                    +-- useTopicsForUser()
                    +-- handleComplete()
                            +-- setOnboarded(true)
                                    +-- updateUser({accessibility: ...})
                            +-- navigate('/explore' or '/')
```

### データフロー図

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

初回アクセス
  |
  +-- /activitypub/welcome --> リダイレクト --> /activitypub/welcome/1
                                                    |
                                                    +-- Step1 表示
                                                            |
Next クリック -----------> navigate('/welcome/2') ------> Step2 表示
                                                            |
Next クリック -----------> navigate('/welcome/3') ------> Step3 表示
                                                            |
Next クリック -----------> handleComplete() ------------> setOnboarded(true)
                                  |                         updateUser()
                                  |
                                  +-- topics? --> /explore
                                  |
                                  +-- else ----> /
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| onboarding.tsx | `apps/activitypub/src/components/layout/onboarding/onboarding.tsx` | ソース | レイアウト・オンボーディング状態管理 |
| step-1.tsx | `apps/activitypub/src/components/layout/onboarding/step-1.tsx` | ソース | Step 1コンポーネント |
| step-2.tsx | `apps/activitypub/src/components/layout/onboarding/step-2.tsx` | ソース | Step 2コンポーネント |
| step-3.tsx | `apps/activitypub/src/components/layout/onboarding/step-3.tsx` | ソース | Step 3コンポーネント |
| routes.tsx | `apps/activitypub/src/routes.tsx` | ソース | ルーティング定義 |
| accessibility.ts | `apps/activitypub/src/utils/accessibility.ts` | ソース | アクセシビリティ設定ユーティリティ |
| use-activity-pub-queries.ts | `apps/activitypub/src/hooks/use-activity-pub-queries.ts` | ソース | API呼び出しフック |
| header.tsx | `apps/activitypub/src/components/layout/onboarding/components/header.tsx` | ソース | ステップ共通ヘッダー |
| ap-nodes.png | `apps/activitypub/src/assets/images/onboarding/` | アセット | Step 1背景画像 |
| ap-dashed-lines.png | `apps/activitypub/src/assets/images/onboarding/` | アセット | Step 2背景画像 |
