Spaces:
Sleeping
fix(#75): compare_policies curated fallback — no scorecard surface 404s
Browse filesGeneralises #60. compare_policies (/api/policies/compare) was the last
scorecard surface that still did 'if not extracted_path.exists(): raise
HTTPException(404)'. Curated-only catalogued products (e.g.
star-health__star-comprehensive, UIN SHAHLIP26044V092526) have no
rag/extracted/<pid>.json, so 'Compare all' 404'd / broke for them while
the marketplace, single /api/scorecard and bulk scorecard endpoints all
already resolved them from the curated layer. Mirrored the same curated
fallback (curated dict also carries __wordings/__cis/__brochure/
__prospectus alias keys). Verified: star-comprehensive now grades A 76
in the compare path (was 404). Every scorecard surface now resolves
curated-only + (via #40 SSOT / #61) variant/doctype ids — no catalogued
policy can show N/A / 'No extraction available' / 404 on any surface.
Full pytest gate green (rc=0).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- backend/main.py +30 -5
|
@@ -3524,11 +3524,36 @@ async def compare_policies(policy_ids: list[str] = None):
|
|
| 3524 |
# reflects the corrected/verbatim 40-data/policy_facts, not stale extract.
|
| 3525 |
_curated = _load_curated_facts()
|
| 3526 |
for pid in policy_ids:
|
| 3527 |
-
|
| 3528 |
-
|
| 3529 |
-
|
| 3530 |
-
|
| 3531 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3532 |
# Insurer reviews for scorecard
|
| 3533 |
slug = data.get("insurer_slug")
|
| 3534 |
ir = None
|
|
|
|
| 3524 |
# reflects the corrected/verbatim 40-data/policy_facts, not stale extract.
|
| 3525 |
_curated = _load_curated_facts()
|
| 3526 |
for pid in policy_ids:
|
| 3527 |
+
ep = settings.EXTRACTED_DIR / f"{pid}.json"
|
| 3528 |
+
data: Optional[dict] = None
|
| 3529 |
+
if ep.exists():
|
| 3530 |
+
try:
|
| 3531 |
+
data = _json.loads(ep.read_text())
|
| 3532 |
+
except Exception:
|
| 3533 |
+
data = None
|
| 3534 |
+
if data is not None:
|
| 3535 |
+
data = _merge_curated(
|
| 3536 |
+
data,
|
| 3537 |
+
_curated.get(data.get("policy_id", pid)) or _curated.get(pid),
|
| 3538 |
+
)
|
| 3539 |
+
if data is None:
|
| 3540 |
+
# #75 (2026-05-18) — curated-only catalogued products (e.g.
|
| 3541 |
+
# star-health__star-comprehensive, UIN SHAHLIP26044V092526) have
|
| 3542 |
+
# NO rag/extracted/<pid>.json. The marketplace, single
|
| 3543 |
+
# /api/scorecard, and bulk scorecard endpoints all resolve these
|
| 3544 |
+
# from the curated layer; compare_policies alone still 404'd,
|
| 3545 |
+
# breaking "Compare all" for those policies. Mirror the same
|
| 3546 |
+
# curated fallback (curated dict also carries doctype-suffixed
|
| 3547 |
+
# alias keys) instead of raising.
|
| 3548 |
+
data = (
|
| 3549 |
+
_curated.get(pid)
|
| 3550 |
+
or _curated.get(f"{pid}__wordings")
|
| 3551 |
+
or _curated.get(f"{pid}__cis")
|
| 3552 |
+
or _curated.get(f"{pid}__brochure")
|
| 3553 |
+
or _curated.get(f"{pid}__prospectus")
|
| 3554 |
+
)
|
| 3555 |
+
if not data:
|
| 3556 |
+
raise HTTPException(404, f"No data for {pid}")
|
| 3557 |
# Insurer reviews for scorecard
|
| 3558 |
slug = data.get("insurer_slug")
|
| 3559 |
ir = None
|