CastBox ダッシュボード 仕様書

版 2.0 / 最終更新: 2026-04-25 / 対象リビジョン: castbox-dashboard-00078-2zj

1. 概要

MNP獲得実績を可視化する自社ダッシュボード。Tableauの代替として、Google Sheetsの入力フォーム(成果報告・出発報告)を5分ごとに取得・集計し、FastAPI + Chart.js で表示する。

項目内容
本番URLhttps://castboard-data-reader.web.app
廃止URL(*.run.app 直アクセスは web.app へ 301 リダイレクト)https://castbox-dashboard-80063870039.asia-northeast1.run.app / https://castbox-dashboard-3x2gddnwgq-an.a.run.app
GCPプロジェクトcastboard-data-reader
リージョンasia-northeast1
サービス名castbox-dashboard
最新リビジョンcastbox-dashboard-00078-2zj
スプレッドシートID1KdORhEshilEWEESRySSc9qATGRj6m-HdEiLO9RN6kcI

2. システム構成

[ Google Sheets (入力フォーム) ]
        │ gspread (Service Account認証, readonly)
        ▼
[ core/pipeline.py ] 取得・名寄せ・結合・集計
        │
        ▼
[ api/cache.py ] インメモリ DataFrame + SQLite永続化 + 5分バッチ更新
        │
        ▼
[ api/auth.py ] Firebase Auth ミドルウェア(JWT検証)
        │
        ▼
[ api/main.py ] FastAPI REST + StaticFiles(ui/ をルートにマウント)
        │
        ▼
[ ui/ ] vanilla JS + Chart.js(外部CSS/JS分割済 T-19)
  index.html ← スプラッシュ + ダッシュボード + マイページオーバーレイ
  login.html ← Firebase Auth ログイン画面
  account.html ← アカウント設定(スタンドアロン)

2.1 実行環境

2.2 依存ライブラリ

パッケージバージョン
fastapi>=0.111.0
uvicorn[standard]>=0.29.0
gspread>=6.1.0
google-auth>=2.29.0
pandas>=2.2.0
firebase-admin>=6.5.0

3. データソース

3.1 シート一覧

シート名用途主要列
成果報告_V3退勤時の獲得件数A:timestamp / B:email / E:client / F〜N:キャリア別件数 / U:備考
出発報告_V2出勤時の稼働場所申告A:timestamp / B:email / G:クライアント / H〜N:稼働場所 / R:氏名
氏名マスタメール→氏名(低優先)A:email / B:氏名
ユーザー登録_V1メール→氏名(高優先)B:email / C:氏名

3.2 集計ロジック

件数パース(_parse_count)

稼働場所算出(_calc_location)

  1. 候補列(H〜N)のいずれかに この中に当てはまるものがない が入っていれば列N(自由記入)を採用
  2. そうでなければ H〜M の最初の非空値
  3. すべて空なら N

キャリア名寄せ

入力正規化後
Softbank / Ymobile / SBSoftbank
docomo / ドコモdocomo
KDDI / au / UQKDDI
その他非空その他

結合

3.3 キャリア列マッピング(成果報告_V3)

列indexキャリア列indexキャリア
5SB10POVO
6YM11UQ
7docomo12楽天
8au13その他
9ahamo

4. キャッシュ設計

項目仕様
保持形式pandas DataFrame(インメモリ)+ SQLite永続化
SQLiteパスcache.db(プロセス直下)
更新間隔300秒(5分)
起動フローSQLite復元 → 即サーブ → バックグラウンドでSheets再取得
手動更新POST /api/refresh
データ準備中503 Service Unavailable

5. API仕様

5.1 エンドポイント一覧

メソッドパス概要
GET/api/summaryKPI + 案件別 + 人別 + 日次 + コメント
GET/api/by_location案件別ランキング
GET/api/by_carrierキャリア別件数(ドーナツ用)
GET/api/calendar日次カレンダー
GET/api/filtersフィルター選択肢
GET/api/healthヘルスチェック
POST/api/refresh手動データ更新

5.2 共通クエリパラメータ

パラメータ説明
month2026-04年月(YYYY-MM)
name山田太郎氏名完全一致
location渋谷店稼働場所完全一致
careerSoftbankクライアント(Softbank / docomo / KDDI)
date2026-04-12単日絞り込み(summary/by_carrierのみ)

5.3 レスポンス例

GET /api/summary

{
  "total_count": 309,
  "total_working": 268,
  "avg_per_work": 1.15,
  "by_location": [{"name": "渋谷店", "件数": 42, "稼働数": 28}, ...],
  "by_person":   [{"name": "山田太郎", "件数": 15, "稼働数": 10}, ...],
  "daily":       [{"date": "2026-04-01", "件数": 12, "稼働数": 5}, ...],
  "comments":    [{"date": "2026-04-21", "name": "山田太郎", "comment": "..."}],
  "updated_at":  "2026-04-21T06:00:00+00:00"
}

GET /api/by_carrier

