最終更新: 2026-02-25
| 領域 | 完了度 | 詳細 |
|---|---|---|
| モノレポ基盤 | 100% | Turborepo + Bun ワークスペース、CI/CD (GitHub Actions)、lint/format (oxlint/oxfmt)、lefthook pre-commit |
| DynamoDB テーブル設計 | 100% | 5テーブル(Users, Costumes, UserCostumes, CostumeBuilds, Sessions)+ GSI 定義済み。docker compose up + bun run db:init で即起動 |
| リポジトリ層 | 100% | 全5テーブルの CRUD を楽観的ロック付きで実装済み(packages/server/src/repositories/) |
| tRPC 基盤 | 100% | publicProcedure / protectedProcedure、JWT middleware、コンテキスト抽出、ルーター構成 |
| JWT 認証フロー | 90% | jose HS256 署名・検証実装済み。nfcLogin mutation 動作するが、DB からのユーザー検索が未接続(後述) |
| リアルタイム通信 | 95% | tRPC SSE subscriptions 3チャンネル(projector / session / signaling)。EventEmitter ベース。WebRTC シグナリング(offer/answer/ICE)完備 |
| ガチャロジック | 85% | 重み付きランダム(normal 60% / rare 25% / superRare 12% / ultraRare 3%)。純粋関数+テスト済み。DB 連携が未接続 |
| S3 / ローカルファイル保存 | 80% | デュアルモード(本番: S3 / ローカル: .local/uploads/)。ファイル配信エンドポイントあり |
| WebRTC 接続(admin ↔ projector) | 80% | DataChannel でメッセージ送受信可能。ハートビート/キープアライブ実装済み |
| GitHub Pages デプロイ | 100% | admin + projector を /admin, /projector にデプロイ |
| Zod スキーマ | 100% | packages/shared/src/schemas.ts に全ドメインモデル + Input + Event 型を定義済み |
| Bedrock クライアント | 50% | AWS SDK 接続設定のみ。実際の呼び出しロジックなし |
| 領域 | 完了度 | 不足している部分 |
|---|---|---|
| NFC 読み取り | 30% | QR コード読み取りは動作する。Web NFC API は未実装(手動入力の prompt() のみ) |
| ユーザー DB 検索 | 10% | auth.ts の nfcLogin で nfcId → User 検索をしていない。nfcId をそのまま userId として使用中(TODO コメントあり) |
| ガチャ → DB 連携 | 10% | gacha.ts ルーターがハードコード衣装を返す。Costumes テーブルから実際に引いていない。UserCostumes への保存もなし |
| 写真アップロード | 20% | tRPC エンドポイント定義済みだが、Base64 デコード・S3 保存・URL 保存がすべてハードコード |
| 衣装一覧 API | 10% | costumes.list() が空配列を返す。DB から取得していない |
| 衣装構築 API | 10% | リポジトリは完璧。tRPC ルーターに create/update/delete/equip エンドポイントなし |
| モバイル UI | 5% | プレースホルダーの見出しのみ。全画面未実装 |
| プロジェクター映像 | 10% | WebRTC 接続とステータス表示のみ。動画再生・顔合成表示なし |
| 顔検出・合成 | 0% | Bedrock クライアントがあるだけ。合成ロジック・動画生成の実装なし |
| ノーツ&スコア | 0% | 未着手(Should 優先度) |
| リザルト画面 | 0% | 未着手(Should 優先度) |
| コスチュームシードデータ | 0% | DB に衣装マスターデータが入っていない |
| Terraform / 本番 AWS | 10% | GitHub Actions ワークフローのみ。Terraform 設定ファイルなし |
DB 接続の穴を埋めて、エンドツーエンドのデータフローを通す。
-
0-1. コスチュームシードデータ作成
scripts/seed-costumes.tsを作成- 各レアリティに衣装を 3〜5 件ずつ投入
bun run db:seedスクリプトをpackage.jsonに追加
-
0-2.
nfcLoginのユーザー DB 検索を接続packages/server/src/trpc/routers/auth.tsの TODO を解消- nfcId-index GSI でユーザー検索 → 存在しなければ新規作成 → JWT 返却
-
0-3. ガチャの DB 連携
gacha.tsルーターで Costumes テーブルからレアリティ別に取得- UserCostumes テーブルに保存
isNewフラグを正しく判定
-
0-4. 衣装一覧 API 接続
costumes.list()で UserCostumes → Costumes を JOIN して返却costumes.equip()で CostumeBuilds を更新
来場者がスマホで操作する全画面を構築。
-
1-1. ルーティング設計
/— ログイン待ち / QR スキャン案内/mypage— マイページ(名前・スコア・メニュー)/gacha— ガチャ画面/costumes— 衣装一覧/build— 衣装構築/photo— 写真アップロード
-
1-2. マイページ
- ユーザー情報表示(
trpc.users.me.useQuery()) - 各画面へのナビゲーション
- ユーザー情報表示(
-
1-3. ガチャ画面
- ガチャ演出アニメーション
trpc.gacha.pull.useMutation()連携- 獲得衣装の表示
-
1-4. 衣装一覧画面
- 獲得済み衣装のグリッド表示
- レアリティ別フィルタ
-
1-5. 衣装構築画面
- 衣装スロット選択 UI
- ビルド保存(
trpc.costumes.createBuild.useMutation())
-
1-6. 写真アップロード画面
- カメラ起動(
getUserMedia) - 撮影 → プレビュー → アップロード
trpc.users.uploadPhoto.useMutation()連携
- カメラ起動(
- 2-1.
uploadPhotoエンドポイント実装- Base64 → Buffer デコード
- S3 (またはローカル) に保存
- Users テーブルに
photoUrlを更新 - レスポンスに URL を返す
- 3-1. Web NFC API 統合
NDEFReaderで NDEF メッセージからシリアル番号を取得- フォールバック: Web NFC 非対応端末では手動入力 UI を残す
- NFC スキャン →
trpc.sub.nfcScan.mutate()→ projector へ broadcast
デモの核。技術選定を含む。
-
4-1. 合成方式の決定
- 選択肢 A: Bedrock (Nova Canvas / Titan Image) で静止画を生成 → 動画のフレームに合成
- 選択肢 B: Bedrock で顔の位置を検出 → Canvas API / Three.js でリアルタイム合成
- 選択肢 C: サーバー側 FFmpeg で動画を生成
- 推奨: 選択肢 B(リアルタイム性が高く、30秒制約をクリアしやすい)
-
4-2. Bedrock 呼び出し実装
synthesis.start()で合成処理を開始- 顔画像 + 衣装情報を入力
- 進捗を
sessionSSE チャンネルで配信
-
4-3. 合成結果の保存・配信
- 生成物を S3 に保存
- プロジェクターへ URL を SSE で通知
-
5-1. 待機画面
- QR コード表示(来場者の接続用)
- 「カードをかざしてください」の案内
-
5-2. ダンス動画再生
<video>+ Canvas オーバーレイ- ユーザーの顔画像を動画上に合成表示
- 衣装の反映
-
5-3. SSE イベントハンドリング
NFC_SCANNED→ ユーザー情報取得 → 準備画面表示GACHA_RESULT→ 衣装獲得演出SYNTHESIS_COMPLETE→ 動画再生開始
-
6-1. フロー結合テスト
- NFC / QR スキャン → ユーザー特定
- モバイルでガチャ → 衣装獲得
- 写真アップロード
- 顔合成開始 → 完了
- プロジェクターでダンス動画再生
-
6-2. エラーハンドリング
- 接続断時のリトライ
- 合成タイムアウト時のフォールバック表示
-
7-1. ノーツ&スコア
- BGM 同期のタイミング判定
- ノーツ UI(プロジェクター)
- スコア計算ロジック
-
7-2. リザルト画面
- スコア表示
- ランク判定(S/A/B/C)
- リプレイ / 次のユーザーへの遷移
-
8-1. Terraform 構成
- EC2 (サーバー) + DynamoDB + S3 + CloudFront
- セキュリティグループ / IAM ロール
-
8-2. 環境変数設定
- 本番用
JWT_SECRET, AWS credentials - S3 バケットポリシー
- 本番用
-
8-3. デプロイ確認
- GitHub Pages (admin / projector)
- EC2 (server)
| 時間 | 担当 | タスク |
|---|---|---|
| 09:00-10:00 | 全員 | フェーズ 0(基盤修正)を分担 |
| 10:00-12:00 | A | フェーズ 1(モバイル UI: マイページ + ガチャ) |
| 10:00-12:00 | B | フェーズ 4-1, 4-2(顔合成の技術選定 + Bedrock 実装) |
| 10:00-12:00 | C | フェーズ 2(写真アップロード API)+ フェーズ 3(NFC) |
| 時間 | 担当 | タスク |
|---|---|---|
| 13:00-15:00 | A | フェーズ 1 続き(衣装一覧 + 構築 + 写真アップロード画面) |
| 13:00-15:00 | B | フェーズ 4-3(合成結果保存)+ フェーズ 5-2(動画再生) |
| 13:00-15:00 | C | フェーズ 5-1, 5-3(プロジェクター待機画面 + SSE連携) |
| 15:00-17:00 | 全員 | フェーズ 6(結合テスト + バグ修正) |
| 時間 | 担当 | タスク |
|---|---|---|
| 09:00-10:00 | 全員 | 前日のバグ修正 + 仕上げ |
| 10:00-11:00 | A | フェーズ 7(Should 機能)※ 余裕があれば |
| 10:00-11:00 | B | フェーズ 8(本番デプロイ) |
| 10:00-11:00 | C | デモリハーサル + UX 改善 |
| 11:00-12:00 | 全員 | 最終デモリハーサル |
-
動画合成の実装方法
- Canvas API でリアルタイム合成(推奨)
- Three.js で 3D 空間に配置
- FFmpeg サーバー側処理
-
Bedrock で使用するモデル
- Nova Canvas(画像生成)
- Claude Vision(顔検出の座標取得)
- Titan Image Generator
-
衣装データの形式
- 画像アセット(PNG/SVG)の管理場所
- レイヤー構成(頭/体/足 等)
| リスク | 影響度 | 対策 |
|---|---|---|
| 顔合成が 30 秒以内に収まらない | 高 | Canvas API で簡易合成にフォールバック。静止画合成をまず動かす |
| Web NFC が会場端末で動かない | 中 | QR コードスキャンをバックアッププランとして維持(既に実装済み) |
| Bedrock のレート制限 | 中 | 合成結果をキャッシュ。同一ユーザーの再合成を避ける |
| モバイル UI が間に合わない | 高 | 最低限ガチャ + 写真アップロードのみ実装。衣装構築は後回し |
| 本番デプロイのトラブル | 中 | ローカル環境でデモ可能なように構成(DynamoDB Local + ローカルファイル保存) |
NFC/QR スキャン → ユーザー認証 → モバイルページ表示
↓
ガチャで衣装獲得
写真アップロード
↓
顔合成処理(Bedrock)
↓
プロジェクターで動画再生
ボトルネック: 顔合成(フェーズ 4)が最大の技術リスク。ここが動かないとデモの核が成立しない。 推奨: フェーズ 4 の技術検証を最優先で着手し、午前中に PoC を完了させる。