# 画面設計書 38-ソーシャルアカウント設定

## 概要

本ドキュメントは、Ghost管理画面の「ソーシャルアカウント」設定の設計内容を記載した画面設計書です。この画面は、サイトのFacebookとX（旧Twitter）アカウントのURLを設定するための機能を提供します。

### 本画面の処理概要

この画面では、サイトに関連付けるFacebookページとXプロフィールのURLを設定することができます。

**業務上の目的・背景**：ソーシャルメディアアカウントをサイトに関連付けることで、構造化データ（Schema.org）やリッチカードの生成時にこれらの情報が使用されます。これにより、検索エンジンやソーシャルプラットフォームがサイトとソーシャルアカウントの関連性を理解し、より適切な情報表示が可能になります。

**画面へのアクセス方法**：
- 設定画面（/ghost/settings）のGeneral settingsセクション内
- 「Social accounts」項目でソーシャルURLを設定

**主要な操作・処理内容**：
1. FacebookページURLの入力：https://www.facebook.com/形式のURLを入力
2. XプロフィールURLの入力：https://x.com/形式のURLを入力
3. URL形式のバリデーション：入力値が正しい形式か検証
4. 設定の保存：変更内容をAPIを通じて保存

**画面遷移**：
- 遷移元：設定画面のGeneral settingsセクション
- 遷移先：なし（インライン編集のため画面遷移なし）

**権限による表示制御**：Admin権限以上のスタッフユーザーのみ編集可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 36 | ソーシャルメディア連携 | 主機能 | Twitter/Facebookアカウントの設定 |

## 画面種別

編集（インライン編集形式）

## URL/ルーティング

| URL パターン | 説明 |
|-------------|------|
| `/ghost/settings` (General settings内) | 設定画面内のSocial accountsセクション |

## 入出力項目

### 入力項目

| 項目名 | 型 | 設定キー | プレースホルダー | バリデーション |
|--------|-----|---------|-----------------|---------------|
| Facebook URL | String | facebook | https://www.facebook.com/ghost | validateFacebookUrl |
| X URL | String | twitter | https://x.com/ghost | validateTwitterUrl |

### 保存形式

設定にはURLではなくハンドル（ユーザー名部分）が保存されます。

| 設定キー | 保存値例 | 元URL |
|---------|---------|-------|
| facebook | ghost | https://www.facebook.com/ghost |
| twitter | ghost | https://x.com/ghost |

## 表示項目

| 項目名 | コンポーネント | 説明 |
|--------|--------------|------|
| Facebook URL入力 | TextField | FacebookページのURL |
| X URL入力 | TextField | XプロフィールのURL |

## イベント仕様

### 1-Facebook URL変更

**トリガー**: Facebook URLフィールドへの入力

**処理内容**:
- handleFacebookChange(value)が呼ばれる
- setFacebookUrl(value)でローカル状態を更新
- validateFacebookUrl(value)でバリデーション
- 有効な場合:
  - facebookUrlToHandle(newUrl)でハンドルを抽出
  - updateSetting('facebook', handle)で設定を更新
  - エラーをクリア
- 無効な場合:
  - setErrors({...errors, facebook: err.message})でエラー設定
  - updateSetting('facebook', null)で設定をnullに

**バリデーション** (validateFacebookUrl):
- Facebook URL形式のチェック
- https://www.facebook.com/またはhttps://facebook.com/で始まるか
- 有効なユーザー名/ページ名が含まれるか

### 2-X URL変更

**トリガー**: X URLフィールドへの入力

**処理内容**:
- handleTwitterChange(value)が呼ばれる
- setTwitterUrl(value)でローカル状態を更新
- validateTwitterUrl(value)でバリデーション
- 有効な場合:
  - twitterUrlToHandle(newUrl)でハンドルを抽出
  - updateSetting('twitter', handle)で設定を更新
  - エラーをクリア
- 無効な場合:
  - setErrors({...errors, twitter: err.message})でエラー設定
  - updateSetting('twitter', null)で設定をnullに

**バリデーション** (validateTwitterUrl):
- X/Twitter URL形式のチェック
- https://x.com/またはhttps://twitter.com/で始まるか
- 有効なユーザー名が含まれるか

### 3-保存ボタンクリック

**トリガー**: Saveボタンをクリック

**処理内容**:
- handleSaveClick()が呼ばれる
- 両方のURLを再バリデーション
- エラーがあれば保存をブロック
- エラーがなければhandleSave()でAPI呼び出し

**API呼び出し**:
```
PUT /ghost/api/admin/settings/
Content-Type: application/json

{
  "settings": [
    { "key": "facebook", "value": "{ハンドル}" },
    { "key": "twitter", "value": "{ハンドル}" }
  ]
}
```

### 4-キャンセルボタンクリック

**トリガー**: Cancelボタンをクリック

**処理内容**:
- handleCancel()が呼ばれる
- useEffectにより、facebookHandle/twitterHandleの変更を検知
- setFacebookUrl/setTwitterUrlでローカル状態を元の値にリセット

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示時 | settings | SELECT | 現在のfacebook, twitter取得 |
| 保存ボタンクリック | settings | UPDATE | facebook, twitterの更新 |

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