{
  "carriers": {"SB": 80, "YM": 12, "docomo": 60, "au": 50, "ahamo": 8,
               "POVO": 5, "UQ": 10, "楽天": 4, "その他": 2},
  "updated_at": "2026-04-21T06:00:00+00:00"
}

GET /api/filters

{
  "names":     ["山田太郎", "佐藤花子", ...],
  "locations": ["渋谷店", "新宿店", ...],
  "months":    ["2026-04", "2026-03", ...],
  "careers":   ["Softbank", "docomo", "KDDI"]
}

6. フロントエンド仕様

6.1 技術スタック

6.2 外部化ファイル構成(T-19 / 2026-04-23)

ファイル役割
styles/base.css変数・フォント・ヘッダー静的スタイル・btn-menu共通
styles/splash.css🔒 Splash演出(仕様クリティカル)
styles/dashboard.cssPCレイアウト・フィルタバー・オーバーレイ
styles/mobile.css@media(〜900/640/380px)
styles/account.cssマイページ専用スタイル
scripts/auth.js認証ガード・グローバル変数
scripts/splash.js🔒 Splash関数(SVG ID占有)
scripts/dashboard.jsダッシュボード本体・オーバーレイ開閉
scripts/main.jsupdateDashboard / init / manualRefresh
scripts/pull-refresh.jsモバイルPull-to-refresh
scripts/account.jsFirestore読み書き・プロフィール編集(ES Module)

6.3 主要画面構成

6.4 マイページ(account overlay)

6.3 Splash演出

6.4 禁止事項(先祖返り防止)

  1. setInterval(updateDashboard, ...) 自動更新の再導入禁止
  2. 初回ロード・手動更新で updateDashboard() を直接呼ばず runSplashSequence() 経由
  3. 最低5秒表示の短縮禁止
  4. ヘッダーロゴのアニメ化禁止(splash側がSVG IDを占有)
  5. phase-settle → phase-exit の切替順は remove('phase-settle')add('phase-exit')
  6. CSS記述順は .phase-exit .char.phase-settle .char より後ろ

6.5 モバイル対応

7. デプロイ

gcloud run deploy castbox-dashboard \
  --source . \
  --region asia-northeast1 \
  --allow-unauthenticated \
  --set-secrets "GOOGLE_SA_KEY_JSON=castbox-sa-key:latest" \
  --quiet

8. セキュリティ

8.1 SA鍵管理(T-21完了 2026-04-24)

8.2 Firebase認証

8.3 グローバル運用規則

9. タスク状況

完了

#タスク完了日
T-01Sheets API 接続2026-04-19
T-02location計算式 Python再現(100%一致)2026-04-19
T-03「X件」→数値変換2026-04-19
T-04成果×出発 結合ロジック2026-04-19
T-05Tableau突き合わせ(件数309 vs 311、稼働268完全一致)2026-04-19
T-06FastAPI + UIフルスタック構築2026-04-20
T-07UI Tableau配色刷新(白背景・オレンジアクセント)2026-04-20
T-08Cloud Run本番デプロイ(5分自動更新)2026-04-20
T-09即時更新ボタン(POST /api/refresh)2026-04-21
T-10UI Ver.2刷新(ロゴ・2段フィルター・レイアウト再構成)2026-04-21
T-11自動更新停止 + ヘッダーロゴ静的化2026-04-21
T-12Splashアニメーション実装(phase 3段・5秒保証)2026-04-21
T-13Comfortaa Variable 適用(ヘッダー+splash)2026-04-21
T-14ローカル開発環境整備(scripts/dev.cmd / DEV_SKIP_AUTH)2026-04-22
T-15UI を Cloud Run 経由配信に統一2026-04-22
T-16合計行バーをレベル別人数スタック化 + 折れ線ラベル期間集計 + 期間トグル改称2026-04-22
T-17Phase 2: 上位N%レベル化(Lv.4段階)+ 凡例固定 + ファネル + スマホ列幅最適化2026-04-23
T-18人リスト1列化(Lv.mini+レベル着色バー)+ 比較母数3か月固定 + グラフ切替2段トグル2026-04-23
T-19UI外部化: CSS 5ファイル + JS 6ファイル分割(index.html 2780→242行)2026-04-23
T-20ファネル母数3か月集計プール統一 + バー幅人数比例化2026-04-23
T-21SA鍵を Secret Manager へ移行(castbox-sa-key)2026-04-24
T-22アカウントページ新規作成(プロフィール編集・Google連携・Firestore読み書き)2026-04-24
T-23PWAアイコン統一(apple-touch-icon 180px / manifest / theme-color #37359A)2026-04-24
T-24マイページをページ遷移からオーバーレイ方式に変更(即時表示・ハンバーガー→X)2026-04-25
T-25フィルタボタン・Pull-to-refresh の overlay 連動 + ヘッダー高さ変数統一 --header-h2026-04-25

バックログ

#タスク優先度
U-01UIデザイン細部修正(Tableau差異詰め)
U-03カスタムドメイン移行(独自ドメイン)
U-04折れ線グラフ・ドーナツのツールチップ実装