# チャット型ファネルビルダー — 製品判断が必要な論点の整理

**作成日: 2026-07-07 / 対象ブランチ: `feature/funnel-chat-builder`**

この文書は、実装済みのチャット型ファネルビルダー（feature flag `FEATURE_FUNNEL_BUILDER`、既定 OFF）について、
**エンジニアだけでは決められず製品側の判断が要る論点**を、コードの実態に基づいて洗い出したものです。
「デグレなし・技術負債なし・既存挙動不変」は監査済み（別掲）。ここで扱うのは *完成度・スコープ・公開方針* の判断です。

各論点は **[現状の実装] / [選択肢] / [推奨] / [影響範囲]** で記載します。推奨は一案であり、決定は製品側にあります。

---

## サマリ（先に結論だけ）

| # | 論点 | 種別 | 推奨 | 緊急度 |
|---|------|------|------|--------|
| A-1 | vendor 環境での `migrate` + テスト実行（未検証） | 検証ゲート | Cursor/サーバ側で1コマンド実行 | 公開前必須 |
| A-2 | flag を誰がいつ ON にするか | 公開判断 | 検証後に段階的 ON | 公開前必須 |
| B-1 | ③LINE はステップ0通で出す価値があるか | 完成度 | 「登録まで」と割り切り or ③保留 | 高 |
| B-2 | 生成した決済プランを active / inactive どちらで作るか | 課金安全 | inactive 生成に変更を推奨 | 中 |
| B-3 | メールステップ draft 固定（手動有効化）の UX | 運用UX | draft維持＋一括有効化導線を別途 | 中 |
| B-4 | 送信/決済アカウントの自動選択（複数所持時に無言で先頭） | 精度 | チャットで選ばせる | 中 |
| B-5 | 生成ページの簡素さ（見出し+文+フォームのみ） | スコープ | 「下書き」と位置づけ許容 | 低 |
| C-1 | ①個別相談・④Zoom のイベント連携方式 | 新規開発 | 案B（Event生成＋送客リンク） | 中 |
| C-2 | ⑤ウェビナー視聴ページの時限CTA/再生期限 | 新規開発 | 別機能として切り出し | 中 |
| D-1 | flag の粒度（全体 env / プラン別 / ユーザー別） | 公開方針 | 当面は全体env、後でプラン別 | 低 |

> **実装状況メモ（2026-07-07 追記）**: 製品判断が不要な安全改善（B系）と、方針決定済みの連携（C系）を実装。
> - **B-2 実装済**（`1cc9626`）: 決済プランを `status='inactive'` で生成し、誤って LP を公開しても即課金にならないようにした。完了画面に「無効状態＝確認後に有効化」を表示。
> - **B-1 実装済**（`4e49e31`）: ③LINE の「配信文面は自動生成しない」注意を、チャット内 warnings に加え apply 後の完了画面にも表示。
> - **B-4 一部実装**（`5c6db2a`）: 送信アカウントが複数あるとき、自動選択した使用先を完了画面で明示（1件以下なら非表示）。完全な「複数時にチャットで選ばせる」動的質問は静的テンプレ設計の範囲外のため将来課題として保留。
> - **C-1 実装済（案B採用）**（`448d6c7`）: ①個別相談・④Zoom面談を、下書きイベント（`status=draft`/`is_published=false`）を生成し LP の予約ボタンから相対 `/e/{uid}` へ送客する形で実装。予約枠（日程）・会議URLは自動生成せず、確定後にイベント管理で設定・公開する（公開までボタンのリンク先は非表示）ことを warnings と完了画面で明示。
> - **C-2 実装済（簡易版採用）**（`448d6c7`）: ⑤オンラインセミナーを「登録ページ→視聴ページ（動画＋締切カウントダウン＋常時CTA）」の簡易版で実装。**「動画X分でCTA表示」「登録からN日で視聴不可（再生期限）」は簡易版では未対応**であることを明示。視聴ページURLは登録後メールに手動差し込み。
> - **B-3 決定＝現状維持**: メールステップは draft（手動有効化）のまま。一括有効化UIは作らない。
> - **残る要判断**: A-1/A-2（検証・公開）、B-5（ページ簡素さの許容）、D-1（flag粒度）、および将来拡張として C-2 の本格ウェビナー機能（時限CTA・再生期限）・B-4 の完全動的アカウント選択。
> - これで **テンプレは①〜⑦の7種すべて登録済み**（②③⑥⑦＋①④⑤）。

