fix(halachot): ספירת-תור אמיתית + עדכון-חי בתגי-הכרעה (#6/#7/#8)
המספרים בתגי תור-ההלכות היו תקרות-שאילתה ולא ספירה אמיתית: - "ממתינות 500" = pendingData.items.length עם limit=500 - "נדחו 1000 / אושרו 1000" = useHalachotByStatus(...,1000) — תקרה 1000 ובלי refetchInterval התגים התעדכנו רק בכניסה לדף. המקור האמיתי כבר קיים: /api/precedent-library/stats מריץ COUNT(*) אמיתי (pending=1373, approved=2100). מוסיף לו halachot_rejected + halachot_deferred, מחבר את תגי-ה-HalachaReviewPanel למקור הזה, ומוסיף polling (30s) כדי שהם יתעדכנו חי. מסיר את useHalachaCount המיותר. תור-העבודה עצמו עדיין נטען עד 500 פריטים (cap-עבודה לגיטימי); רק תצוגת הספירות תוקנה להציג את הסך-האמיתי. Invariants: מקיים G1 (נרמול-במקור — ספירה אמיתית מ-COUNT(*) במקום len(rows) מתוקרת בקריאה) ו-G2 (מאחד על מקור-הספירה הקיים, ללא endpoint-ספירה מקביל). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,7 @@ import { CorroborationBadge } from "./corroboration-badge";
|
||||
import { practiceAreaLabel } from "./practice-area";
|
||||
import {
|
||||
useHalachotPending, useHalachotByStatus, useUpdateHalacha, useBatchReviewHalachot,
|
||||
isExtractionFixItem, type Halacha,
|
||||
useLibraryStats, isExtractionFixItem, type Halacha,
|
||||
} from "@/lib/api/precedent-library";
|
||||
import { AuthorityBadge, ruleTypeLabel } from "./halacha-meta";
|
||||
|
||||
@@ -979,13 +979,6 @@ function PendingPanel() {
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Count badge for tabs ─────────────────────────────────────────────────────
|
||||
|
||||
function useHalachaCount(status: string) {
|
||||
const { data } = useHalachotByStatus(status, 1000);
|
||||
return data?.count ?? data?.items.length ?? null;
|
||||
}
|
||||
|
||||
// ─── Main export ──────────────────────────────────────────────────────────────
|
||||
|
||||
type Tab = "pending" | "rejected" | "approved";
|
||||
@@ -998,16 +991,16 @@ const TAB_LABELS: Record<Tab, string> = {
|
||||
|
||||
export function HalachaReviewPanel() {
|
||||
const [tab, setTab] = useState<Tab>("pending");
|
||||
const { data: pendingData } = useHalachotPending({ limit: 500 });
|
||||
const rejectedCount = useHalachaCount("rejected");
|
||||
const approvedCount = useHalachaCount("approved");
|
||||
|
||||
const pendingCount = pendingData?.items.length ?? null;
|
||||
// Real COUNT(*) totals from the stats endpoint — not the limit-capped
|
||||
// /api/halachot len(rows), which pinned these chips at 500/1000/1000 and only
|
||||
// refreshed on navigation. The stats query polls, so the chips track live (#6/#7/#8).
|
||||
const { data: stats } = useLibraryStats();
|
||||
|
||||
const counts: Record<Tab, number | null> = {
|
||||
pending: pendingCount,
|
||||
rejected: rejectedCount,
|
||||
approved: approvedCount,
|
||||
pending: stats?.halachot_pending ?? null,
|
||||
rejected: stats?.halachot_rejected ?? null,
|
||||
approved: stats?.halachot_approved ?? null,
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -188,6 +188,8 @@ export type LibraryStats = {
|
||||
halachot_total: number;
|
||||
halachot_pending: number;
|
||||
halachot_approved: number;
|
||||
halachot_rejected: number;
|
||||
halachot_deferred: number;
|
||||
};
|
||||
|
||||
export type ListFilters = {
|
||||
@@ -301,7 +303,11 @@ export function useLibraryStats() {
|
||||
queryKey: libraryKeys.stats(),
|
||||
queryFn: ({ signal }) =>
|
||||
apiRequest<LibraryStats>("/api/precedent-library/stats", { signal }),
|
||||
staleTime: 60_000,
|
||||
staleTime: 30_000,
|
||||
// The halacha-review tab counts ride on this (real COUNT(*) — not the
|
||||
// limit-capped /api/halachot len), so poll so the chips track approvals
|
||||
// live instead of only refreshing on navigation (#6/#7/#8).
|
||||
refetchInterval: 30_000,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user