系統架構
系統如何構建
CPBL 官方 API 為資料源的 Python ETL 資料管線、Cloudflare D1 at edge、Hono-on-Workers 提供 15 個 API、Next.js 16 SSG 前端、以及自建 MCP server + Workers AI bge-m3 embedding 搜尋。 全 CF 邊緣堆疊、全自動 CI/CD。
(舊版 v1 有整合 Rebas Open Data,v2 monorepo 評估重疊 85% 後 scope 收斂至 CPBL 官方為單一來源)
系統架構
從原始資料來源到即時儀表板的端對端資料流。
CPBL Public API
POST /getlive
POST /getlive
ETL Pipeline
Python / scripts/
→Python / scripts/
Cloudflare D1
SQLite at edge
→SQLite at edge
Hono on Workers
15 endpoints
→15 endpoints
Next.js 16 SSG
static export
→static export
CF Pages
Global edge CDN
Global edge CDN
GitHub Actions 每日 06:00 (台灣) 自動執行完整管線
ETL 資料管線詳解
CPBL 官方 API 單一來源提取、轉換、冪等載入 SQLite。
資料擷取
CPBL 官方 APIPOST /box/getlive + /box/getboxsum。Box score、逐球 play-by-play、LOB。
歷史整合(v1 archived)舊 repo 有 Rebas Open Data loader(重疊 85%、v2 scope 收斂)
Game 鍵(game_sno, year) + (date, home, away) 自然鍵備援
資料品質與對應
Schema drift testpytest 每天驗上游格式,不符擋 deploy
冪等INSERT OR REPLACE + game_sno + player_name 複合鍵
磁碟快取原始 JSON 快取在 data/cpbl_raw/
速率限制(CPBL API)
2s
請求間隔
30/min
硬限制上限
管線執行順序
- 1
seed_cpbl.py爬 CPBL 官方 API、解析 + 快取 raw JSON - 2
test_schema_consistency.pySchema drift 守門員,不通過擋 deploy - 3
calc_park_factors.py / calc_wrc_plus.py / compute_radar.py從 SQLite 計算進階統計 - 4
export_static.py產靜態 JSON → apps/cpbl/public/api/ - 5
sync_to_d1.pySQLite → D1 冪等 INSERT OR REPLACE
資料庫結構
SQLite WAL 模式。8 個表、15+ 個索引、分析快取層。
| 表 | 列數 | 關鍵欄位 | 說明 |
|---|---|---|---|
| games | 377 | game_id, game_date, home_team, away_team, season, kind_code | 所有表的主連接鍵。日期、主隊、客隊的複合唯一約束。 |
| plate_appearances | 28,502 | pa_id, game_id, batter_id, pitcher_id, inning, outs, bases, result | 核心事件表。包含 RE24 的槓桿背景(局數、出局數、壘包狀態)。 |
| pitch_events | 111,983 | event_id, pa_id, pitch_seq, pitch_type, result, balls, strikes | 最大的表。用於計數拆分和疲勞曲線分析。 |
| batter_box | 8,400 | game_id, player_id, ab, h, bb, hbp, hr, rbi, lob | 每位打者每場比賽的成績單。LOB 欄位來自 CPBL API 補充。 |
| pitcher_box | 3,217 | game_id, player_id, ip, h, bb, k, er, pitch_count, lob, left_behind_lob | LOB% 分子/分母來自此處。left_behind_lob 來自 CPBL API。 |
| analysis_cache | — | cache_key, value_json, computed_at, ttl_seconds | 鍵值存儲。昂貴的彙總在 ETL 後快取,新資料載入時無效化。 |
| player_mapping | — | canonical_name, cpbl_name_zh, team_code, season | 跨來源球員名稱對齊表(v1 用於 Rebas ID 串接,v2 保留為未來多源整合 scaffold)。 |
| run_expectancy_matrix | 24 | outs, bases_state, expected_runs, season, sample_size | 24 個壘包出局狀態。用於 RE24 + 槓桿指數。 |
Entity-Relationship Diagram
核心資料流:games → plate_appearances → pitch_events(逐球事件鏈)。
開發者體驗基建
除了前台 dashboard,另有一套內部工具鏈:自建 MCP server 讓 Claude 直接查資料庫、 語義搜尋系統讓歷史決策可被快速找回、Worker 本身就是 AI 推論的入口。
murs-data MCP Server
本地 stdio MCP server(TypeScript)。4 個 parametric tool 一次覆蓋 5 個資料源:
d1_query(db, sql)— read-only SELECT across cpbl / fantasy / polymarket / mursfoto D1d1_schema(db, table?)— list tables / columnsyaoye_sheets_read(key, range)— Google Sheets API v4memory_search(query)— 語義搜尋 91 個 memory 檔
安全:`assertReadOnly()` 拒絕 INSERT/UPDATE/DELETE/DROP;拒絕 multi-statement;結果 cap 500 rows。
Workers AI bge-m3 embedding
Hono API 的
/api/ai/embed endpoint 用 env.AI.run('@cf/baai/bge-m3') 直接在 Worker 內跑推論。- 1024-dim 多語 embedding(bge-m3 中文支援優)
- 免 API key(Worker binding)
- Free tier 10,000 neurons/day,91 檔 embed 約 100 neurons
- Bearer auth 保護額度
替代了初版用 Google Gemini embedding 的依賴,全 stack 留在 Cloudflare 邊緣。
語義搜尋記憶系統
`~/.claude/projects/*/memory/` 91 個踩坑記錄、決策文件、session archive, 全部透過 bge-m3 向量化存本地 SQLite JSON index。
- 問「CF 部署踩坑」→ 找到 feedback_cloudflare_pitfalls.md(sim 0.626)
- cosine similarity 線性掃描,91 檔 × 1024 維 < 10ms
- Weekly launchd audit 自動 rebuild index
效果:從「我記得有寫過某某」進化到「語義相關性」查找,不用翻目錄。
CI/CD 流程
兩個 GitHub Actions 工作流:推送觸發品質閘道 + 每日自動資料更新。
推送觸發觸發:推送、拉取請求
▶
推送 / PR
✎
檢查 (ruff)
✓
測試 (pytest)
📊
涵蓋報告
🚀
部署到 CF
每日 Cron排程:0 22 * * * (UTC)
🕐
UTC 22:00
💾
植入資料
📄
匯出 JSON
🔄
Git 推送
⚡
自動部署
技術決策
架構決策記錄 — 關鍵技術選擇背後的理由。
ADR-001
儲存SQLite 優於 PostgreSQL
+ 單一寫入 ETL 表示沒有並發寫入衝突
+ 零配置、零營運開銷
+ 整個資料庫是單一可移植檔案
+ 讀取密集工作負載適合 WAL 模式
! 無並發寫入、1 TB 實際大小限制
ADR-002
代管靜態 JSON 匯出
+ Cloudflare Pages 免費層 — 每月 $0
+ 無需伺服器執行時;消除冷啟動
+ 透過 300+ 個 PoPs 的即時全球分佈
+ 資料每日透過 cron 更新
! 無實時查詢;僅預計算彙總
ADR-003
視覺化ECharts 優於 D3 / Plotly
+ Canvas 渲染比 SVG 有更好的行動效能
+ ~750 KB vs Plotly ~3.5 MB
+ 內建互動零程式碼
+ 現成深色主題支援
! 對於完全自訂視覺不如 D3 靈活
ADR-004
後端Python 優於 Node.js
+ pandas / numpy 資料處理
+ 更豐富的統計函式庫
+ FastAPI + SQLAlchemy 2.0 非同步效能
+ 未來 ML 功能已在生態系中
! Python GIL 限制 CPU 綁定並發