---

## A. 検証ゲート（未検証のまま残っている部分）

### A-1. vendor 環境での migrate + テスト実行
- **現状**: 当開発サンドボックスは `vendor/` が無く `php artisan` / `phpunit` を実行できないため、
  構文チェック（PHP 8.4 `php -l` 全ファイル通過）と静的監査までしか行えていない。
  マイグレーション適用とテスト green の**動的確認が未実施**。
- **必要な作業**（実行環境で1回）:
  ```
  composer install
  php artisan migrate            # funnel_builder_sessions / _messages を作成
  php artisan test --filter=FunnelBuilder
  ```
  用意済みテスト: `tests/Feature/FunnelBuilderFlowTest.php`（flag OFF=404 / apply前は funnels 不増 / private下書き生成 / 他ユーザー遮断 / ProductPlan生成）、
  `tests/Unit/FunnelBuilderTemplatesTest.php`・`FunnelBuilderEmailLeadTemplateTest.php`。
- **判断事項**: 誰が・どの環境で実行するか（Cursor 手元 / ConoHa ステージング）。**公開前の必須ゲート**。
- **影響**: 実行しないと、マイグレーションの想定違いや Eloquent 挙動差を本番で初めて踏むリスク。

### A-2. feature flag を ON にする判断
- **現状**: `FEATURE_FUNNEL_BUILDER=false` 既定。ON にしない限り入口もルートも 404 で、既存挙動に一切影響しない。
- **判断事項**: A-1 の green 確認後、誰がいつ `.env` に `true` を入れるか。段階公開の要否。
- **推奨**: ステージングで A-1 green → 社内ユーザーのみ → 全体、の順。

---

## B. 実装済みテンプレ（②メール取得 ③LINE取得 ⑥有料イベント ⑦特商法）に内在する製品判断

> これらは「動くが、仕様の意思決定が要る」項目。現状はエンジニアが安全側の既定を置いているだけで、
> 製品として正しい既定かは未確認。

### B-1.（重要）③LINE取得テンプレは「ステップ0通」で出す価値があるか
- **現状の実装**: ③はLINEシナリオと登録導線（`line_btn`/`line_qr`）を private 下書きで生成する。
  ただし **LINEのステップ配信（ドリップ）文面は自動生成しない**（設計判断 B4）。
  理由はコード実態:
  - `StepMessageController` は `type='email'` をハードコード（L127）し、非email のステップは編集・更新を拒否（L174/209）。
    → **LINEステップは自動生成しないだけでなく、ユーザーが通常UIから手動追加することもできない**。
  - LINE配信は step_messages ではなく LINE管理（自動応答等）側で設定する現行仕様。
- **つまり**: ③で出来上がる下書きは「LINE友だち追加まで」。登録後の教育LINEは別画面で人手設定。
- **選択肢**:
  - (a) 「③は登録導線まで」と割り切って提供し、チャット内と完了画面で明示する（現状の warnings で通知済み）。
  - (b) LINE step_messages 送信基盤を実装してから③を提供（大きめの新規開発）。
  - (c) ③を当面 Registry から外し、②メール取得だけ提供。
- **推奨**: (a)。ただしチャットUIで「LINE配信文面は別途設定が必要」を強く明示する前提。製品として (a) を許容するかが判断点。
- **影響**: ③のユーザー期待値。ここを曖昧にすると「LINEステップが送られない」というクレームになり得る。

### B-2. 生成した決済プランを active / inactive どちらで作るか（⑥）
- **現状の実装**: `ProductPlan` を `status` 未指定で作成 → DB既定 `active`。手動作成フロー（`status ?? 'active'`、許容値 active/inactive）と一致。
  プランは private ページ上にしか載らないため、公開するまで購入導線に到達しない（2重防御）。
