fix: missing-dep [add] button respects MOD_ID_ALIASES on build mismatch
When user is on B42 and a mod requires the B41 mod_id (e.g. truemusic_mixtape_megapack require=truemusic), the canonical wsid (2613146550, B41-only) is rightly filtered out by the build guard — but we were silently dropping the suggestion. Now we fall back to MOD_ID_ALIASES: truemusic → TrueMoozic, suggest wsid 3632610172. - _lookup_wsids_for_missing returns Dict[str, Tuple[wsid, suggested_mod_id]] - build_warnings unpacks tuple, label clarifies rename when alias used - adapters.build_response signature updated for new shape
This commit is contained in:
69
api/app.py
69
api/app.py
@@ -228,20 +228,29 @@ async def _lookup_wsids_for_missing(
|
||||
conn,
|
||||
mlos_warnings: Dict[str, Any],
|
||||
pz_build: Optional[str] = None,
|
||||
) -> Dict[str, str]:
|
||||
) -> Dict[str, Tuple[str, str]]:
|
||||
"""Resolve missing-requirement mod_ids to wsids via mod_parsed cache.
|
||||
|
||||
Returns {mod_id -> workshop_id} for any missing dep we've previously
|
||||
cached. Used to render an [add to list] action button next to the
|
||||
'missing' warning. Unknown deps just get no button.
|
||||
Returns {missing_mod_id -> (workshop_id, suggested_mod_id)} for any
|
||||
missing dep we've previously cached. `suggested_mod_id` matches the
|
||||
missing mod_id by default, but when the canonical wsid is wrong-build
|
||||
AND `MOD_ID_ALIASES` (adapters.py) has an alternative whose cached
|
||||
wsid IS build-correct, we redirect to the alias. Example: user on B42
|
||||
has `truemusic_mixtape_megapack` (require=truemusic). truemusic only
|
||||
exists as a B41 wsid; the alias `TrueMoozic` exists as a B42 wsid.
|
||||
Result: {"truemusic": ("3632610172", "TrueMoozic")} — frontend renders
|
||||
[add TrueMoozic] pointing at the correct build's wsid.
|
||||
|
||||
pz_build filters out wrong-build resolutions: if the user is on B42 and
|
||||
the only cached wsid for `dep` is tagged `Build 41` only, we DROP the
|
||||
suggestion. Adding it would just trigger a build-mismatch warning;
|
||||
worse, in cases like `TacHold requires modoptions` where the author's
|
||||
`require=` is over-declared, the suggestion misleads the user toward
|
||||
a B41 mod that doesn't actually need to be in the load order.
|
||||
the only cached wsid for `dep` is tagged `Build 41` only, the canonical
|
||||
suggestion is DROPPED (and the alias path may rescue it). Adding the
|
||||
wrong-build dep would just trigger a build-mismatch warning; worse, in
|
||||
cases like `TacHold requires modoptions` where `require=` is over-
|
||||
declared, the suggestion misleads the user toward a B41 mod that
|
||||
doesn't actually need to be in the load order.
|
||||
"""
|
||||
from adapters import MOD_ID_ALIASES
|
||||
|
||||
missing = mlos_warnings.get("missing_requirements") or {}
|
||||
if not missing:
|
||||
return {}
|
||||
@@ -252,6 +261,11 @@ async def _lookup_wsids_for_missing(
|
||||
wanted.add(d)
|
||||
if not wanted:
|
||||
return {}
|
||||
# Expand the fetch set with alias targets so we can resolve in one round.
|
||||
for dep in list(wanted):
|
||||
for alias_target in MOD_ID_ALIASES.get(dep, []):
|
||||
wanted.add(alias_target)
|
||||
|
||||
rows = await conn.fetch(
|
||||
"""
|
||||
SELECT DISTINCT ON (mp.mod_id) mp.mod_id, mp.workshop_id, wm.tags
|
||||
@@ -268,15 +282,36 @@ async def _lookup_wsids_for_missing(
|
||||
other_tag = "Build 41" if target_tag == "Build 42" else (
|
||||
"Build 42" if target_tag == "Build 41" else None
|
||||
)
|
||||
out: Dict[str, str] = {}
|
||||
|
||||
def _is_build_correct(tags: List[str]) -> bool:
|
||||
if not target_tag or not other_tag:
|
||||
return True
|
||||
return not (other_tag in tags and target_tag not in tags)
|
||||
|
||||
# candidates: mod_id -> (wsid, build_correct)
|
||||
candidates: Dict[str, Tuple[str, bool]] = {}
|
||||
for r in rows:
|
||||
if target_tag and other_tag:
|
||||
tags = list(r["tags"] or [])
|
||||
if other_tag in tags and target_tag not in tags:
|
||||
# Wrong-build only — adding it would just trigger a
|
||||
# build-mismatch. Skip the suggestion.
|
||||
continue
|
||||
out[r["mod_id"]] = r["workshop_id"]
|
||||
tags = list(r["tags"] or [])
|
||||
candidates[r["mod_id"]] = (r["workshop_id"], _is_build_correct(tags))
|
||||
|
||||
deps_seen: set = set()
|
||||
for deps in missing.values():
|
||||
for d in deps:
|
||||
if d:
|
||||
deps_seen.add(d)
|
||||
|
||||
out: Dict[str, Tuple[str, str]] = {}
|
||||
for dep in deps_seen:
|
||||
cand = candidates.get(dep)
|
||||
if cand and cand[1]:
|
||||
out[dep] = (cand[0], dep)
|
||||
continue
|
||||
# Canonical missing or wrong-build; try aliases in declaration order.
|
||||
for alias_target in MOD_ID_ALIASES.get(dep, []):
|
||||
alt = candidates.get(alias_target)
|
||||
if alt and alt[1]:
|
||||
out[dep] = (alt[0], alias_target)
|
||||
break
|
||||
return out
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user