fix(cases): מספור 5-ספרתי לבל"מ — סיווג, ולידציה, וחיפוש פסיקה-חסרה
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 6s
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 6s
נוהל-יו"ר (2026-06-11): מבנה מספר-תיק = <סידורי>-<חודש>-<שנה>, ואורך הסידורי
מקודד את סוג-ההליך — 4 ספרות = ערר, 5 ספרות = בל"מ. הספרה הראשונה ממשיכה
לקבוע תחום בשני האורכים (1→רישוי, 8→היטל, 9→פיצויים). הכלל חד-כיווני:
5-ספרתי הוא תמיד בל"מ; 4-ספרתי אינו מחייב ערר (בל"מ-מורשת מזוהה מהנושא).
הבאג שדיווח עליו היו"ר: חיפוש פסיקה-חסרה לפי מספר-תיק החזיר 404 על כל ערך
שאינו תיק קיים — שבר את הטבלה תוך כדי הקלדה ועל מספרי 5-ספרות.
תיקונים:
- web/app.py: GET /api/missing-precedents — מסנן case_number שלא תאם תיק מחזיר
רשימה ריקה (200), לא 404. סמנטיקה תקינה ל-collection-filter.
- missing-precedents/page.tsx: debounce (350ms) על שדות-הסינון — קוורי אחד
אחרי שמפסיקים להקליד, לא אחד לכל הקשה.
- practice_area.py: regex סידורי \d{4}→\d{4,5}; case_serial_digits() +
is_blam_by_number() (5⇒בל"מ); derive_subtype_with_blam ו-derive_proceeding_type
מזהים בל"מ גם מ-5-ספרות (בנוסף לנושא). callers: cases.py, internal_decisions.py.
- proofreader.py: דפוסי חילוץ-שם-קובץ \d{3,4}→\d{3,5}.
- web-ui: practice-area.ts (מראָה ל-backend), schemas/case.ts (regex
serial-month-year, 4-or-5 ספרות, superRefine 5⇒בל"מ), placeholder בוויזרד.
- תיעוד: docs/spec/X1-identifiers.md §1א + legal-ai/CLAUDE.md.
Invariants: מקיים G1 (נרמול-במקור — ספרה ראשונה כמקור-אמת יחיד לתחום),
G2 (מסלול-סיווג יחיד, אין כפילות), INV-DM/X1 (מפתח קנוני + proceeding_type).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { AppShell } from "@/components/app-shell";
|
||||
import { Input } from "@/components/ui/input";
|
||||
@@ -35,6 +35,20 @@ export default function MissingPrecedentsPage() {
|
||||
const [legalTopic, setLegalTopic] = useState("");
|
||||
const [filter, setFilter] = useState<StatusFilter>("open");
|
||||
|
||||
/* Debounce the filters so the table fires one query after the user stops
|
||||
* typing — not one per keystroke. Each intermediate value used to
|
||||
* round-trip to the API (and a non-existent case number errored mid-typing). */
|
||||
const [caseNumberQ, setCaseNumberQ] = useState("");
|
||||
const [legalTopicQ, setLegalTopicQ] = useState("");
|
||||
useEffect(() => {
|
||||
const t = setTimeout(() => setCaseNumberQ(caseNumber.trim()), 350);
|
||||
return () => clearTimeout(t);
|
||||
}, [caseNumber]);
|
||||
useEffect(() => {
|
||||
const t = setTimeout(() => setLegalTopicQ(legalTopic.trim()), 350);
|
||||
return () => clearTimeout(t);
|
||||
}, [legalTopic]);
|
||||
|
||||
const counts = useMissingPrecedents({ limit: 1 });
|
||||
const byStatus = counts.data?.by_status ?? {};
|
||||
|
||||
@@ -123,8 +137,8 @@ export default function MissingPrecedentsPage() {
|
||||
|
||||
<MissingPrecedentsTable
|
||||
status={filter === "all" ? "" : filter}
|
||||
caseNumber={caseNumber.trim() || undefined}
|
||||
legalTopic={legalTopic.trim() || undefined}
|
||||
caseNumber={caseNumberQ || undefined}
|
||||
legalTopic={legalTopicQ || undefined}
|
||||
/>
|
||||
|
||||
{/* lifecycle note (mockup 09 `.lifecycle`) */}
|
||||
|
||||
Reference in New Issue
Block a user