#### settings

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | facebook | ハンドル文字列またはnull | URLからハンドルを抽出して保存 |
| UPDATE | twitter | ハンドル文字列またはnull | URLからハンドルを抽出して保存 |

## メッセージ仕様

| メッセージ種別 | メッセージ内容 | 表示条件 |
|--------------|---------------|---------|
| エラー | (validateFacebookUrlからのメッセージ) | 無効なFacebook URL |
| エラー | (validateTwitterUrlからのメッセージ) | 無効なX URL |
| プレースホルダー | https://www.facebook.com/ghost | Facebook URLフィールド |
| プレースホルダー | https://x.com/ghost | X URLフィールド |

## 例外処理

| 例外状態 | 処理内容 |
|---------|---------|
| 無効なURL形式 | エラーメッセージをフィールド下部に表示、保存時に再チェック |
| API通信エラー | handleError()でエラートースト表示 |

## 備考

- URLとハンドルの変換にはsocial-urls.tsのユーティリティ関数を使用
- 編集ボタン（Edit）は非表示（hideEditButton）で、フィールドを直接編集して編集開始
- キャンセル時はuseEffectでfacebookHandle/twitterHandleの変化を監視してリセット
- 構造化データやリッチカードのサポートのために設定が使用される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | social-urls.ts | `apps/admin-x-settings/src/utils/social-urls.ts` | URL⇔ハンドル変換、バリデーション関数 |

**読解のコツ**: facebookHandleToUrl, facebookUrlToHandle, validateFacebookUrl等の関数の動作を確認。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | social-accounts.tsx | `apps/admin-x-settings/src/components/settings/general/social-accounts.tsx` | メインコンポーネント全体の構造 |

**主要処理フロー**:
1. **L8-17**: useSettingGroupでフォーム状態管理
2. **L19-22**: errorsのローカル状態
3. **L24**: getSettingValuesでfacebook, twitterハンドルを取得
4. **L26-27**: useState でURLのローカル状態を管理（ハンドル→URL変換）
5. **L30-33**: useEffectでキャンセル時のリセット処理
6. **L35-52**: handleFacebookChangeでバリデーション付き更新
7. **L54-71**: handleTwitterChangeでバリデーション付き更新
8. **L73-104**: handleSaveClickで保存前バリデーション

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

```
[ユーザー操作]
    │
    ├─ SocialAccounts コンポーネント
    │      │
    │      ├─ useSettingGroup() フック
    │      │      ├─ localSettings
    │      │      ├─ updateSetting()
    │      │      └─ handleSave()
    │      │
    │      ├─ useState (facebookUrl, twitterUrl)
    │      ├─ useState (errors)
    │      │
    │      ├─ useEffect
    │      │      └─ キャンセル時のリセット処理
    │      │
    │      ├─ handleFacebookChange()
    │      │      ├─ validateFacebookUrl()
    │      │      ├─ facebookUrlToHandle()
    │      │      └─ updateSetting('facebook')
    │      │
    │      ├─ handleTwitterChange()
    │      │      ├─ validateTwitterUrl()
    │      │      ├─ twitterUrlToHandle()
    │      │      └─ updateSetting('twitter')
    │      │
    │      └─ TopLevelGroup
    │             └─ SettingGroupContent
    │                    ├─ TextField (facebook)
    │                    └─ TextField (twitter)
    │
    └─ [保存時]
           ├─ handleSaveClick()
           │      └─ 再バリデーション
           └─ handleSave()
                  └─ PUT /settings/
```

### データフロー図

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

                     ┌─────────────────────────────┐
settings API ───────▶│ getSettingValues()          │
(facebook, twitter   │   - ハンドル取得            │
 as handles)         │   - facebookHandleToUrl()   │
                     │   - twitterHandleToUrl()    │
                     └────────────┬────────────────┘
                                  │
                     ┌────────────▼────────────────┐
                     │ useState (URL状態)          │
                     │   - facebookUrl             │
                     │   - twitterUrl              │
                     └────────────┬────────────────┘
                                  │
[TextField入力] ────▶┌────────────▼────────────────┐
                     │ handleFacebookChange()      │
                     │ handleTwitterChange()       │
                     │   - validateXxxUrl()        │
                     │   - xxxUrlToHandle()        │
                     │   - updateSetting()         │
                     └────────────┬────────────────┘
                                  │
[Saveクリック] ─────▶┌────────────▼────────────────┐
                     │ handleSaveClick()           │
                     │   - 再バリデーション        │───▶ [PUT /settings/]
                     │   - handleSave()            │     (ハンドルとして保存)
                     └─────────────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| social-accounts.tsx | `apps/admin-x-settings/src/components/settings/general/social-accounts.tsx` | ソース | メインコンポーネント |
| social-urls.ts | `apps/admin-x-settings/src/utils/social-urls.ts` | ソース | URL⇔ハンドル変換、バリデーション |
| use-setting-group.ts | `apps/admin-x-settings/src/hooks/use-setting-group.ts` | ソース | 設定グループ管理フック |
| general-settings.tsx | `apps/admin-x-settings/src/components/settings/general/general-settings.tsx` | ソース | 親コンポーネント |
