From 5913654ae23101120de4df60d409324cc4c4162e Mon Sep 17 00:00:00 2001 From: Chaim Date: Fri, 12 Jun 2026 10:49:19 +0000 Subject: [PATCH] =?UTF-8?q?feat(approvals):=20=D7=A7=D7=98=D7=92=D7=95?= =?UTF-8?q?=D7=A8=D7=99=D7=99=D7=AA=20"=D7=97=D7=99=D7=9C=D7=95=D7=A5-?= =?UTF-8?q?=D7=94=D7=9C=D7=9B=D7=95=D7=AA=20=D7=AA=D7=A7=D7=95=D7=A2"=20?= =?UTF-8?q?=D7=91=D7=9E=D7=A8=D7=9B=D7=96-=D7=94=D7=90=D7=99=D7=A9=D7=95?= =?UTF-8?q?=D7=A8=D7=99=D7=9D=20(#133)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ה-wakeup המיידי ל-CEO לחילוץ-הלכות הוא best-effort; כשהוא נכשל (למשל churn-פריסה), הבקשה נשענת רק על הדריינר-הלילי והפריט נשאר 'pending' בלי שאיש רואה — עד ~16-18 שעות. מוסיף קטגוריה חמישית ל-api_chair_pending שמציפה case_law עם halacha_extraction_status= 'pending' שכבר עבר את חלון-הדריינר (requested_at < now()-6h), כך שכשל-שקט הופך לפריט-יו"ר גלוי במרכז-האישורים ("שלא יישכח"). שאילתת-מקור ישירה (תואם הדפוס), href ל-/precedents (שם כפתור request-halachot מעיר CEO = retry). אפס שינוי-frontend — דף-האישורים מרנדר categories גנרית (ApprovalCard לפי label/severity/count/href). gate-free (לוגיקה/נתון בלבד). הסף 6h תכוונן. Co-Authored-By: Claude Opus 4.8 --- web/app.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) 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,