diff --git a/web/app.py b/web/app.py index 66d5896..9c7e062 100644 --- a/web/app.py +++ b/web/app.py @@ -5253,11 +5253,21 @@ async def precedent_library_upload( case_law_id = result.get("case_law_id") if isinstance(result, dict) else None if case_law_id: try: - await pc_wake_for_precedent_extraction( + wake = await pc_wake_for_precedent_extraction( case_law_id=case_law_id, citation=citation.strip(), practice_area=practice_area, ) + # The wake helper returns {ok: False, ...} on a skipped / + # failed wakeup WITHOUT raising — previously that path was + # silently dropped and the precedent sat at 'pending' + # forever. Surface it as a WARNING with the reason. + if not wake.get("ok"): + logger.warning( + "precedent %s: extraction wakeup did not queue (%s) — " + "halachot stay pending until precedent_process_pending runs", + case_law_id, wake.get("skipped") or wake.get("error"), + ) except Exception: logger.exception("precedent-extraction wakeup failed (non-fatal)") except Exception as e: @@ -5524,7 +5534,7 @@ async def internal_decisions_upload( async def _run(): try: - await int_decisions_service.ingest_internal_decision( + result = await int_decisions_service.ingest_internal_decision( case_number=case_number.strip(), case_name=case_name.strip(), court=court.strip(), @@ -5538,7 +5548,40 @@ async def internal_decisions_upload( summary=summary.strip(), file_path=staged, ) - await _progress.set(task_id, {"status": "completed", "percent": 100}) + # Auto-trigger halacha+metadata extraction via the CEO. The + # extractor needs the local `claude` CLI (absent in this + # container), so the only automatic path is a Paperclip wakeup. + # Without this, committee decisions stay stuck forever at + # halacha_extraction_status='pending' (the other two upload paths + # — precedent_library_upload and missing-precedent — already do + # this; this path was missing it). + case_law_id = result.get("case_law_id") if isinstance(result, dict) else None + extraction_queued = True + if case_law_id: + # Route to the correct company CEO. _get_company_id keys off + # practice_area; committee case numbers are reliably prefixed + # (1xxx→רישוי, 8xxx→היטל, 9xxx→פיצויים), so derive a routing + # tag from the prefix when practice_area is empty — otherwise + # an 8xxx case wrongly routes to the licensing CEO. + routing_pa = practice_area or { + "1": "rishuy_uvniya", "8": "betterment_levy", "9": "compensation_197", + }.get(case_number.strip()[:1], "") + wake = await pc_wake_for_precedent_extraction( + case_law_id=case_law_id, + citation=case_number.strip(), + practice_area=routing_pa, + ) + if not wake.get("ok"): + extraction_queued = False + logger.warning( + "internal-decision %s: extraction wakeup did not queue (%s) — " + "halachot stay pending until precedent_process_pending runs", + case_number, wake.get("skipped") or wake.get("error"), + ) + await _progress.set(task_id, { + "status": "completed", "percent": 100, + "extraction_queued": extraction_queued, + }) except Exception as e: logger.exception("internal-decisions upload failed") await _progress.set(task_id, {"status": "failed", "error": str(e)}) @@ -6023,11 +6066,20 @@ async def missing_precedent_upload( # file's text. Best-effort: mirrors the precedent_library_upload # contract — failures are logged, not surfaced. try: - await pc_wake_for_precedent_extraction( + routing_pa = practice_area or { + "1": "rishuy_uvniya", "8": "betterment_levy", "9": "compensation_197", + }.get(committee_case_number.strip()[:1], "") if is_committee else practice_area + wake = await pc_wake_for_precedent_extraction( case_law_id=case_law_id, citation=citation, - practice_area=practice_area, + practice_area=routing_pa, ) + if not wake.get("ok"): + logger.warning( + "missing-precedent %s: extraction wakeup did not queue (%s) — " + "halachot stay pending until precedent_process_pending runs", + case_law_id, wake.get("skipped") or wake.get("error"), + ) except Exception: logger.exception( "missing-precedent: precedent-extraction wakeup failed (non-fatal)"