fix: resolve each team independently to prevent squadron_long order inversion

When one team has a dash-tag (e.g. -DSPLA-) and the opponent has a normal
tag (e.g. ALUN2), batching both into resolve_clans caused the short-name
pass to place the normal team first in results and the tag pass to append
the dash-tagged team second — inverting the mapping vs. the teams array.
Each team's players were then looked up against the wrong squadron's API,
yielding curr=0 for everyone and diffs=0 on the scoreboard.

Fix: resolve each team concurrently and independently so results are always
index-aligned with the teams list regardless of which resolution path fires.
Also propagates squadron_short to the scoreboard renderer so display names
are clean (DSPLA not -DSPLA-).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
deploy
2026-05-29 17:04:40 +00:00
parent cc4bc14193
commit 606e174a97
2 changed files with 20 additions and 8 deletions
+19 -7
View File
@@ -1633,13 +1633,25 @@ async def build_scoreboard_context(
"""
teams: List[Dict[str, Any]] = list((replay_data.get("teams") or [])[:2])
squads: List[str] = [str(team["squadron"]) for team in teams if team.get("squadron")]
squads_tagged: List[str] = [str(team["squadron_tagged"]) for team in teams if team.get("squadron_tagged")]
resolved = await resolve_clans(shorts=squads, tags=squads_tagged)
long_clans = [c["long_name"] for c in resolved]
for team, long_name in zip(teams, long_clans):
if team and long_name:
team["squadron_long"] = long_name
# Resolve each team independently and concurrently so the result is always
# index-aligned with the teams list. Batching both teams into one
# resolve_clans call can invert the order when one team resolves via the
# short-name pass and the other falls through to the tag pass.
async def _resolve_team(team: dict) -> Optional[dict]:
sq = str(team.get("squadron") or "")
tag = str(team.get("squadron_tagged") or "")
if not sq and not tag:
return None
results = await resolve_clans(shorts=[sq] if sq else [], tags=[tag] if tag else [])
return results[0] if results else None
resolved_teams = await asyncio.gather(*[_resolve_team(t) for t in teams])
for team, result in zip(teams, resolved_teams):
if team and result:
if result.get("long_name") and result["long_name"] != "<unresolved>":
team["squadron_long"] = result["long_name"]
if result.get("short_name"):
team["squadron_short"] = result["short_name"]
home_tag: Optional[str] = (teams[0] or {}).get("squadron") if len(teams) > 0 else None
away_tag: Optional[str] = (teams[1] or {}).get("squadron") if len(teams) > 1 else None
+1 -1
View File
@@ -458,7 +458,7 @@ def _create_scoreboard_sync(match_details,
# --- 1) Squadron header & points ---
squadron_short = team_data.get("squadron", "Unknown")
squadron_short = team_data.get("squadron_short") or team_data.get("squadron", "Unknown")
squadron_long = team_data.get("squadron_long", "Unknown")
matched_diff_source = None
squad_diffs = None