開発プラン
インタビュー機能 独立アプリ化(OpenTok → LiveKit 移行)の開発計画。新基盤レーン(独立 Next.js)と minedia-www レーンの2レーン並走を、シナリオ階段とスプリント単位で示す。依存は「OpenAPI 段階公開」「core 稼働」の2ゲート。
全体シナリオ — シナリオ階段
機能を「Stage(ゲート)」単位でデモ可能性に落とし込む。各 Stage は「新基盤レーンで何が見せられるか」と「minedia-www レーンの到達点」を対にして進む。
| Stage | 達成 Sprint | 新基盤レーンで見せられること | minedia-www レーンの到達点 |
|---|---|---|---|
| G0 基盤構築 | S0 | LiveKit 接続・CI・テスト・Storybook が動く。ユーザーマスター(最小)・TVM 中核・API 横断基盤。3スパイク(TVM中核 / DEC-04 / 接続テスト計測)着手 | Phase0/1 着手(seam + migration・core 非依存) |
| G1 最小疎通 | S1 | 委譲信頼トークンで panelist + moderator が会話。リロード復帰・再入室阻止(ban芯)・presence(W1/W2) | Phase0/1 完了 → ★ OpenAPI v0.1 公開で Phase2 アンブロック |
| G2 1対1完成 | S2 前半 | + in-room チャット(案A データプレーン) | Phase2-2a(CoreApiClient 土台) |
| G2.5 即席E2E先行(第0弾) | S2 末 | 即席ルームが新App単独でE2E(作成→匿名/多人数入室→案Aチャット→録画→期限ガード)。調査ドメイン連携ゼロ・core 稼働を待たず実機デモ | (依存なし=www 不要) |
| G3 見学者対応 | S2 後半 | 見学者が裏で moderator と密談しつつ見学(多人数 observer 含む) | Phase2-2b/2c(LivekitRoom / Session 作成) |
| G4 進行ツール | S3 | 提示物・画面共有・録画(Egress→Recording)・Ban・異常系(録画失敗→通知)・運用者監視 | Phase2-2d(Webhook receiver) |
| G5 運用・連携 | S4 | Webhook 配信基盤・文字起こしバッチ・接続テスト・調査↔基盤 API 連携 | Phase2-2e((C)読み取り書換)→ ★ core 稼働で Phase3 アンブロック |
| G6 独立アプリ完成 | S5 | 全 Capability + multi-actor E2E + 内部パイロット | Phase3(実 core 結合・1案件 e2e・二重運用) |
完全性の担保:機能を1個忘れても「Gx がデモできない」で露見する。G2.5(即席先行)は「core を待たず新App単独で価値を出せる最小スライス」として、移行リスクの早期実証台になる。
2レーン構成 — 並走の考え方
新基盤レーン本流
LiveKit を中核とする独立アプリを Sprint 単位で構築。接続基盤・委譲信頼トークン・データプレーン・録画・運用機能・接続テストまでを段階的に積み上げ、各 Sprint 末で OpenAPI を段階公開する。
minedia-www レーン
既存の調査業務側を seam リファクタ → migration → contract-first → core 結合の4 Phase で並走改修。Phase0/1 は core 非依存で S0 から即着手、Phase2 は OpenAPI 公開、Phase3 は core 稼働が gate。
2つの依存ゲート:① OpenAPI v0.1 公開(S1末)で minedia-www の Phase2 がアンブロック。② 公開API 全エンドポイント実装完了=core 稼働(S4末)で Phase3 がアンブロック。新基盤レーンが先行し、minedia-www は pure consumer として追従する。
Sprint 0 — 土台 + 基盤の芯 + 3スパイク
ゴール:Next.js + CI + テスト + Storybook + LiveKit 接続に加え、ユーザーマスター(最小)・委譲信頼 TVM 中核・API 横断基盤を立てる。3スパイク(TVM中核 / DEC-04 / 接続テスト計測)を先行し、CP 先頭・最大 UX リスク・最大地雷領域の不確実性を着手前に潰す。
| ID | サイズ | タスク |
|---|---|---|
| S0-1 | L | 環境構築一式(F-1〜F-11) — スキャフォールド / CI / Sentry / Vitest+RTL+MSW / Playwright smoke / アセット移植 / Storybook + host |
| S0-2 | S | LiveKit 接続基盤 + token route — server SDK / token.ts / roles.ts 移植 |
| S0-3 | M | 委譲信頼 TVM 中核(スパイク①) — 委譲信頼トークン基盤の中核。基盤は参加者の身元を自分で確認せず、テナント(=minedia-www)の保証を信頼して入室トークンを発行する。テナントを API キーで認証 → 参加者の入室トークン(JWT)を発行 → テナントが渡す役割・表示名をトークンに封入。署名鍵の管理(JWKS / kid / 鍵ローテーション)も整備。DEC-06(失効の仕組み=jti 無効化リスト・一括失効カウンタ token_epoch の置き場/強制退室UIの所在)を先に決める |
| S0-4 | M | ユーザーマスター(最小) — users 台帳 + 最小認証(管理 UI は含まない) |
| S0-5 | M | API 契約素案(散文・調査↔基盤6連携) — エンドポイント / エンベロープ / エラー設計 |
| S0-6 | L | API 横断基盤スケルトン — L0 存在秘匿(404) / Idempotency-Key / external_ref 双方向 / health・ready / エラーコード体系 / エンベロープ / PII 認証層境界 |
| S0-7 | M | DEC-04 リロード UX 検証(スパイク②) — sessionStorage 退避 / 親フレーム再要求を実機検証。webview ケースも含める。成立しないと G1 ゲート不成立 |
3スパイク③=接続テスト計測エンジン(S4-15)の iOS/WebKit/CDN 既知地雷は S0 で先行検証する(タスク本体は S4)。DEC-02 = LiveKit 確定済(案A の前提クリア)。
Sprint 1 — 🎯 G1 最小疎通(委譲信頼 × LiveKit × 再入室阻止)
ゴール:委譲信頼トークンで panelist + moderator が LiveKit 会話。リロード復帰・ban 再入室阻止の芯・presence(W1/W2)まで。Sprint 末に OpenAPI v0.1 公開。S1-7・S1-10 は削除につき欠番(ban 仕様は別途詰める)。
| ID | サイズ | タスク |
|---|---|---|
| S1-1 | M | decorator 配線 + story — Storybook で各 UI を隔離表示する decorator(Zustand store / Context / MSW モックを注入するラッパー)を配線し、代表 story を作成。Storybook 駆動開発の土台 |
| S1-2 | S | 入室フロー — 参加者がトークンで入室する一連の流れ。トークン内の役割情報(role クレーム)を読み取り、ルーム内の権限コンテキストを組み立てる(resolver) |
| S1-3 | M | ルーム初期化 + Zustand + RoomShell |
| S1-4 | M | Publish/Subscribe(LiveKit) |
| S1-5 | M | CreateRoom 事前生成(案A) — empty_timeout = ends_at + 30分 + provider_session_id 即保存 |
| S1-6 | M | presence webhook 受信 + W1/W2 配信前倒し — participant_joined/left → EntryHistory → W1/W2 送出。配信基盤の芯を S4-3 から前倒し |
| S1-8 | S | ban — POST .../ban + RDS status/epoch++ + RemoveParticipant |
| S1-9 | S | リロード時トークン再取得・同一参加者復帰 — DEC-04・S0-7 スパイクの本実装 |
| S1-11 | S | 通知トースト / Join Sound — 入退室・エラー等の画面内トースト通知と入室時の効果音 |
| S1-12 | M | モーダル基盤(7種) — 退室確認・デバイス選択・設定・エラー・ban 確認・招待 等の共通基盤(開閉制御 / オーバーレイ / フォーカストラップ) |
| S1-13 | L | OpenAPI v0.1 公開(中核) — Session/Room/token/participant/entry/health の機械可読化 + vendoring 用公開。www-Phase2 アンブロック点 |
| S1-14 | L | 公開API 中核サーバー実装 — Session 5本 / Room 2本 / room-access-tokens 2本 / Participant ban 2本 / EntryHistory 1本 / JWKS。L0・API key 認可・ページング |
G1 ゲート:委譲信頼トークンで 2タブ会話、リロードで同一参加者復帰、ban で再入室不可、presence(W1/W2)、Sentry クリーン。★ OpenAPI v0.1 公開済。
Sprint 2 — 🎯 G2 → G2.5(即席先行) → G3
ゴール:案A で chat を実装し 1-on-1 完成。S2 末に即席ルーム単独 E2E(G2.5・第0弾)をデモゲート化。さらに Observer 密談見学。
| ID | サイズ | タスク |
|---|---|---|
| S2-1 | M | chat decorator + story — チャット UI 用の Storybook decorator と story。public/private/observer 各チャネル・メッセージ履歴の状態を隔離表示 |
| S2-2 | S | RoomPolicy canSendTo / destinationIdentitiesFor の単一点化 — 案A の配信 authz。canSendTo=送信者 role × チャネル visibility で送信可否を判定、destinationIdentitiesFor=サーバーが配信先 participant を算出し宛先詐称を構造的に封じる。両者を RoomPolicy に集約して正典化 |
| S2-3 | L | データプレーン基盤一式(案A) — Route Handler(HTTP 送信) → canSendTo 認可 → RDS 永続化 → sendData 配信 → DataReceived 受信、履歴 API でリロード補完(送信 authz / 永続化 / 配信 / 履歴補完に分解検討) |
| S2-4 | M | Private チャット(3系統) |
| S2-5 | M | Observer チャット |
| S2-6 | S | Observer 閲覧モード(4ロール) |
| S2-7 | S | Panelist スタンバイ — パネリスト入室後、モデレーターの準備が整うまで待機させる本番開始前の待機状態 UI |
| S2-8 | S | 退室・切断(最小) |
| S2-9 | M | dev デバッグ(Inspector / seed / ?role=) — Inspector で状態/接続を可視化、seed でテストデータ投入、?role= で任意ロールに切替えて検証 |
| S2-10 | L | 即席先行 第0弾 — 匿名 participant JWT(external_ref 両 null) + 多人数ルーム(複数 observer + moderator + panelist) + 期限ガード(Session.status) + room_access_token 相当の入口。既存 Capability(委譲信頼 / LiveKit 会話 / 案A チャット / 録画 / ban)を即席向けに束ね単独 E2E(詳細は下記「即席先行スライス」) |
G2 ゲート:案A chat 込み 1-on-1、リロードで履歴復帰。
G2.5 ゲート(第0弾):即席ルームが新App単独で E2E(作成→匿名/多人数入室→案A チャット→録画→期限切れ)。調査ドメイン連携ゼロ。core 稼働を待たない実機デモ=go/no-go 材料を早期提示。
G3 ゲート:Observer 密談見学(多人数 observer 含む)。
Sprint 3 — 🎯 G4 周辺機能実装 + 異常系
ゴール:提示物・画面共有・録画・Reaction・Ban が本格運用シナリオで動く。異常系1本(録画失敗→通知)を含む。さらに Operator 監視・緊急発行・退室(reconnect)・PiP・見学者招待リンク・接続診断/Stats/Help を S4 から本 Sprint へ前倒し(S3-13〜18)。
| ID | サイズ | タスク |
|---|---|---|
| S3-1 | S | moderation story — リアクション / 提示物 / 画面共有 / 録画 / Ban 等の Storybook story を作成 |
| S3-2 | M | リアクション + Room Event dispatcher(LiveKit data) |
| S3-3 | M | 提示物(Handout) + 動画同期再生 — handout.show/hide 正典 |
| S3-4 | M | 画面共有(LiveKit) |
| S3-5 | M | 録画(Egress → Recording entity + S3) + 録画失敗監視 → W3 failed → オペ通知(異常系) |
| S3-6 | S | 強制退出 / Ban(UI フル) — 芯は S1-8 |
| S3-7 | S | 動画レイアウト / 拡大 |
| S3-8 | S | OpenAPI v0.2 公開(録画・提示物) |
| S3-9 | L | 公開API 実装 — Recording 4本 / Handout 4本。download-url = API key 限定(PII 境界) |
| S3-10 | M | 管理画面基盤(Refine) — Refine セットアップ + authProvider=users(管理プレーン)ログイン + dataProvider=公開API/内部API 接続 + shadcn/ui 統合。将来の Operator 監視・ユーザーマスター管理 UI の土台 |
| S3-11 | L | 即席 Folder/Slot CRUD — ExtemporaryFolder/Slot の一覧 / 作成 / 編集 / 削除 + room_access_token 相当の入室 URL トークン発行(Refine useTable/useForm) |
| S3-12 | M | 即席 URL 配布 + 履歴参照 — 入室 URL 一覧 / CSV 出力 + 即席ルームの入退室・録画の参照(即席の運用・振り返り) |
| S3-13 | S | 緊急発行(force access token) — POST /room-access-tokens force:true。S4 から前倒し |
| S3-14 | S | Operator monitoring — 運用者監視(管理画面基盤 S3-10 の上に構築)。S4 から前倒し |
| S3-15 | S | 退室(reconnect + Observer auto-exit) S4 から前倒し |
| S3-16 | S | Picture-in-Picture S4 から前倒し |
| S3-17 | S | 見学者向け招待リンク S4 から前倒し |
| S3-18 | S | 接続診断 / Stats / Help — ルーム内表示 UI。本番前テストは S4-15〜19。S4 から前倒し |
G4 ゲート:提示物 + 画面共有 + 録画 + Reaction + Ban + 録画失敗の異常系が運用シナリオで動く。即席調査 CRUD 管理画面で Folder/Slot 作成→URL 発行→履歴参照が運用できる。Operator 監視・緊急発行・退室(reconnect)・PiP・見学者招待リンク・接続診断/Stats/Help も揃う。
Sprint 4 — 🎯 G5 運用 + Webhook配信 + 文字起こし + API連携 + 接続テスト
ゴール:Webhook 配信基盤(W3〜W6)・文字起こしバッチ・API 連携・接続テスト一式。★ core 稼働=公開API 全エンドポイント実装完了。本 Sprint は最もタスクが多く、状況次第で配信 / 文字起こし / 接続テストを別 Sprint に割る余地がある(特に接続テスト S4-15〜19 は会議本流と非依存で分離可)。運用系の S4-6〜11(緊急発行 / Operator 監視 / 退室 / PiP / 接続診断/Stats/Help / 招待リンク)は Sprint 3 へ前倒し(S3-13〜18)のため欠番。S4-14(Transcription 公開API実装)は S4-19 に統合。S4-2(認可正典化)は廃止し、認可は各機能タスクと同じタイミングで実装する方針(RoomPolicy 単一点化の芯は S2-2)。S4-12(委譲信頼 / クロスサブドメイン認証 E2E)は削除。
| ID | サイズ | タスク |
|---|---|---|
| S4-1 | S | 残 Capability story |
| S4-3 | L | Webhook 配信基盤(W3〜W6) — webhook_endpoints(multi-endpoint / 個別 secret / 購読フィルタ)・HMAC 署名・リトライ(指数バックオフ5回)・5回失効後破棄。W1/W2 は S1-6 で前倒し済。PoC は tenant0・1endpoint に絞り multi は v2 退避 |
| S4-4 | L | Transcription バッチ — 録画完了(W3 available) → STT → VTT → W6。ffmpeg / BullMQ・複数ベンダ(azure 既定・話者分離既知バグ回避)・status 追跡。要約は調査残置 |
| S4-5 | L | 調査↔基盤 連携実装 — ルーム作成 / トークン発行 / 退室トリガー / 録画参照 |
| S4-13 | S | OpenAPI v0.3 公開(文字起こし・接続テスト) |
| S4-15 | L | 接続テスト 計測エンジン — LiveKit 版ダミー配信 + 購読負荷・MEASUREMENT_MIN_SECONDS=15。現 BrowserTestHistory のコア化。iOS/WebKit/CDN 既知地雷は S0 スパイク③で先行検証 |
| S4-16 | L | 接続テスト 8チェック + 最適判定 — signaling / webrtc / turn / reconnect / publish_audio / video / protocol / region + best_protocol/region |
| S4-17 | M | 接続テスト ConnectionTestEvent 診断ログ — action_type + check_type |
| S4-18 | L | 接続テスト UI — 基盤ホスト画面・短命 test スコープトークン・計測保存は基盤内部 endpoint |
| S4-19 | L | 公開API 実装(v0.3:文字起こし + 接続テスト)+ W5 — Transcription 3本 + POST/GET /connection-tests・connection_test.completed。これで全公開エンドポイント完了。合否判定(User.webrtc_test_status)・参加可否反映は調査側残置(旧 S4-14 を統合) |
G5 ゲート:Webhook 配信・文字起こしバッチ・API 連携・接続テスト(本番前のブラウザ/回線品質チェック)が揃う。★ 公開API 全エンドポイント実装完了=新基盤 core 稼働 → www-Phase3 アンブロック。
Sprint 5 — 🎯 G6 E2E + パイロット
ゴール:全 Capability + multi-actor E2E + 内部パイロット。
| ID | サイズ | タスク |
|---|---|---|
| S5-1 | M | Playwright + LiveKit 統合 |
| S5-2 | S | multi-context シナリオ基盤 — observer 密談 / ban / 録画 / 即席多人数 |
| S5-3 | L | Smoke E2E 5〜9 シナリオ(異常系含む) |
minedia-www レーン(並走)
調査ドメイン側の Phase0〜3。Phase0/1 は core 非依存で S0 から即着手。Phase2 は OpenAPI 公開、Phase3 は core 稼働が gate。
| ID | サイズ | Phase | 並走先 | ゴール(受け入れ) | core 依存 |
|---|---|---|---|---|---|
| WWW-P0 | L | Phase0 seam | S0〜S1 | Slot#interview_room 統一 IF で OpenTok を OpentokRoom ラップ・(B)読み取りアダプタ経由・挙動完全無変更 / 全テスト緑 | 即着手 |
| WWW-P1 | L | Phase1 migration | S0〜S1 | webrtc_engine / interview_room_refs(二股FK+cached列) / 事後処理4モデルに recording_uuid+slot_id/project_id(additive・可逆) | 即着手 |
| WWW-P2a | L | Phase2 client 土台 | S2(v0.1後) | vendoring + WebMock + openapi_parser 契約検証 → CoreApiClient 土台 | v0.1 |
| WWW-P2b | L | Phase2 LivekitRoom | S2〜S3 | LivekitRoom アダプタ(API on demand + デグレード)・engine 分岐・共有コントラクトテスト | v0.1 |
| WWW-P2c | L | Phase2 作成+JWT | S3〜S4 | Session/Room 作成(POST /sessions・Idempotency・outbox) + 入室 JWT 発行 + 緊急発行 UI。キャンセル時 DELETE /sessions 発火 + outbox リトライ。作成失敗(502)時のフォールバック方針(エラー提示 / リトライ / エンジン確定) | v0.1 |
| WWW-P2d | L | Phase2 webhook 受信 | S4 | Webhook receiver(署名検証 / ±5分 / event.id 重複排除)・W1〜W6 → cached_*/事後処理 populate・失効後 reconciliation。出欠判定材料(is_attend)の取り込みを明示 | v0.1 |
| WWW-P2e | L | Phase2 (C)読み取り | S4 | (C)読み取り書換(room ホップ除去)・既存行 backfill・populate-on-create | P2b/c/d 後 |
| WWW-CT | M | 接続テスト連携 | S4 | 接続テスト結果参照(GET /connection-tests) + W5 受信 → 合否判定 User.webrtc_test_status 反映・案件参加可否(合否ロジックは調査残置・基盤側は S4-19) | v0.3 |
| WWW-RM | M | リマインドURL JWT化 | S2〜S4 | リマインド10種の確認 URL(users_offer_url 等)を JWT 化。15分窓ガード / 冪等性 / TZ の既存ジョブ回帰テスト | v0.1 |
| WWW-P3 | L | Phase3 結合 | S5(★core 稼働後) | 実 core 差替・1案件 e2e・二重運用投入・legacy read-only 化・物理 FK 廃止。両エンジン同一 UI 描画を E2E 受け入れに。着手前に詳細計画化必須(データ移行範囲は別 Issue 切り出し) | core 稼働 |
本ページは独立アプリ化(OpenTok → LiveKit 移行)の開発計画ドキュメントです。新基盤レーンと minedia-www レーンの2レーン並走を、シナリオ階段とスプリント単位で整理しています。