feat(fifa17): own club/stats/{year,consumables} in Rust (Core-accurate)

Migrate the MY CLUB stat set from the Python proxy to a Rust handler computing
Core-accurate counts: player tiers + rare from the collection, staff/consumable
families from catalog kind+subtype, per-nation buckets via the reverse entity
resolver. Faithful port of fut_club_stats.py (VOCAB + global_counts +
context_rows). Unlike the oracle (stale profile + synthetic consumable shelf),
this reflects the real imported content (incl. the content-gap consumables/staff).
Fail-closed 503 on Core error. club/stats/country|league|team sub-screens remain
Python (documented). Adds adapter club_stats module (5 tests), host handler +
classify arm + resolver subtype_of/rareflag_of, ownership + integration tests;
reachability tool splits club/stats global(migrated) vs context(residual).
This commit is contained in:
funman300
2026-08-15 17:56:37 +00:00
parent 979e71fbea
commit 71fcf5e251
5 changed files with 477 additions and 8 deletions
+7 -2
View File
@@ -41,13 +41,14 @@ MIGRATED_NON_ECONOMY = {
"match/reset",
"phishing", # phishing/{trusteddevice,question,validate}
"hub",
"club/stats/global", # year/consumables/staff
}
# Documented residual Python-owned non-economy domains (expected > 0 until
# migrated). Keep in sync with docs/PRODUCTION_AUTHORITY_MATRIX.md.
RESIDUAL_PYTHON = {
"openfut/account/sync",
"club/stats", # year/consumables still Python; club/stats/staff is Rust
"club/stats/context", # country/league/team nation-bucket sub-screens
"clientdata/userHubData",
}
@@ -62,8 +63,12 @@ def python_domain(path: str) -> str:
tail = m.group(1) if m else p.lstrip("/")
if tail.startswith("phishing/"):
return "phishing"
if tail.startswith("club/stats/country") or tail.startswith(
"club/stats/league"
) or tail.startswith("club/stats/team"):
return "club/stats/context"
if tail.startswith("club/stats"):
return "club/stats"
return "club/stats/global"
if tail.startswith("clientdata/"):
return "clientdata/userHubData"
return tail