v1
PoC / 開発計画

インフラ構成

実査機能 新基盤のインフラ構成。コンピュート=Cloudflare(常駐ゼロ・全て従量)/データ永続=AWS 東京(国内保管)/メディア・データ配信=LiveKit Cloud のハイブリッド構成を採用する。開発への展開は開発プラン Phase 0 を参照。

1. 決定サマリ

領域決定備考
基盤コア API採用 Cloudflare Workers(Hono + @hono/zod-openapi + Prisma 7)エントリポイント4種(fetch / queue / workflows / scheduled)
DB採用 AWS Aurora Serverless v2(PostgreSQL・東京)min 0.5 ACU 常時。見送り D1(レジデンシ・トランザクション制約)
DB 接続採用 Hyperdrive → 公開エンドポイント直結SG=Hyperdrive 公開 IP レンジのみ + TLS verify-full
オブジェクトストレージ採用 AWS S3(東京)録画・handout(文字起こし本文は Aurora 行内 result_json・As-Is 踏襲)。不採用 R2(リージョン保証不可)
W1〜W6 配信採用 Cloudflare Queues + DLQリトライ・DLQ 組み込み
録画→文字起こし採用 Cloudflare Workflowsステップ実行(ステップごとに結果を永続化し、失敗時は失敗ステップから再開)・ステップ単位リトライ
定期実行採用 Cron Triggersリコンサイルバッチ
チャット採用 LiveKit データチャネル再利用(サーバー権威型)不使用 独自 WS サーバー・Durable Objects
ルーム SPA採用 Vite + React SPA + Workers Assets 配信SSR 不要(OpenNext / Next.js は不採用)
管理画面(開発者向け)採用 Refine SPA on Workers(Workers Assets)+ Cloudflare Accessコアの内部プロキシ /internal/admin 経由・ApiKey 非露出(開発プラン §1.4)。ルーム SPA・コアと同じ Workers 系ツールチェーンに統一(Pages は不使用
メディア外部 LiveKit Cloud(SFU + Egress・Ship プラン録画は video composite(合成1本)・Egress は S3 東京へ直書き
AI モデレーター外部 LiveKit Managed Agent Hostinglk agent deploy。自前の Agent 基盤を持たない
文字起こし AI外部 Azure Speech / OpenAI Whisper / ElevenLabsWorkflows から REST 呼び出し・VTT 出力
オブザーバビリティCF ネイティブ(Traces / Workers Logs / Analytics Engine)+ @sentry/cloudflareTeam プラン外部集約先(Grafana Cloud 等)は導入しない。実装方法は オブザーバビリティの Cloudflare 補遺が正
minedia-www既存 現行インフラのまま(Rails)REST(ApiKey)で呼び出し・W1〜W6 受信。Phase 5 でレーンB改修

2. 全体構成図

クリックで拡大 🔍
インフラ構成図(Cloudflare 軸): ブラウザ(全ロール)はルーム SPA・基盤コア Worker(入室ゲート・API・チャット送信)に接続し、メディアとチャット/イベントの受信は LiveKit Cloud に直結する。基盤コアはチャット ingest を認可・永続化して sendData で配信する。Cloudflare ゾーンには基盤コア Worker(Hono + zod-openapi + Prisma 7)、Queues(W1〜W6 配信 + DLQ)、Cron Triggers、Hyperdrive、Workflows、管理画面(Refine SPA・Workers Assets + Cloudflare Access)が並ぶ。Hyperdrive は AWS 東京の Aurora Serverless v2(PostgreSQL・min 0.5 ACU・公開エンドポイント直結)へ TLS verify-full で接続。LiveKit Egress は S3 東京へ録画を直書きし、minedia-www は presigned GET で録画を視聴、REST API(ApiKey 認証)で基盤コアを呼び出し、Queues から W1〜W6 署名付き Webhook を受信する。Workflows は AI 文字起こし(Azure / OpenAI Whisper / ElevenLabs)へ依頼。エラーは Sentry へ送られる

主要フロー

  1. 入室: ブラウザ → SPA → 基盤コア(参加 JWT 検証 → RoomPolicy → LiveKit トークン発行)→ LiveKit へメディア直結。映像・音声は Cloudflare を通らない
  2. チャット/ルームイベント(サーバー権威型): 送信=ブラウザ → コア Worker の HTTP ingest(RoomPolicy 認可 → Aurora 永続化 → 宛先算出)→ RoomServiceClient.sendData → LiveKit データチャネルで配信。受信=DataReceived。クライアント直送は不可(canPublishData 全ロール false)。後入室・リロード時は履歴 API(GET /rooms/{id}/chat-messages)で補完
  3. 録画: LiveKit Egress → S3 東京へ直書き → webhook → Workflows が文字起こしをステップ実行 → W6 配信
  4. W1〜W6: 基盤コア → Queues(リトライ・DLQ)→ minedia-www へ署名付き配信
  5. DB: 基盤コア → Hyperdrive(接続プール)→ Aurora 公開エンドポイント。書き込み RTT は Smart Placement(Worker を東京近傍で実行)で圧縮
  6. 録画視聴: download-url API で presigned URL を発行し S3 から直接配信

3. 技術スタック

3-1. Worker 構成(デプロイ単位)

Worker は「プロセス」ではなくデプロイとアクセス制御の境界で切る。1 Worker は複数ハンドラ(fetch / queue / scheduled / Workflow クラス)を同居できるため、基盤コアの非同期処理は分割しない。

Worker中身分割理由
① 基盤コアapps/coreHono(fetch)+ Queues consumer + Cron + Workflows + 内部プロキシ /internal/adminAPI 契約と非同期処理が同じ Prisma スキーマ・RoomPolicy を共有。Smart Placement はこの Worker のみ有効化
② ルーム SPAapps/interview-roomWorkers Assets(静的配信)UI は API と独立したデプロイ頻度。配信はエッジ最寄り
③ 管理画面apps/adminWorkers Assets(Refine SPA)Cloudflare Access を被せる境界を公開物と分離

ドメインは Worker 単位に割り当て(例: api.* → ①、room.* → ②、admin.* → ③ + Access)。管理画面 → コアは Service Bindings で内部接続(公開ホップなし・CORS 回避)。負荷特性が分かれた場合、queue consumer / Workflows は後から④として分離可能(wrangler.jsonc を分けるだけ)。

🔗

Service Bindings とは: Worker 同士をネットワークを介さず直接呼び出す Cloudflare の仕組み。呼び出し側の wrangler.jsonc に "services": [{ "binding": "CORE", "service": "interview-core" }] と宣言すると env.CORE.fetch(request) で相手 Worker を呼べる。見た目は fetch だが実際は同一スレッド上での直接実行のため、公開 URL への出戻り(DNS・TLS・エッジ再入場)が発生しない。ブラウザは管理画面のオリジンとしか通信しないため CORS 設定も不要。コアの /internal/admin は Service Bindings 経由でのみ到達可能にでき、公開インターネットに管理 API の入口を持たない。

apps/core/                     ← 基盤コア Worker
  wrangler.jsonc               ← bindings: Hyperdrive / Queues / Analytics Engine / Rate Limiting
  src/index.ts                 ← export default { fetch, queue, scheduled } + Workflow クラス
  src/api/                     ← Hono(@hono/zod-openapi ルート定義・ミドルウェア)
  src/queue/ src/workflows/ src/cron/ src/lib/
  prisma/schema.prisma
apps/interview-room/                 ← ルーム SPA
apps/admin/                    ← 管理画面(Refine)
packages/contracts/            ← zod スキーマ・生成 openapi.yaml・API 型(全アプリで共有)

3-2. 基盤コア(apps/core)

領域採用備考
HTTP / 契約hono + @hono/zod-openapiルート定義=zod スキーマ=OpenAPI の単一ソース(G1 の実体)
OpenAPI UI@scalar/hono-api-reference確定。コア Worker の /docs ルートに Scalar UI をミドルウェアとしてマウント(app.doc() の OpenAPI 出力をそのまま参照、別ホスティング不要)
ORMprisma 7 + @prisma/adapter-pgHyperdrive 経由。prisma migrate は CI から TCP 実行
JWTjoseEdDSA 署名・/.well-known/jwks.json 公開(jsonwebtoken は EdDSA 非対応)
LiveKitlivekit-server-sdkAccessToken / RoomServiceClient.sendData(チャット配信)/ Egress / WebhookReceiver。Workers 実機確認は P0 スパイク
S3aws4fetchSigV4 の presign / put(@aws-sdk より軽量)
ApiKey 照合bcryptjs + crypto.subtle.timingSafeEqualtruffle-survey-v2 と同系
バリデーションzodpackages/contracts で共有)
ログ / 監視構造化 console(JSON → Workers Logs)、cloudflare:workers tracing API、Analytics Engine writeDataPoint@sentry/cloudflaretracesSampleRate: 0標準 OTel SDK は Workers 非対応(オブザーバビリティの Cloudflare 補遺 §2)
テストvitest + @cloudflare/vitest-pool-workers、convention testworkerd 実ランタイムでテスト。convention は truffle 移植(エンベロープ形式 / 全ルート認証必須 / ルート網羅 / no-floating-promises)

3-3. ルーム SPA(apps/interview-room)

領域採用備考
フレームワークVite + React SPA + Workers Assets(確定)SSR 不要のため OpenNext / Next.js は不採用
WebRTClivekit-client + @livekit/components-react / -styles参加者タイル・デバイス制御・画面共有
接続テストlivekit-client 同梱の ConnectionChecksignaling / webrtc / turn / reconnect / publish(P4 の自前計測画面の中核)
API クライアントopenapi-typescript + openapi-fetchpackages/contracts の型で契約を FE でも強制
状態管理@tanstack/react-query(サーバー状態)/ zustand(UI 状態)
UI / 監視Tailwind CSS / @sentry/react

3-4. 管理画面(apps/admin)

Refine(React)+ Vite を Workers Assets で配信し、Cloudflare Access(Zero Trust)でゲート。データ取得は基盤コアの内部プロキシ /internal/admin 経由(Cf-Access-Jwt-Assertion 検証・テナント ApiKey 非露出)。API クライアントは SPA と同じ openapi-fetch を共有。

3-5. 開発ツールチェーン

領域採用
モノレポpnpm workspace(apps 3つ + packages/contracts
デプロイwrangler(environments で dev / stg / prd、wrangler types で Env 型生成、wrangler secret put。DB 資格情報は AWS Secrets Manager)
CI/CDGitHub Actions: typecheck / lint / test / prisma migrate / wrangler deploy
OpenAPI生成 yaml を redocly lint、UI 配信は Scalar(@scalar/hono-api-reference・確定)、@stoplight/prism-cli モック(レーンB の G2 前先行着手用)
LintESLint(no-floating-promises 必須)+ Prettier

3-6. minedia-www 側(レーンB・Phase 5)

領域採用
Core::ApiClientfaraday + faraday-retry(ApiKey 認証・Idempotency-Key・リトライ。既存 faraday_middleware 1.x 系との共存に注意)
契約テストcommittee(Prism モックに対して G2 前に先行実装)
W1〜W6 受信OpenSSL::HMAC 署名検証(標準ライブラリ)・イベント id dedup。非同期処理・通知は既存流用(Sidekiq / Twilio / SES / OneSignal)

4. Cloudflare 軸の根拠

評価軸: ①アイドル時固定費最小(サーバーレス徹底)②運用対象最小③データレジデンシ(国内保管の一貫説明)。コスト差は月数十ドル=人件費数時間分であり決め手ではない

  1. 常駐コンポーネントがゼロになる: API(Workers)・キュー(Queues)・パイプライン(Workflows)・定期実行(Cron)のすべてがマネージドかつ従量。チャット配信も LiveKit データチャネルに相乗りするため独自 WS サーバーを持たない。DB 接続も Hyperdrive から Aurora の公開エンドポイントへ直結するため、「自前で面倒を見るプロセス」が文字通り 0 になる
  2. コールドスタート実質ゼロ: Workers は isolate モデルで復帰 ~数ms・自動水平スケール。予約制インタビューの体感遅延源が存在しない(Aurora は min 0.5 ACU 常時でウォーム)
  3. 重い処理は Workers を通らない: 映像・音声は LiveKit 直結、静的アセットはエッジ配信。Workers が処理するのは短命 HTTP(認可・書込・webhook)のみで、128MB/isolate・同時接続 6 の制約は業務特性上ボトルネックにならない

5. 月額コスト試算

規模前提(Medium): 月200インタビュー×60分・全件録画60分・180日保管(定常在庫 ~1.2TB)・視聴転送 ~400GB/月・AI モデレーター比率 30%。LiveKit 費は #5317 の既存試算を使用(7人/セッション=publisher 2 + subscriber 5・720p ≈2Mbps・録画前提・¥160/USD)。オーダー把握用であり、規模実値の確定後に精緻化する。

5-1. ホスティング層(クラウド請求額)

項目月額算定前提
Workers Paid$5基本料。動的リクエスト実勢 月5〜10万件(チャット ingest 含む)は包含枠(10M req・30M CPU-ms)内
Queues / Workflows / Cron~$0W1〜W6 は月数千メッセージ=無料枠内。Workflows は Workers 従量に包含
Hyperdrive / Smart Placement / Rate Limiting / Access$0Workers Paid 込み・無料枠内(Access は 50 ユーザーまで無料)。静的アセット配信(ルーム SPA・管理画面)は Workers Assets で無料
Workers Logs / Traces / Analytics Engine$0~22万イベント/月 ≪ 包含枠 2,000万(オブザーバビリティ補遺の試算)
Cloudflare 小計~$5
Aurora Serverless v2~$73compute 0.5 ACU×730h×$0.15 ≈ $55 + storage 50GB×$0.12 ≈ $6 + I/O ~50M req×$0.24/M ≈ $12
S3 保管未定現行の実利用量を調査後に反映
S3 視聴転送未定同上(視聴のたび発生・感度大)
AWS 小計~$73 + S3(未定)
ホスティング計~$78 + S3(未定)

5-2. 監視

項目月額備考
Sentry~$26Team プラン(確定)。traces / logs は CF ネイティブで完結し、外部集約先(Grafana Cloud 等)は導入しない
~$26

5-3. 外部 SaaS(クラウド選定と独立・参考)

項目月額備考
LiveKit Cloud(Ship・録画込)~$507(≈¥81,200)基本 $50 + 下り転送 (2,160GB−250GB)×$0.12 ≈ $229 + 合成録画 (12,000分−600分)×$0.02 ≈ $228。接続分 84,000 分は無料枠 150,000 分内で $0(#5317 試算
AI(OpenAI Realtime 30% + STT)未定現行の実利用量を調査後に反映
~$507 + AI(未定)

5-4. 総計・感度

月額
ホスティング + 監視~$104 + S3(未定)
外部 SaaS 込み総計(確定分)~$610 + S3・AI(未定)
📉

感度・削減レバー: 規模実値(インタビュー数・参加者数に概ね線形)。S3・OpenAI は現行実測の調査後に反映(§6)。

6. 未決事項(Phase 0 で確定)

#事項対応
1規模実値による試算精緻化現行 minedia-www の実測値で更新(S3・OpenAI 利用料の実測を含む

7. 経緯資料

  • D1 採用評価(docs/interview-app-poc/d1-database-assessment.md)— 見送り。Aurora 東京でレジデンシ・トランザクション懸念を解消
  • オブザーバビリティ — 監視設計(Cloudflare での実装方法を含む)

本ページは実査機能 新基盤のインフラ構成です。構成図・根拠・コスト試算・未決事項を整理しています。