3 Commits

Author SHA1 Message Date
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
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
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