feat: תיקון-ציטוט בדלי-החילוץ + קישור-לתור מדף-פרט (#133 follow-ups)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 6s

אושר ב-Claude Design (כרטיס 20-halacha-followups).

א׳ תיקון-חילוץ אמיתי ל-quote_unverified:
- `update_halacha` מקבל `supporting_quote`; בעדכונו מריץ `_verify_quote`
  הקיים מול `case_law.full_text` השמור (דטרמיניסטי — בלי OCR/LLM מחדש,
  feedback_no_reocr_retrofit) ומסנכרן `quote_verified` + מוסיף/מסיר את
  הדגל `quote_unverified`. יו"ר שמדביק את הנוסח הנכון מהמקור → הדגל נמחק
  → ההלכה עוזבת את דלי-החילוץ. `HalachaUpdateRequest`+handler מעבירים את
  השדה; `HalachaPatch` + מצב-העריכה ב-HalachaCard כוללים textarea-ציטוט
  (נשלח רק כששונה) + hint.

ב׳ דף-פרט פסיקה — ביטול כפילות-המשטח:
- הלכה pending ב-`ExtractedHalachotSection` מציגה קישור "עבור לתור הלכות"
  במקום כפתורי אשר/דחה כפולים (שער-אישור יחיד, INV-IA/G10).
- `/precedents` Tabs הפך נשלט וקורא `?tab=review` (post-mount, בלי
  hydration-mismatch) כדי שהקישור ינחת על טאב-התור.

display-only ל-G10 (האימות מסנכרן מטא-איכות, לא review_status). ולידציה:
py_compile + tsc + eslint נקיים.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 09:03:29 +00:00
parent 99fe16a43d
commit 2962538c09
6 changed files with 96 additions and 25 deletions

View File

@@ -1,5 +1,6 @@
"use client";
import { useEffect, useState } from "react";
import Link from "next/link";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { AppShell } from "@/components/app-shell";
@@ -52,10 +53,22 @@ function IncomingPill() {
return <CountPill n={data?.by_status?.open ?? 0} tone="info" />;
}
const PRECEDENT_TABS = new Set(["library", "search", "review", "incoming", "stats"]);
export default function PrecedentsPage() {
// Controlled so a deep link like /precedents?tab=review (e.g. from a pending
// halacha on a precedent-detail page, #133) lands on the right tab. Read after
// mount to avoid an SSR/CSR mismatch and the useSearchParams Suspense rule.
const [tab, setTab] = useState("library");
useEffect(() => {
// read post-mount (not lazy init) to avoid an SSR/CSR hydration mismatch
const t = new URLSearchParams(window.location.search).get("tab");
// eslint-disable-next-line react-hooks/set-state-in-effect
if (t && PRECEDENT_TABS.has(t)) setTab(t);
}, []);
return (
<AppShell>
<Tabs defaultValue="library" dir="rtl">
<Tabs value={tab} onValueChange={setTab} dir="rtl">
<section className="space-y-6">
<header className="space-y-3">
<nav className="text-[0.78rem] text-ink-muted">