- **リスク**: ユーザーが LP を公開した瞬間、決済連携が設定済みなら**即購入可能**になる。レビュー前の意図せぬ課金余地。
- **選択肢**:
  - (a) 現状維持（active）。手動作成と同じで一貫。
  - (b) ビルダー生成分は `inactive` で作り、ユーザーが明示的に有効化するまで購入不可にする（より安全側）。
- **推奨**: (b)。チャット生成物は「まだ確認前の下書き」なので、決済だけは inactive 既定が安全。
  実装は Applier の `ProductPlan::create` に `'status' => 'inactive'` を足すだけ（1行、既存挙動非影響）。
- **影響**: ⑥のみ。B-2 を (b) にする場合、完了画面に「決済プランは無効状態。確認後に有効化してください」を追記。

### B-3. メールステップの draft 固定（手動有効化）UX（②）
- **現状の実装**: 生成する `StepMessage` は `status='draft'`。`StepMailDispatchService` は `status='active'` のみ送信（L39/87）ので、
  **確定直後に誤送信されない**。ユーザーは各ステップを開いて有効化する必要がある。
- **判断事項**: これは意図どおりか。ステップ数が多いと「1通ずつ有効化」が手間。
- **選択肢**:
  - (a) draft 維持（安全）＋ ステップ一覧に「まとめて有効化」導線を別途用意（別PR）。
  - (b) apply 時に active で作る（即戦力だが、レビュー前に配信予約が走るリスク）。
- **推奨**: (a)。安全既定は維持し、一括有効化は将来の改善として分離。
- **影響**: ②のみ。現状でも動作はするが、有効化操作の学習コストが残る。

### B-4. 送信/LINE/決済アカウントの自動選択（複数所持時）
- **現状の実装**: Applier は `user_id` の非アーカイブ・種別一致アカウントを **`orderBy('id')` の先頭**で自動選択
  （メール: type in email/both、LINE: line/both、決済: telecom かつ active）。
  対応アカウントが無ければシナリオ/プランは「未生成」または「購入不可下書き」とし、完了画面で通知。
- **判断事項**: 複数アカウントを持つユーザーで、**無言で先頭を選ぶ**のは事故になり得る（想定と違う送信元）。
- **選択肢**:
  - (a) チャットのステップに「どの送信アカウントを使うか」を追加し選ばせる（精度↑・質問数↑）。
  - (b) 現状維持（先頭自動）＋ 完了画面で「送信元: ○○を使用」を明示。
- **推奨**: 単一アカウントのユーザーは (b) のまま、**複数あるときだけ (a) で聞く**動的分岐。
- **影響**: ②③⑥。実装は Engine の質問追加で対応可能（テンプレの steps に条件付きノード）。

### B-5. 生成ページの内容の簡素さ
- **現状の実装**: 生成ページは「見出し＋説明文＋フォーム/ボタン」の最小構成（`FunnelPageContentFactory`）。
  画像・装飾・多段セクション・カラムは付けない（既知の公開レンダラのセクション margin 未読込バグを避けるためにも意図的に単純化）。
- **判断事項**: これを「そのまま公開できる完成品」ではなく「エディタで仕上げる下書き」と位置づけてよいか。
- **推奨**: 「下書き（骨子）」と明言して許容。リッチ化はテンプレ側の blocks を足せば拡張可能（テンプレ非依存設計済み）。
- **影響**: 全テンプレ。期待値設定の問題。

---

## C. 未実装テンプレ ①個別相談 ④Zoom面談 ⑤ウェビナー の連携方式（新規開発の要否）

> これらは「盲目実装すると技術負債になる」ため保留中。**前提機能が現状のコードに存在しない**のが理由。

### 事実確認（コード実態）
- エディタが扱う要素型の全リスト（`editor.blade.php` より）:
  `accordion / audio / balloon / bullet / button / buy_button / comment_block / countdown / divider / footer /
  form_payment / form_register / headline / html / image / line_btn / line_qr / next_link / pdf / progress /
  section / spacer / subhead / table / text / video / video_menu`
