Ship Steam login, D1 player sync, and cached「我」dashboard.

Players get a fast TTL-backed homepage (local profile / Cloudflare D1) with dense UI polish; login unlocks /home without blocking on every OpenDota refresh.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
voson
2026-08-01 01:24:30 +08:00
co-authored by Cursor
parent 4a61aeeb26
commit f5b7011c45
65 changed files with 7304 additions and 552 deletions
+50
View File
@@ -0,0 +1,50 @@
"""TTL helpers for player homepage cache-first serving."""
from __future__ import annotations
import sys
import unittest
from datetime import datetime, timedelta, timezone
from pathlib import Path
PC = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(PC))
from player_pages import ( # noqa: E402
profile_fetched_at,
profile_has_payload,
profile_is_stale,
)
def _iso_ago(seconds: int) -> str:
t = datetime.now(timezone.utc) - timedelta(seconds=seconds)
return t.strftime("%Y-%m-%dT%H:%M:%SZ")
class PlayerPagesCacheTests(unittest.TestCase):
def test_has_payload_career(self):
self.assertTrue(profile_has_payload({"career": {"games": 10}}))
self.assertFalse(profile_has_payload({"career": {"games": 0}}))
def test_has_payload_recent(self):
self.assertTrue(profile_has_payload({"recent": [{"match_id": 1}]}))
self.assertFalse(profile_has_payload({"recent": []}))
def test_fetched_at_prefers_availability(self):
p = {
"availability": {"fetched_at": "2026-01-01T00:00:00Z"},
"enriched_at": "2026-01-02T00:00:00Z",
}
self.assertEqual(profile_fetched_at(p), "2026-01-01T00:00:00Z")
def test_stale_ttl(self):
fresh = {"enriched_at": _iso_ago(60)}
old = {"enriched_at": _iso_ago(1200)}
self.assertFalse(profile_is_stale(fresh, 600))
self.assertTrue(profile_is_stale(old, 600))
self.assertTrue(profile_is_stale({}, 600))
if __name__ == "__main__":
unittest.main()
+95
View File
@@ -0,0 +1,95 @@
"""Unit tests for player homepage aggregates."""
from __future__ import annotations
import sys
import unittest
from pathlib import Path
PC = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(PC))
from player_stats import ( # noqa: E402
aggregate_from_rows,
career_from_opendota,
kda,
merge_availability,
should_keep_old_career,
top_heroes_from_opendota,
winrate,
)
class PlayerStatsTests(unittest.TestCase):
def test_kda_zero_deaths(self):
self.assertEqual(kda(5, 0, 5), 10.0)
def test_winrate_empty(self):
self.assertIsNone(winrate(0, 0))
self.assertEqual(winrate(1, 1), 50.0)
def test_aggregate_recent(self):
rows = [
{"won": True, "kills": 10, "deaths": 2, "assists": 8, "gpm": 500, "hero_id": 1},
{"won": False, "kills": 0, "deaths": 10, "assists": 2, "gpm": 300, "hero_id": 2},
]
out = aggregate_from_rows(rows, limit=20)
self.assertEqual(out["sample"], 2)
self.assertEqual(out["wins"], 1)
self.assertEqual(out["winrate"], 50.0)
self.assertEqual(out["avg_gpm"], 400)
def test_career_empty_private(self):
self.assertIsNone(career_from_opendota({"win": 0, "lose": 0}, []))
def test_career_populated(self):
career = career_from_opendota(
{"win": 10, "lose": 10},
[
{"field": "kills", "n": 20, "sum": 100},
{"field": "deaths", "n": 20, "sum": 50},
{"field": "assists", "n": 20, "sum": 150},
{"field": "gold_per_min", "n": 20, "sum": 8000},
],
)
self.assertEqual(career["games"], 20)
self.assertEqual(career["kda"], 5.0)
self.assertEqual(career["avg_gpm"], 400)
def test_keep_old_career_on_empty(self):
old = {"games": 100, "wins": 50, "losses": 50}
self.assertEqual(should_keep_old_career(old, None), old)
new = {"games": 101, "wins": 51, "losses": 50}
self.assertEqual(should_keep_old_career(old, new), new)
def test_top_heroes(self):
heroes = top_heroes_from_opendota(
[
{"hero_id": 1, "games": 5, "win": 3, "last_played": 100},
{"hero_id": 2, "games": 10, "win": 4, "last_played": 90},
],
hero_lookup={1: {"key": "antimage", "name_loc": "敌法"}, 2: {"key": "axe", "name_loc": "斧王"}},
limit=1,
)
self.assertEqual(len(heroes), 1)
self.assertEqual(heroes[0]["hero_key"], "axe")
def test_availability_syncing(self):
avail = merge_availability(
opendota_recent_n=0,
career=None,
steam_history_status=1,
fetched_at="t",
)
self.assertEqual(avail["status"], "syncing")
private = merge_availability(
opendota_recent_n=0,
career=None,
steam_history_status=15,
fetched_at="t",
)
self.assertEqual(private["status"], "private")
if __name__ == "__main__":
unittest.main()