feat(plans): עיון+חיפוש בתכניות-מאושרות בטאב התכניות (Phase A)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 3s
Lint — undefined names / undefined-names (pull_request) Successful in 10s

כרטיס-התכניות בדף /precedents הציג רק review_status=pending_review,
כך שתכניות מאושרות (התקינות, בשימוש-חוזר בבלוק ט) לא היו נגישות לעיון.
ה-backend כבר תמך ב-?review_status= ו-?q= — חסר רק חוט-UI.

- plans.ts: usePlansPending → usePlansAll (טעינת כל המרשם בקריאה אחת;
  הפאנל מסנן client-side — מרשם קטן, מונה-מדויק לכל סגמנט, חיפוש מיידי)
- plans-review-panel: סרגל-מצב (ממתינים/מאושרות/כולן) עם מונים + תיבת-חיפוש
  fuzzy (מספר/שם/ייעוד/aliases, מנורמל-bidi); הערת-קטיעה אם >1000 (בלי cap שקט)
- PlanCard מסתעף לפי review_status: מאושרת/נדחתה → תג-מצב + "החזר לתור"
  (review→pending_review) במקום אשר/דחה; דדופ-candidates רק בתור

עבר דרך שער-עיצוב Claude Design (מוקאפ 22-plans-review מאושר ע"י חיים).
ללא שינוי-backend. מרחיב מרשם-V38 הקיים — לא מסלול מקביל.

Invariants: G2 (יכולת קיימת, endpoint קיים) · INV-IA2 (שער-יחיד /precedents)
· G10 נשמר (review_status שער-יו"ר).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-17 10:05:15 +00:00
parent f3b5223f0f
commit d4ec675c67
2 changed files with 167 additions and 34 deletions

View File

@@ -43,17 +43,23 @@ export type Plan = {
export const planKeys = {
all: ["plans"] as const,
pending: () => [...planKeys.all, "pending"] as const,
list: () => [...planKeys.all, "list"] as const,
duplicates: (id: string) => [...planKeys.all, "duplicates", id] as const,
};
/** All plans awaiting the chair gate (G10). */
export function usePlansPending(limit = 500) {
/**
* The whole registry in one fetch (every review_status). The panel filters
* client-side by status segment (ממתינים/מאושרות/כולן) and search — the
* registry is small, so one load gives accurate segment counts + instant
* filtering without per-keystroke round-trips. `limit` is a safety ceiling;
* if it is ever hit the panel surfaces a truncation note (no silent cap).
*/
export function usePlansAll(limit = 1000) {
return useQuery({
queryKey: planKeys.pending(),
queryKey: planKeys.list(),
queryFn: ({ signal }) =>
apiRequest<{ items: Plan[]; count: number }>(
`/api/plans?review_status=pending_review&limit=${limit}`,
`/api/plans?limit=${limit}`,
{ signal },
),
staleTime: 5_000,