Commit Graph

8 Commits

Author SHA1 Message Date
c428566c9a feat: fetcher 支援多 target union 掃描
- 新增 RADAR_TARGETS 環境變數('name:lat,lng;...')
- 未設時 fall back 到單點 RADAR_LAT/LNG(backward-compat)
- 主流程改為 loop 每個 target 呼叫 Function Server,以 (id, lat, lng, expire_time) dedupe 後 union
- 單點失敗不阻斷其他 target(try/except 包起來)
- debug 記錄每 target 原始筆數與完整 targets 清單
- 搭配 RADAR_ZOOM=15 解決 zoom 11 廣視角下單位面積密度過低的問題

本機驗證:5 target(台北/內湖/板橋/新竹/宜蘭)union 191 筆,
twpk 內湖南港街區 bounds(zoom 17 視角)從 0 筆變 2 筆。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:35:44 +08:00
ce9a944b45 docs: 更新 README 與 INFRA.md 記錄 generated_at、SWR 重試、updated badge
- README: /scan response 示例補 generated_at 欄位與說明
- INFRA.md:
  - 演進紀錄新增 3.12(前端空資料 auto-retry)、3.13(UI 顯示資料更新時間、後端加 generated_at)
  - 3.12 記錄 webhook pipeline 第一次真實使用(由前端 auto-retry 的 push 觸發)
  - follow-up 追加 pokemon-radar-api 後端自動部署的想法

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:21:02 +08:00
0264a35b8d feat: /scan response 多帶 generated_at,讓前端能顯示資料更新時間
從 Redis 快取內容讀取 fetcher 寫入時的時間戳(ISO8601 +08:00),原本
只放在 debug 區塊沒暴露。ScanResponse model 加對應 Optional[str] 欄位。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:15:38 +08:00
863036c293 docs: 新增 INFRA.md 記錄跨 repo 部署架構與 2026-04-20 演進
- 架構現況:前端 / API / Redis / webhook 自動部署 / NPM 反代 全景圖
- 機器與端點速查(42.108 / 42.104 / 42.124 / 外部 domain / git repos)
- 今天做了什麼的時序紀錄(含 bug / 踩坑 / 解法)
- 日常操作 cookbook(新增自動部署 repo、查 log、手動部署、API 端操作、NPM 建 proxy host)
- 已知限制與 follow-up(state.json 過期、token 歷史殘留、監控缺口等)
- README 首段加指引連到 INFRA.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:08:33 +08:00
2f7285437b feat: /scan 採 stale-while-revalidate,閒置時零呼叫
- /scan 永遠秒回當前 Redis 快取,若 TTL < STALE_THRESHOLD 或 key 不存在,用 daemon thread 呼叫 radar_fetcher.main() 非同步更新
- 以 Redis SET NX EX 當互斥 lock(pokemon:radar:fetching,TTL 180s)避免並發 fetcher
- 新增設定:STALE_THRESHOLD=120、FETCH_LOCK_KEY、FETCH_LOCK_TTL=180
- 原本需要 cron 定期跑 fetcher;現在 API 端會自動觸發,沒人打就不動

驗證:
- cold start /scan: 26ms 回空、同時搶 lock
- 背景 fetcher 跑完(~16s Function Server)後寫入 Redis 並釋放 lock
- 下一次 /scan 13ms 回 96 筆、TTL 299s
- 快取新鮮時重複打 /scan 不會重複觸發(refresh counter=1)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 09:30:53 +08:00
c95d6074d5 docs: 合併成單一 README(寫給一年後回來看的自己)
- 常用指令放最上面,.env 和 API 速查在中間,架構與故障排除在最下面
- QUICKSTART / SUMMARY 砍掉,WHY 融進架構段
- 移除「給新人入門」的 step-by-step 路徑

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 09:22:56 +08:00
da5a36e8ad security: 移除 hard-coded FUNCTION_TOKEN,改從 env 讀取
- pokemon_location_fetcher.py:DEFAULT_URL/TOKEN 改走 os.getenv,並補 load_dotenv() 讓 fetch_and_upload.sh 能從 .env 取值
- run_pokemon_radar_api.sh:POKER_* 改為可由環境覆蓋(實務上未被 API 使用,保留結構)
- pyproject.toml:補宣告 python-dotenv(專案已使用但原本未列)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 09:17:24 +08:00
f7ef105436 init: Redis-backed Pokémon 雷達 API
- radar_fetcher.py:呼叫 Function Server 抓 twpkinfo.com 資料後寫入 Redis (TTL 300s)
- pokemon_radar_api.py:FastAPI /scan,從 Redis 讀取並依 request 即時二次篩選;Redis 不可用時回 200 空結果,不再 500
- pokemon_location_fetcher.py:舊版 CLI,仍由 fetch_and_upload.sh 使用
- 文件:README (參考手冊)、QUICKSTART (操作指南)、SUMMARY (故事線)、CLAUDE.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 09:13:59 +08:00