- **この中にイベント予約を埋め込む要素は無い**（`grep` で確認）。イベント予約は独立公開ページ `/e/{uid}`
  （`PublicPublishedEventController`）として存在し、LP内に差し込む部品は未実装。
- `page_type` enum には `event_booking` / `webinar` が存在するが、これは**意味ラベルであって機能部品ではない**。

### C-1. ①個別相談・④Zoom面談 のイベント連携
- **必要なこと**: 「LP → 日程を選んで予約」までを1本のファネルにする。現状、予約UIをLPに埋め込む手段が無い。
- **選択肢**:
  - **案A（新規要素）**: `event_booking` という funnel-page 要素を新設し、指定イベントの予約枠をLP内に埋め込む。
    - 長所: 体験が一体化。 短所: 新要素はエディタ／公開レンダラ／プレビューの3箇所に実装が要る（中規模）。
  - **案B（送客リンク）**: ビルダーが Event 本体（`events` + 日程設定）を生成し、LPには `button`/`next_link` で `/e/{uid}` へ送客。
    - 長所: 新要素不要、既存の公開イベントページをそのまま使える。 短所: Event は必須項目・日程設定・担当者・申込フォーム項目が多く、
      「最小の Event を安全に生成する」設計が別途必要（②のシナリオ生成より重い）。
  - **案C**: ①④は当面スコープ外（②③⑥⑦で先行リリース）。
- **推奨**: **案B**。新要素を増やさず既存資産を使え、technical debt を最小化できる。
  ただし「ビルダーで Event をどこまで生成するか（枠は作る？担当者は？申込フォーム項目は？）」の**スコープ確定が判断点**。
- **影響**: 新規開発。②〜⑦の既存実装には影響しない（テンプレを足すだけ）。

### C-2. ⑤ウェビナー視聴ページ
- **必要なこと**: 動画視聴ページで「一定時間経過後にCTA出現」「再生期限（登録からN日で視聴不可）」等の時限挙動。
- **事実**: `video` と `countdown` 要素は在るが、**「動画のX分地点でCTA表示」「再生期限」という挙動は未実装**。
- **選択肢**:
  - **案A（新機能）**: 視聴ページに時限CTA・再生期限を実装してから⑤を提供（機能開発）。
  - **案B（簡易版）**: 既存 `video` + `countdown` + `button` で「動画＋締切カウントダウン＋常時CTA」の簡易ウェビナー風を提供（時限出現は無し）。
  - **案C**: ⑤はスコープ外。
- **推奨**: 時限CTA/再生期限は**ウェビナー機能そのものの新規開発**として切り出し、ビルダー対応はその後。
  先に出すなら案Bの簡易版を「ウェビナー(簡易)」と明示。
- **影響**: 新規開発。既存実装に影響なし。

---

## D. ロールアウト方針

### D-1. feature flag の粒度
- **現状**: `FEATURE_FUNNEL_BUILDER` は全体 env フラグ（全ユーザー一括）。
- **選択肢**:
  - (a) 当面は全体 env のまま（実装済み・最小）。
  - (b) プラン別（trial/有料）やユーザー別に出し分け（gate 追加が必要）。
- **推奨**: まず (a) で社内・限定公開 → 反応を見て (b) を検討。
- **影響**: (b) は Controller の `ensureEnabled()` にユーザー条件を足す小改修で対応可能。

---

## 付録: この文書が「判断待ち」とするものと、しないもの

- **判断待ち（本文）**: 上記 A〜D。完成度・スコープ・公開のいずれかで製品側の意思が要るもの。
- **判断不要（実装済み・監査済み）**:
  - flag OFF のバイト単位不変性、ルート/認証、マイグレーション安全性、生成物の private/draft、
    スケジューラ無影響、fillable/NOT NULL 網羅、PHP 8.4 lint。詳細は監査結果（チャット記録）参照。
  - ②⑥⑦の生成物は公開すれば機能する（公開レンダラは `form_register` を `scenario_id` で解決、
    `registration_route_token=null` は空文字フォールバックで安全）。

以上。決定した方針を本文の各推奨欄に追記していけば、そのまま実装指示書として使えます。
