"use client"; /** * "אימות פסיקה" tab (X11 Phase 2 / #154) — per legal argument, the in-corpus * supporting precedents with the cumulative authority signal (cited_by), a verify * gate + chair note, and per-issue radar (unlinked digests). The writer cites only * verified quotes (INV-AH); the digest is never cited (INV-DIG1, radar only). */ import { useState } from "react"; import { toast } from "sonner"; import { Card, CardContent } from "@/components/ui/card"; import { Skeleton } from "@/components/ui/skeleton"; import { useCitationVerification, useVerifyCitation, type ArgumentBlock, type SupportingPrecedent, type RadarLead, } from "@/lib/api/citation-verification"; const PRIORITY_LABEL: Record = { threshold: "סף", substantive: "מהותית", procedural: "פרוצדורלית", relief: "סעד", }; const RADAR_LABEL: Record = { new_lead: "ליד חדש", gap_open: "בתור-חסרים", fetched: "נמשך", available_link: "בקורפוס — לקשר", }; export function CitationVerificationPanel({ caseNumber }: { caseNumber: string }) { const { data, isPending, isError } = useCitationVerification(caseNumber); const verify = useVerifyCitation(caseNumber); const [notes, setNotes] = useState>({}); if (isPending) { return ( ); } if (isError || !data || data.status !== "ok") { return ( לא ניתן לטעון את אימות-הפסיקה כעת. ); } if (!data.arguments.length) { return (

אין עדיין סוגיות מזוקקות לתיק

הרץ את ניתוח-הטענות (aggregate) כדי שהמערכת תזהה סוגיות ותתאים להן פסיקה.

); } function runVerify(a: ArgumentBlock, s: SupportingPrecedent, verified: boolean) { verify.mutate( { argument_id: a.argument_id, case_law_id: s.case_law_id, quote: s.quote, citation: s.case_number || s.case_name, chair_note: notes[s.case_law_id] ?? s.chair_note, verified, attached_id: s.attached_id ?? "", }, { onSuccess: () => toast.success(verified ? "הציטוט אומת" : "סומן כלא-רלוונטי"), onError: (e: Error) => toast.error(`שגיאה: ${e.message}`), }, ); } function saveNote(a: ArgumentBlock, s: SupportingPrecedent) { const note = notes[s.case_law_id]; if (note === undefined || note === s.chair_note) return; verify.mutate( { argument_id: a.argument_id, case_law_id: s.case_law_id, quote: s.quote, citation: s.case_number || s.case_name, chair_note: note, verified: s.verified, attached_id: s.attached_id ?? "", }, { onSuccess: () => toast.success("הערת-יו״ר נשמרה"), onError: (e: Error) => toast.error(`שגיאה: ${e.message}`), }, ); } const sum = data.summary; return (
{/* summary */}
סוגיות עם פסיקה: {sum.arguments_with_support}/{sum.arguments_total} אומתו: {sum.verified} לידֵי רדאר: {sum.radar_leads} ה-writer מצטט רק מאומתים (INV-AH) · היומון אינו מצוטט (INV-DIG1)
{data.arguments.map((a) => ( {/* issue header */}
{a.title}
סוגיה{a.legal_topic ? ` · ${a.legal_topic}` : ""}
{a.priority && ( {PRIORITY_LABEL[a.priority] ?? a.priority} )}
{/* supporting precedents */}
פסיקה תומכת בקורפוס
{a.supporting.length === 0 ? (

לא נמצאה פסיקה תומכת בקורפוס לסוגיה זו.

) : (
    {a.supporting.map((s) => (
  • {s.case_number || s.case_name} {s.cited_by.positive > 0 && ( אומץ ×{s.cited_by.positive} )} {s.cited_by.negative > 0 && ( אובחן ×{s.cited_by.negative} )}
    {s.quote && (
    {s.quote}
    )}
    {s.verified ? ( <> ✓ אומת ע״י היו״ר ) : ( <> )} {s.cited_by.negative > 0 && !s.verified && ( ⚠ אובחן — בדוק הקשר )}
    {/* chair note */}
    setNotes((n) => ({ ...n, [s.case_law_id]: e.target.value }))} onBlur={() => saveNote(a, s)} className="flex-1 text-[0.8rem] text-ink-soft bg-parchment border border-dashed border-rule rounded-md px-2.5 py-1.5 focus:outline-none focus:border-gold" />
  • ))}
)}
{/* radar — unlinked digests for this issue (INV-DIG1: pointer, not citation) */}
))}
); } function RadarStrip({ radar }: { radar: RadarLead[] }) { if (!radar.length) return null; return (
📡 רדאר — פסיקה שאין לנו בקורפוס (מצביע, לא מצוטט)
    {radar.map((r) => (
  • {r.underlying_citation || "(אין מראה-מקום)"} {RADAR_LABEL[r.action] ?? r.action} {r.headline}
  • ))}
); }