feat(case-files): פאנל "קבצי-התיק" — גישה מה-UI לכל תתי-התיקיות #414

Merged
chaim merged 1 commits from worktree-case-files-browser into main 2026-07-07 17:31:17 +00:00
Owner

מימוש מוקאפ X17 מאושר (18m-case-files-browser). פותר את הפער שהעלה היו"ר: קובץ הטיוטה שהסוכן שמר (documents/research/interim-decision-draft.md) היה נגיש רק ב-SSH לשרת — לא מה-UI.

Backend — web/app.py

הכללה של שני ה-endpoints הקיימים מ-research/proofread לכל תת-תיקיית-תוכן:

  • _case_file_folders — מונה כל תת-תיקייה תחת התיק (מקור · מחולץ · מחקר · הגהה · טיוטות · גיבויים), רקורסיה שכבה אחת לתוך documents/, מדלג על מוסתרות (.git/.claude) ו-thumbnails.
  • _resolve_case_file — מאמת folder-key מול רשימת-התיקיות וחוסם path-traversal (target.parent == base + is_file).
  • GET /local-files מחזיר את כל התיקיות כולל ריקות (files:[]); GET /local-files/{folder}/{filename} מגיש מכל תיקייה עם media_type לפי סיומת.

Frontend

  • lib/api/case-files.tsuseCaseFiles · useCaseFileText · caseFileUrl.
  • CaseFilesBrowser — עץ-תיקיות (אקורדיון; ריקות מסומנות "ריק"; תווית-נתיב) + viewer מובנה ל-.md/.txt (רכיב Markdown הקיים) + הורדה לכל קובץ. נבחר כברירת-מחדל קובץ-טקסט ב-research. נטען בטאב "טיוטות והערות" מתחת ל-DraftsPanel.

הערות

  • אין response_model בשני ה-endpoints → אין תלות ב-api:types (מודול הטיפוסים בכתב-יד).
  • ברירות-מחדל לפי אישור היו"ר: תיקיות ריקות מוצגות עם "ריק"; originals נשאר לשלמות.

Invariants

  • G1/G2 — מכליל את יכולת-הקבצים הקיימת, לא יוצר מסלול מקביל. אבטחת-נתיב — allowlist + חסימת traversal.

בדיקות

tsc --noEmit ✓ · eslint ✓ · לוגיקת enumeration+resolution נבדקה מול תיק אמיתי (מזהה 6 תיקיות, חוסם ../ ו-folder-key זדוני). Build מלא ב-CI.

🤖 Generated with Claude Code

מימוש מוקאפ X17 מאושר (`18m-case-files-browser`). פותר את הפער שהעלה היו"ר: קובץ הטיוטה שהסוכן שמר (`documents/research/interim-decision-draft.md`) היה נגיש רק ב-SSH לשרת — לא מה-UI. ## Backend — `web/app.py` הכללה של שני ה-endpoints הקיימים מ-`research/proofread` ל**כל** תת-תיקיית-תוכן: - **`_case_file_folders`** — מונה כל תת-תיקייה תחת התיק (מקור · מחולץ · מחקר · הגהה · טיוטות · גיבויים), רקורסיה שכבה אחת לתוך `documents/`, מדלג על מוסתרות (`.git`/`.claude`) ו-`thumbnails`. - **`_resolve_case_file`** — מאמת `folder`-key מול רשימת-התיקיות ו**חוסם path-traversal** (`target.parent == base` + `is_file`). - `GET /local-files` מחזיר את כל התיקיות כולל **ריקות** (`files:[]`); `GET /local-files/{folder}/{filename}` מגיש מכל תיקייה עם `media_type` לפי סיומת. ## Frontend - **`lib/api/case-files.ts`** — `useCaseFiles` · `useCaseFileText` · `caseFileUrl`. - **`CaseFilesBrowser`** — עץ-תיקיות (אקורדיון; ריקות מסומנות "ריק"; תווית-נתיב) + **viewer מובנה** ל-`.md`/`.txt` (רכיב Markdown הקיים) + **הורדה** לכל קובץ. נבחר כברירת-מחדל קובץ-טקסט ב-`research`. נטען בטאב **"טיוטות והערות"** מתחת ל-DraftsPanel. ## הערות - **אין `response_model`** בשני ה-endpoints → אין תלות ב-`api:types` (מודול הטיפוסים בכתב-יד). - ברירות-מחדל לפי אישור היו"ר: תיקיות ריקות מוצגות עם "ריק"; `originals` נשאר לשלמות. ## Invariants - **G1/G2** — מכליל את יכולת-הקבצים הקיימת, לא יוצר מסלול מקביל. **אבטחת-נתיב** — allowlist + חסימת traversal. ## בדיקות `tsc --noEmit` ✓ · `eslint` ✓ · לוגיקת enumeration+resolution נבדקה מול תיק אמיתי (מזהה 6 תיקיות, חוסם `../` ו-folder-key זדוני). Build מלא ב-CI. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
chaim added 1 commit 2026-07-07 17:31:09 +00:00
feat(case-files): פאנל "קבצי-התיק" בטאב טיוטות — גישה מה-UI לכל תתי-התיקיות
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 31s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
85af98cded
היו"ר לא יכל לגשת לטיוטה שהסוכן שמר בדיסק (interim-decision-draft.md) אלא ב-SSH.
מימוש מוקאפ X17 מאושר (18m): פאנל דפדפן-קבצים בטאב "טיוטות והערות".

Backend (web/app.py) — הכללה של ה-endpoints הקיימים ל**כל** תת-תיקייה:
- `_case_file_folders` — מונה כל תת-תיקיית-תוכן תחת התיק (מקור/מחולץ/מחקר/הגהה/
  טיוטות/גיבויים), רקורסיה שכבה אחת לתוך documents/, מדלג על מוסתרות (.git/.claude)
  ו-thumbnails. `_resolve_case_file` מאמת folder-key מול הרשימה + חוסם path-traversal.
- `/local-files` מחזיר את כל התיקיות (כולל ריקות, עם files=[]); `/local-files/{folder}/{filename}`
  מגיש מכל תיקייה עם media-type לפי סיומת.

Frontend:
- `lib/api/case-files.ts` — useCaseFiles / useCaseFileText / caseFileUrl.
- `CaseFilesBrowser` — עץ-תיקיות (אקורדיון, ריקות מסומנות "ריק") + viewer מובנה
  ל-md/txt (Markdown הקיים) + הורדה לכל קובץ. נטען בטאב "טיוטות והערות".

אין response_model → אין תלות ב-api:types (מודול טיפוסים בכתב-יד).
Invariants: G1, G2 (אין מסלול-קבצים מקביל — מכליל את הקיים), אבטחת-נתיב.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
chaim merged commit 29970ad8b2 into main 2026-07-07 17:31:17 +00:00
chaim deleted branch worktree-case-files-browser 2026-07-07 17:31:17 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ezer-mishpati/legal-ai#414