diff --git a/web/app.py b/web/app.py index de1480b..2caa50e 100644 --- a/web/app.py +++ b/web/app.py @@ -5737,6 +5737,27 @@ async def api_chair_pending(): "href": f"/cases/{r['case_number']}"} for r in qa_rows[:5]], }) + # 5) חילוץ-הלכות תקוע — כשל-שקט (#133): ה-wakeup המיידי ל-CEO הוא + # best-effort; אם הוא נכשל, הבקשה נשענת רק על הדריינר-הלילי (23:00–05:00), + # והפריט נשאר 'pending' בלי שאיש רואה. מציפים רק כאלה שכבר עברו את חלון + # הדריינר (>6 שעות) — כך בקשת-בוקר שתנוקה הלילה לא מקפיצה אזעקת-שווא. + STUCK = "halacha_extraction_status='pending' AND " \ + "halacha_extraction_requested_at < now() - interval '6 hours'" + se_count = await conn.fetchval(f"SELECT count(*) FROM case_law WHERE {STUCK}") + se_oldest = await conn.fetchval( + f"SELECT min(halacha_extraction_requested_at) FROM case_law WHERE {STUCK}") + se_sample = await conn.fetch( + f"SELECT coalesce(case_number,'') AS cn, coalesce(case_name,'') AS name " + f"FROM case_law WHERE {STUCK} ORDER BY halacha_extraction_requested_at ASC LIMIT 5") + categories.append({ + "key": "stuck_halacha_extraction", "label": "חילוץ-הלכות תקוע", + "description": "החלטות סופיות שחילוץ-ההלכות שלהן לא נכנס לתור — להרצה מחדש מ-ספריית הפסיקה.", + "count": se_count, "severity": "high" if se_count else "ok", + "href": "/precedents", + "oldest_at": se_oldest.isoformat() if se_oldest else None, + "sample": [{"text": r["cn"], "source": r["name"]} for r in se_sample], + }) + total_pending = sum(c["count"] for c in categories) return { "total_pending": total_pending,