| 階層 | 対象 | アプリ | 主な機能 |
|---|---|---|---|
| L1 プラットフォーム | Gonmura | admin/gonmura (Next.js) | 事務所管理、全体統計、システム設定 |
| L2 事務所 | 芸能事務所等 | admin/agency (Next.js) | タレント管理、パスコード設定、収益確認 |
| L3 配信者 | タレント | talent-app (KMP) | 配信開始/終了、ビンゴ抽選、コメント確認 |
| L4 視聴者 | ファン | src/ (React + Vite) | ライブ視聴、ギフト、ビンゴ、質問投票 |
| ルール | 説明 |
|---|---|
| 集計値・残高を保存しない | COUNT / SUM / 残高はサブコレクションから都度集計する |
| 名前を埋め込まない | userId のみ保存し、表示時に users を参照する |
| 定数を複製しない | giftName, price は GIFT_DEFINITIONS から導出 |
| データの正本は1箇所 | 同じデータを複数コレクションに持たない |
| 必要な値 | 導出方法 |
|---|---|
| コイン残高 | SUM(users/{id}/transactions.coins WHERE status=completed) - SUM(giftHistory 価格) |
| 配信者名 | users/{streamerId}.displayName |
| 視聴者数 | COUNT(viewers WHERE isActive=true) |
| ギフト合計 | SUM(gifts → GIFT_DEFINITIONS[giftId].price) |
| ギフト名・価格 | GIFT_DEFINITIONS[giftId] |
| 投票数 | COUNT(votes) |
| 累計消費 | COUNT(giftHistory) × GIFT_DEFINITIONS[giftId].price |
| タレント数 | COUNT(agencies/streamers) |
配信者A に対して:
└── パスコード "ABCD1234"(1つだけ)
├── ファン1 -> このコードで入室 OK
├── ファン2 -> 同じコードで入室 OK
└── ファン3 -> 同じコードで入室 OK
-> 事務所がいつでもコードを変更可能
データ保存先:
agencies/{agencyId}/streamers/{streamerId}
└── passcode: "ABCD1234" (たった1フィールド)
| 操作 | 処理内容 |
|---|---|
| パスコード確認 | agencies/{id}/streamers/{id}.passcode を読み取って表示 |
| パスコード変更 | agencies/{id}/streamers/{id}.passcode を上書き更新 |
| パスコード無効化 | passcode フィールドを空文字 or 削除 |
COUNT(streams/gifts) × GIFT_DEFINITIONS[giftId].price で都度算出。
| 表示に必要な値 | 導出方法 | 使用画面 |
|---|---|---|
| 配信者名 | users/{streamerId}.displayName |
ライブ画面、ホーム、管理画面 |
| 視聴者数(リアルタイム) | COUNT(streams/{id}/viewers WHERE isActive=true) |
ライブ画面 |
| ピーク視聴者数 | MAX(streams/{id}/viewers の同時 isActive 数)または配信終了時に1回だけ計算して streams に記録 |
配信統計 |
| ギフト合計額 | SUM(streams/{id}/gifts.totalCost) |
タレント画面、収益レポート |
| ギフト名・価格 | GIFT_DEFINITIONS[giftId].name / .price |
ギフト履歴、管理画面 |
| コメント投稿者名 | users/{userId}.displayName |
ライブ画面コメント欄 |
| 投票数 | COUNT(questions/{id}/votes) |
質問投票箱 |
| ビンゴ参加者数 | COUNT(streams/{id}/bingoCards) |
ビンゴゲーム画面 |
| ビンゴ勝者数 | COUNT(bingo/current/winners) |
ビンゴゲーム画面 |
| コイン残高 | SUM(users/{id}/transactions.coins WHERE status=completed) - SUM(giftHistory → GIFT_DEFINITIONS[giftId].price) |
全画面(ヘッダー表示等) |
| ユーザー累計消費 | SUM(users/{id}/giftHistory → GIFT_DEFINITIONS[giftId].price) |
Gonmura管理画面ユーザー詳細 |
| ユーザー累計ギフト数 | COUNT(users/{id}/giftHistory) |
Gonmura管理画面ユーザー詳細 |
| タレント数 | COUNT(agencies/{id}/streamers WHERE status IN [active, inactive]) |
事務所ダッシュボード |
| 月次売上 | SUM(streams WHERE agencyId=X AND startedAt in month → SUM(gifts価格)) |
事務所ダッシュボード、収益画面 |
| 事務所名 | agencies/{agencyId}.name |
Gonmura管理画面 |
| タレント配信数 | COUNT(streams WHERE streamerId==X) |
事務所タレント一覧 |
| タレント累計収益 | SUM(streams WHERE streamerId=X → SUM(gifts価格)) × タレント分配率 |
事務所タレント一覧 |