fix(combat): handle JSON string from DB (double-encoded stats_data)
The combat_stats DB column stores stats_data as JSON, but SQLAlchemy returns it as a string (not a parsed dict). This caused: - _combat_lifetime_cache loaded a string, merge failed silently - API endpoints returned string instead of object for lifetime - Frontend saw lifetime as a string, couldn't read .monsters Fix: parse JSON string with json.loads() wherever stats_data is read from DB — in the lifetime cache loader, single-character endpoint, and all-characters endpoint. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0a0fdc5b3d
commit
17f4d4b2aa
1 changed files with 26 additions and 3 deletions
29
main.py
29
main.py
|
|
@ -1752,10 +1752,17 @@ async def get_combat_stats(character_name: str):
|
|||
)
|
||||
if not row:
|
||||
return {"character_name": character_name, "session": None, "lifetime": None}
|
||||
sd = row["stats_data"]
|
||||
if isinstance(sd, str):
|
||||
import json as _json
|
||||
try:
|
||||
sd = _json.loads(sd)
|
||||
except Exception:
|
||||
sd = None
|
||||
return {
|
||||
"character_name": character_name,
|
||||
"session": None,
|
||||
"lifetime": row["stats_data"],
|
||||
"lifetime": sd,
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1776,10 +1783,15 @@ async def get_all_combat_stats():
|
|||
rows = await database.fetch_all("SELECT character_name, stats_data FROM combat_stats")
|
||||
for r in rows:
|
||||
if r["character_name"] not in seen:
|
||||
sd = r["stats_data"]
|
||||
if isinstance(sd, str):
|
||||
import json as _json
|
||||
try: sd = _json.loads(sd)
|
||||
except Exception: sd = None
|
||||
results.append({
|
||||
"character_name": r["character_name"],
|
||||
"session": None,
|
||||
"lifetime": r["stats_data"],
|
||||
"lifetime": sd,
|
||||
})
|
||||
results.sort(key=lambda x: x["character_name"])
|
||||
return {"stats": results}
|
||||
|
|
@ -3028,7 +3040,18 @@ async def ws_receive_snapshots(
|
|||
"SELECT stats_data FROM combat_stats WHERE character_name = :n",
|
||||
{"n": char},
|
||||
)
|
||||
_combat_lifetime_cache[char] = row["stats_data"] if row else {}
|
||||
if row and row["stats_data"]:
|
||||
sd = row["stats_data"]
|
||||
# DB may return JSON as string — parse if needed
|
||||
if isinstance(sd, str):
|
||||
import json as _json
|
||||
try:
|
||||
sd = _json.loads(sd)
|
||||
except Exception:
|
||||
sd = {}
|
||||
_combat_lifetime_cache[char] = sd
|
||||
else:
|
||||
_combat_lifetime_cache[char] = {}
|
||||
|
||||
lifetime = _combat_merge_into_lifetime(
|
||||
_combat_lifetime_cache[char], delta
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue