feat(missing-precedents): bridge cited-by-chair + decision number; open/closed tabs; single-line citation
Implements the chair-approved redesign of /missing-precedents (Claude Design card 09). The "צוטט ע״י" and "תיק" columns were empty for ~98% of rows because the corpus-decision reliance lives in precedent_internal_citations (keyed to case_law), a different system than missing_precedents (keyed to cases). Backend (G2 — read-time bridge, no stored duplication): - list_missing_precedents: new cited_by_chairs / cited_by_decisions columns, resolved from the citation graph by normalized docket number (same normalization the relinker uses). For an open gap cited by committee decisions, surfaces the chair(s) (e.g. דפנה תמיר) + the deciding case numbers. Frontend (matches approved mockup): - "צוטט ע״י" shows the chair chip (bridge) with priority over the generic discovery-source chips; "תיק" shows the deciding decision number(s) + "+N". - Status filter reduced to פתוח / נסגר (removed הועלה, לא-רלוונטי, הכל). - "פסיקה" column collapses to a single line when case_name is empty — fixes the duplicated-citation two-row rendering. - Lifecycle note simplified to open → closed. Verified: bridge SQL returns chair+decisions on live data; tsc --noEmit clean; py_compile clean. Follow-up (data, separate): LLM backfill of legal_topic (נושא); create missing_precedents rows for the 28 graph-cited rulings not yet tracked. Invariants: G2 (single source of truth — bridge derived at read, no duplicated column) · INV-AH context (closing source gaps). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -148,18 +148,43 @@ export function MissingPrecedentsTable({ status, q, legalTopic }: Props) {
|
||||
onClick={() => setOpenId(mp.id)}
|
||||
>
|
||||
<TableCell className="max-w-[440px]">
|
||||
<div className="text-sm text-navy font-semibold truncate">
|
||||
{mp.case_name || mp.citation.split(" ").slice(0, 6).join(" ")}
|
||||
</div>
|
||||
<div className="text-[0.72rem] text-ink-muted truncate" dir="rtl">
|
||||
{mp.citation}
|
||||
</div>
|
||||
{/* Single line when there's no distinct case_name — the old
|
||||
two-line layout repeated the citation (name fell back to a
|
||||
truncation of the same citation). Show the name row only
|
||||
when it adds information. */}
|
||||
{mp.case_name && mp.case_name.trim() ? (
|
||||
<>
|
||||
<div className="text-sm text-navy font-semibold truncate">
|
||||
{mp.case_name}
|
||||
</div>
|
||||
<div className="text-[0.72rem] text-ink-muted truncate" dir="rtl">
|
||||
{mp.citation}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div className="text-sm text-navy font-semibold truncate" dir="rtl">
|
||||
{mp.citation}
|
||||
</div>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<span className="text-sm text-ink">{mp.legal_topic || "—"}</span>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{mp.cited_in_case_number ? (
|
||||
{mp.cited_by_decisions?.length ? (
|
||||
/* committee decision(s) that cite this missing ruling
|
||||
(corpus citation-graph bridge) */
|
||||
<span className="inline-flex items-baseline gap-1.5">
|
||||
<span className="text-sm text-navy font-semibold tabular-nums" dir="ltr">
|
||||
{mp.cited_by_decisions[0]}
|
||||
</span>
|
||||
{mp.cited_by_decisions.length > 1 ? (
|
||||
<span className="text-[0.7rem] text-ink-muted">
|
||||
+{mp.cited_by_decisions.length - 1}
|
||||
</span>
|
||||
) : null}
|
||||
</span>
|
||||
) : mp.cited_in_case_number ? (
|
||||
<Link
|
||||
href={`/cases/${encodeURIComponent(mp.cited_in_case_number)}`}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
@@ -173,7 +198,25 @@ export function MissingPrecedentsTable({ status, q, legalTopic }: Props) {
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="text-sm text-ink">
|
||||
{mp.discovery_source === "cited_only" ? (
|
||||
{mp.cited_by_chairs?.length ? (
|
||||
/* cited by a committee DECISION in the corpus → show the
|
||||
chair who relied on it (e.g. דפנה תמיר). Bridge from
|
||||
precedent_internal_citations; takes priority over the
|
||||
generic discovery-source chips. */
|
||||
<>
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="rounded-full whitespace-nowrap bg-success-bg text-success border-transparent"
|
||||
>
|
||||
{mp.cited_by_chairs[0]}
|
||||
</Badge>
|
||||
{mp.cited_by_chairs.length > 1 ? (
|
||||
<div className="text-[0.7rem] text-ink-muted mt-1">
|
||||
+{mp.cited_by_chairs.length - 1} יו״ר
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
) : mp.discovery_source === "cited_only" ? (
|
||||
<>
|
||||
<Badge
|
||||
variant="outline"
|
||||
|
||||
Reference in New Issue
Block a user