Merge pull request 'docs(ia): אבחון משטח-ההפעלה + ספ-יעד X17 — מפה אחת לכל הדפים/כפילויות/סנכרון (#127)' (#206) from worktree-ia-audit-docs into main
This commit was merged in pull request #206.
This commit is contained in:
146
docs/ia-audit-redesign.md
Normal file
146
docs/ia-audit-redesign.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# IA-Audit & Redesign — מפת משטח-ההפעלה, כפילויות, וניווט-יעד
|
||||
|
||||
> **מה זה.** אבחון שיטתי של **משטח-ההפעלה** של המערכת (כל דף/טאב/drawer/פונקציה) — מה כל אחד עושה, מה כפול, מה מת, מה מציג נתון שגוי, ואיך הכול מסתנכרן — ו**תכנון-מחדש** של ארכיטקטורת-המידע (IA). נכתב לפי בקשת חיים (2026-06-11): *"המערכת מסובכת מדי לתפעול… כל הדפים האלה מפוזרים ואין לי מושג מה כל אחד עושה והאם יש כפילויות."*
|
||||
>
|
||||
> **היקף:** משטח-ההפעלה (1א). ה-backend נכלל רק היכן שהוא גורם לכפילות/נתון-שגוי ב-UI. תוצר-אחות: ספ-היעד [`docs/spec/X17-information-architecture.md`](spec/X17-information-architecture.md). יוזמה: TaskMaster `legal-ai` **#127**.
|
||||
>
|
||||
> **איך הופק:** סריקת-עומק רב-סוכנית (18 סוכנים, 6 אשכולות × 3 שלבים — קטלוג → אימות-אדוורסרי מול הקוד → תכנון-יעד מגובה-מקורות). כל ממצא אומת ב-`file:line`; כל עקרון-תכנון מגובה ב-≥3 מקורות סמכותיים (ראה [X17 §מקורות](spec/X17-information-architecture.md)).
|
||||
|
||||
## יחס למסמכים קיימים (דאבל-צ'ק — לא לכפול)
|
||||
- **[`ui-audit.md`](spec/ui-audit.md)** — ביקורת-קוד פר-רכיב (enums כפולים, טיפוסים, helpers → FU-10). **שכבה אחרת.** מסמך זה הוא בשכבת ה-**IA/הפעלה** (אילו משטחים, מה כל אחד עושה, סנכרון, ניווט). חופף נקודתית ב-UI-C1 (3 דפי-פסיקה חופפים) ו-UI-D2/D3 (שקיפות-מקור) — מורחב כאן.
|
||||
- **[`gap-audit.md`](spec/gap-audit.md)** — ממצאי-ארכיטקטורה (GAP→FU). מסמך זה ברמת-הדף.
|
||||
- **[`X6-ui-api-contract.md`](spec/X6-ui-api-contract.md)** — חוזה UI↔API (UI1–UI6). X17 מוסיף שכבת invariants מעל X6.
|
||||
|
||||
---
|
||||
|
||||
## 1. תקציר-מנהלים — 5 מחלות-השורש
|
||||
|
||||
הסריקה אימתה **37 ממצאים** על פני 34 משטחים. כולם נופלים ל-5 דפוסים:
|
||||
|
||||
| # | מחלת-שורש | כמה | מהות |
|
||||
|---|-----------|-----|------|
|
||||
| **D1** | **פערי-סנכרון ב-cache** | 16 | mutation מבטל רק את ה-queryKey המקומי, לא את ה-aggregator/האח/ה-namespace השני → מונה/נתון תקוע ב-0–60ש' בין דפים. זהו G2 בשכבת ה-TanStack-Query cache. |
|
||||
| **D2** | **משטחי-כתיבה/אישור כפולים** | 6 (dup) + 2 confusing | אותו datum נערך/מאושר ב-2 מקומות שכותבים ל-2 ערוצים. החריף: **שני שערי-למידה** (decision_lessons מול promote) ו-**מתודולוגיה** (PUT מול promote כותבים לאותה שורה — מירוץ lost-update). זו בדיוק ה"למה 2 שערים" של חיים. |
|
||||
| **D3** | **נתונים-שגויים/מטעים** | 6 | KPI סופר דגל אינפורמטיבי-בלבד (`applied_to_skill`/`findings_applied` — "מזויף"); `signature_phrases` עם תווית-קרדינליות שקרית; מונה-תור שמתעלם מחברה לא-זמינה. |
|
||||
| **D4** | **משטחים/פונקציות מתים** | 5 | endpoint `queue/pending` ללא צרכן; כפתור `applied_to_skill`; ז'רגון `T7/T15`; `AuthorityBadge` חסר בחיפוש. |
|
||||
| **D5** | **כפילות-ניווט** | — | הערות-יו"ר ב-2 דפים; `/operations`+`/diagnostics` אותו intent; `precedents` מול `precedent-library`. |
|
||||
|
||||
**התובנה המאחדת:** רוב המחלות הן ביטוי-UI אחד של עקרון-על מופר — **G2 (מקור-אמת יחיד / אין מסלולים מקבילים)** — שמעולם לא הורחב לשכבת-ה-UI (cache + משטחים). זה בדיוק מה שחיים חווה כ"מסובך לתפעול": אותו מספר בשני מקומות, שני שערים לאותה החלטה, ומספרים שלא מתעדכנים.
|
||||
|
||||
### ניווט-היעד (תמצית — מלא ב-X17)
|
||||
שלושה משטחי-**intent** עם בעלים-יחיד, במקום פיזור-לפי-פורמט:
|
||||
1. **`/approvals` = תיבת-ההחלטות-האנושית היחידה** — המקום היחיד שבו פועלים על שער. דפים אחרים **מצביעים** למונה, לא משכפלים אותו.
|
||||
2. **`/operations` = משטח-הקריאה-בלבד היחיד** ("מה המכונה עושה") — בולע את `/diagnostics`.
|
||||
3. **`/settings` = משטח-התצורה היחיד.**
|
||||
ובתוך-התחום: **החלטה=workspace אחד** · **למידה=תיבה+ערוץ+שער אחד** · **`/methodology`=עורך-הכללים היחיד** · **פסיקה=3 קורפוסים נפרדים אך מתפעלים אחיד**.
|
||||
|
||||
> **כל ההצעות שומרות 100% מהשערים-האנושיים (G10/INV-LRN1).** מסירים משטח/ערוץ **כפול**, לא שער. זו ההתאמה בין "פשטות-הפעלה" ל-G10.
|
||||
|
||||
---
|
||||
|
||||
## 2. ממצאים לפי אשכול
|
||||
|
||||
לכל אשכול: משטחים שקוטלגו · ממצאים מאומתים (file:line) · כיוון-היעד. הפירוט המלא (כל אלמנט + כל מקור) נשמר בפלט-הסריקה ([`data/audit/`](../data/audit/)).
|
||||
|
||||
### 2.1 תיקים (`/`, `/archive`, `/cases/[n]`, `/compose`)
|
||||
**3 משטחים · 2 ממצאים.** מחלה: תוכן-ההחלטה מפוצל ל-2 משטחי-כתיבה עצמאיים + עורך-compose שלישי.
|
||||
|
||||
| ID | סוג | ממצא | file:line | תיקון |
|
||||
|----|-----|------|-----------|-------|
|
||||
| CAS-1 | sync-gap | `DraftsPanel` (העלאת DOCX) לא מבטל `['decision-blocks']` → `DecisionBlocksPanel` מציג `source_of_truth='blocks'` תקוע; אזהרת-הסטייה לא מופיעה עד רענון ידני | exports.ts:103-107 מול decision-blocks.ts:46-49; app.py:2673 | add-invalidation |
|
||||
| CAS-2 | sync-gap | `useExportDocx` לא מבטל `['decision-blocks']` — אותו שורש | exports.ts:80-82 | add-invalidation |
|
||||
|
||||
**יעד:** workspace-החלטה אחד (block-editing + DOCX-פעיל) עם **מחוון-מקור-אמת אחד** בבעלות-המערכת ו-cache-slice משותף; אזור "השלמה והעברה" אחד לכל שערי-סיום-התיק.
|
||||
|
||||
### 2.2 אישורים + הערות-יו"ר (`/approvals`, `/feedback`)
|
||||
**3 משטחים · 6 ממצאים.** מחלה: `/api/chair/pending` גוזר 4 מונים, אך כל משטח-משימה מבטל רק את ה-cache שלו ולא את ה-aggregator → התיבה והתג-בסרגל תקועים עד 60ש'.
|
||||
|
||||
| ID | סוג | ממצא | file:line | תיקון |
|
||||
|----|-----|------|-----------|-------|
|
||||
| APR-1 | sync-gap | פתרון הערה ב-`/feedback` לא מבטל `['chair','pending']` → מונה `/approvals` והתג תקועים | feedback.ts:105; chair.ts:36; app-shell.tsx:336 | add-invalidation |
|
||||
| APR-2 | duplication | הערות-יו"ר ב-2 caches (`['feedback']` מול `['chair','pending']`) ללא הצלבה — שני endpoints על אותה `chair_feedback WHERE NOT resolved` | app.py:5650,5654 | add-invalidation |
|
||||
| APR-3 | wrong-data | דגימת-ההערות ב-`/approvals` יכולה להראות 5 ישנות בעוד המונה כבר 0 | app.py:5650-5654; chair.ts:36 | fix-data |
|
||||
| APR-4 | sync-gap | `ApprovalsBadge` בסרגל תקוע אחרי פתרון-הערה/אישור-הלכה/העלאת-פסיקה | app-shell.tsx:336; feedback.ts:105; missing-precedents.ts:256-258; precedent-library.ts:648,668 | add-invalidation |
|
||||
| APR-5 | sync-gap | אישור-הלכה לא מבטל `['chair','pending']` | precedent-library.ts:648,668; app.py:5619-5620 | add-invalidation |
|
||||
| APR-6 | sync-gap | העלאת/סגירת פסיקה-חסרה לא מבטל `['chair','pending']` | missing-precedents.ts:256-258; app.py:5636-5637 | add-invalidation |
|
||||
|
||||
**יעד:** `/approvals` = תיבת-הגייטים הקנונית היחידה; `['chair','pending']` = מקור-אמת יחיד ל"מה ממתין"; התג בסרגל = המונה היחיד; **הערות-יו"ר יורד מהניווט-הראשי** והופך לכרטיס-משימה מתוך התיבה.
|
||||
|
||||
### 2.3 פסיקה (`/precedents`, `/missing-precedents`, `/digests`, `/precedents/[id]`, `/graph`)
|
||||
**13 משטחים · 5 ממצאים.** מחלה: 3 קורפוסים אמיתיים ושונים — אך **מתפעלים שונה** ומבלבלים בשמות.
|
||||
|
||||
| ID | סוג | ממצא | file:line | תיקון |
|
||||
|----|-----|------|-----------|-------|
|
||||
| PRE-1 | confusing | שני namespaces כמעט-זהים: `/api/precedents/search` (typeahead לתיק) מול `/api/precedent-library/search` (חיפוש-קורפוס) | app.py:3109 מול 6057 | clarify (rename/label) |
|
||||
| PRE-2 | dead | `GET /api/precedent-library/queue/pending` — אפס צרכני-frontend (רק digests משתמש ב-queue/pending) | app.py:6282 | delete |
|
||||
| PRE-3 | wrong-data | `AuthorityBadge` (binding/persuasive, DERIVED) מוצג בתור-הביקורת אך **נשמט בחיפוש** | library-search-panel.tsx:26-73 מול halacha-review-panel.tsx:109 | fix-data |
|
||||
| PRE-4 | confusing | תג "ממתין" ב-`/digests` נראה לחיץ אך אינו (ב-`/precedents` הוא טאב-תור אמיתי) | digests/page.tsx:23-35 | clarify |
|
||||
| PRE-5 | dead | `HalachaCard` בחיפוש לא מרנדר authority אף שהשדה על החוט | library-search-panel.tsx:26-73 | fix-data |
|
||||
|
||||
**יעד:** 3 הקורפוסים נשארים נפרדים (גבול אמיתי — G2/INV-DIG1) אך **מתפעלים אחיד**: שם-חיפוש עקבי לכל קורפוס, תבנית-"ממתין" אחת, authority מוצג בכל מקום. מחיקת ה-endpoint המת.
|
||||
|
||||
### 2.4 למידה + סגנון (`/training` — 6 טאבים + CorpusDetailDrawer) ⚠️ האשכול הקריטי
|
||||
**8 משטחים · 10 ממצאים.** מחלה: "לקח" חי ב-2 namespaces ומאושר ב-2 מקומות שכותבים ל-2 ערוצי-כותב; 3 KPI על דגלים-ללא-צרכן.
|
||||
|
||||
| ID | סוג | ממצא | file:line | תיקון |
|
||||
|----|-----|------|-----------|-------|
|
||||
| LRN-1 | sync-gap | כפתור `applied_to_skill` ("אומץ לסקייל") **אינפורמטיבי-בלבד** — לא כותב ל-SKILL.md; היו"ר מאמין שהפעולה הושלמה | lessons-tab.tsx:12-14; app.py:1471-1475 | fix-data (להסיר) |
|
||||
| LRN-2 | confusing | למידה מפוצלת ל-`/api/learning` + `/api/training` לאותה ישות | learning.ts; training.ts; app.py:1448,4616 | clarify (לאחד) |
|
||||
| LRN-3 | confusing | **שני שערי-אישור ללא יחס אכוף** — `promote` מתעלם מ-`review_status` לגמרי | learning-panel.tsx:89-150; lessons-tab.tsx:168-179; app.py:4574 | clarify (שער אחד) |
|
||||
| LRN-4 | wrong-data | `StyleReportPanel`: "12 מתוך 487 שחולצו" — `signature_phrases` ו-`total_patterns` מחושבים עצמאית; אין יחס-תת-קבוצה | style-report-panel.tsx:87-90 | fix-data |
|
||||
| LRN-5 | wrong-data | `findings_applied` ("ממצאים שאומצו ל-SKILL: 42") סופר דגל-אינפורמטיבי → KPI "מזויף" | curator-portrait-panel.tsx:85-86; app.py:1300-1302 | fix-data |
|
||||
| LRN-6 | sync-gap | מחיקת-קורפוס לא מאפסת בחירת `ComparePanel` → submit מחזיר 404 | compare-panel.tsx:119-120; training.ts:172-174 | fix-data |
|
||||
| LRN-7 | keep | `FullTextLazy` ב-raw-fetch מחוץ ל-Query — שביר לעתיד, לא באג חי | corpus-detail-drawer.tsx:320-348 | keep |
|
||||
| LRN-8 | sync-gap | מחיקת-קורפוס מייתמת צ'אטים (`style_corpus_id→NULL`) בשקט, ללא אזהרה | corpus-panel.tsx:45-54; db.py:234 | add-invalidation |
|
||||
| LRN-9 | keep | סינון `PatternsForSubtype` stubbed (אין endpoint) — fallback חינני | corpus-detail-drawer.tsx:351-353 | keep |
|
||||
| LRN-10 | sync-gap | `usePromoteLearning` מבטל רק `learningKeys`, לא `lessonsKeys.forCorpus` → LessonsTab תקוע | learning.ts:104-115; training.ts:499-502 | add-invalidation |
|
||||
|
||||
**יעד:** תיבת-אישור-למידה אחת (מקובצת לפי זוג draft↔final) · **ערוץ-כותב אחד + סטטוס "זורם-לכותב" אחד** (`review_status='approved'`) · **הסרת `applied_to_skill`** (אוצרות SKILL.md = מעשה-git ידני, לא כפתור) · כל artifact תלוי בזוג שלו (progressive disclosure) · תיקון 2 ה-KPI.
|
||||
|
||||
### 2.5 מתודולוגיה (`/methodology` — 5 טאבים)
|
||||
**2 משטחים · 8 ממצאים.** מחלה: כללי-הכותב נערכים מ-2 משטחים שכותבים לאותה שורה `appeal_type_rules(_global, …, 'universal')` — מירוץ lost-update + פער-cache.
|
||||
|
||||
| ID | סוג | ממצא | file:line | תיקון |
|
||||
|----|-----|------|-----------|-------|
|
||||
| MET-1 | sync-gap | `promote` מבטל `['learning']` בלבד; `/methodology` (`['methodology',cat]`, staleTime 30ש') תקוע אחרי אישור | learning.ts:113; methodology.ts:26-28; app.py:4629-4631 | add-invalidation |
|
||||
| MET-2 | duplication | `discussion_rules['universal']` נכתב ב-2 מקומות (PUT מול promote) — כתיבה-שנייה דורסת בשקט | discussion-rules-panel.tsx:35-36; learning-panel.tsx:138-139; app.py:4491-4495,4629; db.py:290 | fix-data |
|
||||
| MET-3 | duplication | `transition_phrases['universal']` — אותו מירוץ | methodology/page.tsx:45-49; learning-panel.tsx:125-129; app.py:4631 | fix-data |
|
||||
| MET-4 | confusing | `universal` מוצג כדלי-תוצאה אח, אך בפועל **מוקדם (prepended)** לכל התוצאות — אין מודל-מנטלי | discussion-rules-panel.tsx:16-22; lessons.py:376-379 | clarify |
|
||||
| MET-5 | dead | ז'רגון `T15`/`T7` בטקסט-העזר — מזהי-משימות פנימיים חסרי-משמעות למפעיל | methodology/page.tsx:48,55 | fix-data |
|
||||
| MET-6 | wrong-data | עורך-צ'קליסטים מציג 5 סוגי-ערר ללא מיפוי איזה `appeal_type` צורך כל אחד | content-checklists-panel.tsx:17-31; app.py:4414 | clarify |
|
||||
| MET-7 | confusing | 3 מושגי-"כלל" מתערבבים (ratios/rules/checklists) ללא מודל-תחולה | methodology/page.tsx:16-19; block_writer.py:912-923 | clarify |
|
||||
| MET-8 | sync-gap | סדר-callbacks ב-promote → toast-הצלחה אחרי invalidation לא-מספק | learning.ts:112-113; learning-panel.tsx:138-143 | add-invalidation |
|
||||
|
||||
**יעד:** `/methodology` = העורך הקנוני **היחיד** (כל כתיבה דרך PUT אחד, עם תג-מקור "ידני/מאומץ-מלמידה"); הלמידה **מנותבת דרכו** (לא כותבת-במקביל) ומבטלת את שני ה-caches; explainer-תחולה inline; קופי בעברית-פשוטה (בלי T7/T15).
|
||||
|
||||
### 2.6 תפעול + אבחון + הגדרות (`/operations`, `/diagnostics`, `/settings`, `/skills`)
|
||||
**5 משטחים · 6 ממצאים.** מחלה: 4 משטחים שמריצים שאילתות-מקור זהות בלי cache משותף + נתונים-מתים/מטעים.
|
||||
|
||||
| ID | סוג | ממצא | file:line | תיקון |
|
||||
|----|-----|------|-----------|-------|
|
||||
| ADM-1 | sync-gap | `halacha_backlog` מוחזר מה-backend אך **נזרק** ב-frontend (אין בטיפוס, לא מרונדר) | app.py:2253; system.ts:21-32; diagnostics/page.tsx | fix-data (לרנדר/להסיר) |
|
||||
| ADM-2 | sync-gap | מוני-הלכות כפולים ב-`/operations` ו-`/approvals` ללא קישור-cache | operations.ts:60; chair.ts:36; app.py:6520,5619-5633 | add-invalidation (consolidate) |
|
||||
| ADM-3 | sync-gap | מוני-פסיקה-חסרה כפולים ב-`/operations` ו-`/approvals` | operations.ts:60; app.py:6521,5636-5647 | add-invalidation (consolidate) |
|
||||
| ADM-4 | confusing | `court_fetch`: "בתור" כולל failed, מטשטש pending מול queued | operations/page.tsx:286-304; app.py:6562 | clarify |
|
||||
| ADM-5 | sync-gap | עריכת env ב-Coolify לא מרעננת את ערך-ה-Container ולא מזהירה על staleness עד redeploy | env-var-row.tsx:76-96; settings.ts:135 | fix-data |
|
||||
| ADM-6 | wrong-data | מוני-סוכנים מסכמים רק חברות-Paperclip זמינות → עומק-תור מוקטן בשקט כשחברה לא-נטענת | app.py:6667-6689; operations/page.tsx:461-465 | clarify (להציג חלקיות) |
|
||||
|
||||
**יעד:** **`/approvals`=תיבת-ההחלטות** (כל גייט נפעל רק כאן; `/operations` מצביע ולא משכפל) · **`/operations`=משטח-קריאה יחיד** (בולע את `/diagnostics`, מרנדר `halacha_backlog`, מתקן queued/pending, מציג חלקיות) · **`/settings`=תצורה** (עריכת-env שמשלימה-את-עצמה: סימון-staleness + redeploy באותה שורה).
|
||||
|
||||
---
|
||||
|
||||
## 3. עדכוני-ספ מומלצים (מתועדים ב-X17)
|
||||
הסריקה זיהתה ש-X6 לא מכסה את שכבת-ה-UI-state, וש-07-learning מסנקצן בטעות שני-ערוצים. ההמלצות (כל אחת מגובת-מקורות ב-X17):
|
||||
1. **X6 — invariants חדשים בשכבת-UI:** (א) aggregate-נגזר = מקור-אמת; כל mutation לטבלת-מקור חייב לבטל את ה-queryKey שלו; אסור מונה-מתחרה client-side. (ב) למונה-גייט בעלים-משטח-יחיד; אחרים מצביעים. (ג) שדה ב-OpenAPI-response — לרנדר או להסיר (אסור לזרוק בשקט). (ד) אסור להציג aggregate מדויק כש-partial-failure השמיט תורם — להציג חלקיות.
|
||||
2. **07-learning §0.4/§0.6:** שער-אישור **אחד**, טרנזקציית-כותב **אחת**, `applied_to_skill` מוסר; לקחים-מאושרים נכתבים רק דרך מסלול-המתודולוגיה היחיד.
|
||||
3. **00-constitution G2 "הפרות ידועות":** להוסיף את תאום-המתודולוגיה (`discussion_rules['universal']` נכתב ע"י PUT וגם promote).
|
||||
|
||||
---
|
||||
|
||||
## 4. הבא — בקלוג-איחוד (פאזה F)
|
||||
מסמך זה **ממפה ומאבחן**; הוא אינו משנה קוד. הבקלוג המתועדף (TaskMaster, מקושר לכל ממצא) נגזר ב-#127.6 ומחולק ל-3 גלים:
|
||||
- **גל-1 (זול, גבוה-ערך):** הוספת-invalidation ל-16 פערי-הסנכרון + תיקון 6 הנתונים-השגויים + מחיקת המתים. תיקון מקומי, אין הגירת-IA.
|
||||
- **גל-2 (איחוד-משטחים):** תיבת-אישור אחת · ערוץ-למידה אחד (הסרת `applied_to_skill`, איחוד שני-השערים) · `/operations`⊇`/diagnostics`.
|
||||
- **גל-3 (ניווט):** הורדת `/feedback` מהראשי · שמות-חיפוש עקביים · X17 ל-canonical.
|
||||
|
||||
**הכרעת-יו"ר נדרשת לפני גל-2/3** (3א — עוצרים על המסמך).
|
||||
@@ -3,11 +3,12 @@
|
||||
זהו מקור-האמת הקנוני ל"מהו תקין" במערכת. שער-הכניסה: [00-constitution.md](00-constitution.md).
|
||||
כל invariant מגובה ב-≥3 מקורות סמכותיים; פריט לא-מאומת מסומן ⚠ UNVERIFIED ומועלה ליו"ר.
|
||||
|
||||
מבנה: 00 חוקה · 01–07 מחזור-חיים · X1–X16 חוצי-שלבים. ראה אינדקס מלא בחוקה.
|
||||
מבנה: 00 חוקה · 01–07 מחזור-חיים · X1–X17 חוצי-שלבים. ראה אינדקס מלא בחוקה.
|
||||
- X1–X5: מזהים · רב-חברתי · אינטגרציה+deploy · סוכנים · audit.
|
||||
- X6–X10 (מחזור-2, 8 משטחי-האפליקציה): חוזה UI↔API · לקוח-Paperclip · מילוי-שדות · חוזה כלי-MCP · deploy/env/secrets.
|
||||
- X11–X14 (הרחבות-תחום): citator פנימי (תיקוף-הלכות) · יומונים כשכבת-גילוי (radar) · אחזור-פסיקה אוטומטי מנט המשפט (שירות) · אחסון-אובייקטים (MinIO/S3, הגירת `data/`).
|
||||
- X15–X16 (ארכיטקטורת-יסוד): שער-הפלטפורמה (Paperclip מאחורי Port — G12, מיישם G2) · עמידות-פייפליין (LangGraph כספרייה — checkpointing/replay, מחזק G3).
|
||||
- X17 (ארכיטקטורת-מידע): [X17-information-architecture.md](X17-information-architecture.md) — משטח-ההפעלה (דפים/תורים/ניווט/cache); INV-IA1–IA6 מרימים את G2 ו-G10 לשכבת-ה-UI. מיישם feedback_operational_simplicity.
|
||||
|
||||
מפות-ממצאים: [gap-audit.md](gap-audit.md) (GAP-01..62 → FU-1..15; מחזור-1 ✅ הושלם, מחזור-2 פתוח) · [ui-audit.md](ui-audit.md) (ביקורת 13 דפי-UI).
|
||||
מפות-ממצאים: [gap-audit.md](gap-audit.md) (GAP-01..62 → FU-1..15; מחזור-1 ✅ הושלם, מחזור-2 פתוח) · [ui-audit.md](ui-audit.md) (ביקורת 13 דפי-UI, שכבת-קוד) · [ia-audit-redesign.md](../ia-audit-redesign.md) (34 משטחים, 37 ממצאים, שכבת-IA/הפעלה → X17, #127).
|
||||
בסיס-עיצוב: docs/superpowers/specs/2026-05-30-system-spec-design.md
|
||||
|
||||
78
docs/spec/X17-information-architecture.md
Normal file
78
docs/spec/X17-information-architecture.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# X17 — ארכיטקטורת-המידע ומשטח-ההפעלה (Information Architecture)
|
||||
|
||||
> **מה זה.** ספ-היעד ל**איך** משטח-ההפעלה (דפים/טאבים/תורים/ניווט/cache) צריך להיות מאורגן — שכבה מעל [X6 (חוזה UI↔API)](X6-ui-api-contract.md). X6 קובע ש**טיפוס** נכון (OpenAPI=SSoT, provenance); X17 קובע ש**משטח** נכון (מקור-אמת יחיד לכל datum, שער אחד לכל החלטה, ניווט מבוסס-משימה).
|
||||
>
|
||||
> **למה.** חיים (2026-06-11): *"המערכת מסובכת מדי לתפעול."* האבחון ([`../ia-audit-redesign.md`](../ia-audit-redesign.md), #127) אימת 37 ממצאים שכולם ביטוי-UI של **G2** מופר שלא הורחב לשכבת-ה-UI. X17 מרים את G2 (מקור-אמת יחיד) ו-G10 (שערים-אנושיים) לשכבת-המשטח, ומקודד את [[feedback_operational_simplicity]] (שער/מקום/ערוץ אחד) כ-invariants אכיפים.
|
||||
>
|
||||
> **גבול קשיח (G10):** X17 מסיר משטחים/ערוצים **כפולים**, לעולם לא **שער**. כל שער-אנושי (אישור-הלכה, פתרון-הערה, אישור-לקח, בחירת-תוצאה) נשאר חובה ומפורש. "שער אחד" = מקום-אחד-להחליט, לא אפס-החלטה.
|
||||
|
||||
---
|
||||
|
||||
## INV-IA1 — בעלים-משטח-יחיד לכל datum/מונה (G2 בשכבת-UI)
|
||||
ל-aggregate/מונה נגזר-שרת יש **משטח-בעלים יחיד** שמריץ את השאילתה; משטחים אחרים **מצביעים** אליו (deep-link/pointer), ולעולם לא מריצים מונה-מתחרה client-side. *(אכיפה: מונה-הגייטים חי רק ב-`/approvals`+`['chair','pending']`; `/operations` מצביע. תופס APR-2/3, ADM-2/3.)*
|
||||
- Maintain Consistency and Adhere to Standards (Heuristic #4) — Nielsen Norman Group — https://www.nngroup.com/articles/consistency-and-standards/
|
||||
- 3 Common IA Mistakes (Low Information Scent) — Nielsen Norman Group — https://www.nngroup.com/articles/3-ia-mistakes/
|
||||
- Information Architecture: For the Web and Beyond, 4th ed. (Organization & Labeling Systems) — Rosenfeld, Morville & Arango (O'Reilly) — https://www.oreilly.com/library/view/information-architecture-4th/9781491913529/
|
||||
|
||||
## INV-IA2 — mutation מבטל כל קורא (no stale cross-surface state)
|
||||
כל mutation שמשנה ערך הנקרא במשטח אחר **חייב לבטל כל queryKey שקורא אותו** — כולל aggregators חוצי-namespace. אסור שמשטח יציג ערך תקוע אחרי שינוי במשטח אחר. *(תופס את 16 פערי-הסנכרון: CAS-1/2, APR-1/4/5/6, LRN-6/8/10, MET-1/8, ADM-2/3/5.)*
|
||||
- Query Invalidation — TanStack Query (official docs) — https://tanstack.com/query/latest/docs/framework/react/guides/query-invalidation
|
||||
- Deriving Client State from Server State — TkDodo (Dominik Dorfmeister, TanStack maintainer) — https://tkdodo.eu/blog/deriving-client-state-from-server-state
|
||||
- Visibility of System Status (Heuristic #1) — Nielsen Norman Group — https://www.nngroup.com/articles/visibility-system-status/
|
||||
|
||||
## INV-IA3 — שער-אחד / ערוץ-אחד לכל החלטה (G10/INV-LRN1 נשמרים)
|
||||
לכל החלטה-אנושית **משטח-יחיד ומסלול-כתיבה-יחיד**. אסור משטח-אישור שני או כותב-מקביל לאותה שורה. הלמידה **מנותבת דרך** העורך הקנוני, לא כותבת-במקביל. *(תופס LRN-1/2/3, MET-2/3 — "שני השערים" של חיים, ומירוץ ה-lost-update.)*
|
||||
- Preventing User Errors / Error Prevention (Heuristic #5) — Nielsen Norman Group — https://www.nngroup.com/articles/slips/
|
||||
- Do the hard work to make it simple (Government Design Principles) — GOV.UK / GDS — https://www.gov.uk/guidance/government-design-principles
|
||||
- Don't Make Me Think, Ch.5 — Omit Needless Words/Controls — Steve Krug (O'Reilly) — https://www.oreilly.com/library/view/dont-make-me/0321344758/ch05.html
|
||||
|
||||
## INV-IA4 — ניווט מבוסס-משימה, לא מבוסס-פורמט
|
||||
משטחים מאורגנים לפי **מה המשתמש עושה** (לאשר / לנטר / להגדיר / לחבר), לא לפי מקור-הנתונים הטכני (pm2 מול DB מול תורים). דלת-כניסה אחת לכל משימה. *(אכיפה: `/operations`⊇`/diagnostics` — אותו intent-ניטור; הורדת `/feedback` מהראשי. תופס D5, ADM.)*
|
||||
- Avoid Format-Based Primary Navigation — Nielsen Norman Group — https://www.nngroup.com/articles/format-based-navigation/
|
||||
- Intranet IA Methods (task-based endures over structure-based) — Nielsen Norman Group — https://www.nngroup.com/articles/intranet-ia-methods/
|
||||
- Task list pattern (one list of outstanding tasks per service) — GOV.UK Design System — https://design-system.service.gov.uk/components/task-list/
|
||||
|
||||
## INV-IA5 — סטטוס-אמיתי מגובה-צרכן
|
||||
כל מספר מוצג ממופה ל**צרכן אמיתי** ו**מקור שלם**. אסור KPI שסופר דגל-ללא-צרכן; אסור aggregate מדויק כש-partial-failure השמיט תורם (להציג חלקיות); שדה ב-response — **לרנדר או להסיר**. *(תופס LRN-1/4/5, ADM-1/6, APR-3.)*
|
||||
- Visibility of System Status (Heuristic #1) — Nielsen Norman Group — https://www.nngroup.com/articles/visibility-system-status/
|
||||
- Design with data (Government Design Principles) — GOV.UK / GDS — https://www.gov.uk/guidance/government-design-principles
|
||||
- Minimize Cognitive Load to Maximize Usability — Nielsen Norman Group — https://www.nngroup.com/articles/minimize-cognitive-load/
|
||||
|
||||
## INV-IA6 — שפת-מפעיל מובנת-מאליה (no jargon; precedence in-context)
|
||||
קופי פונה-למפעיל מתאר את **האפקט המשמעותי**, לא מזהי-משימות פנימיים (T7/T15). התנהגות-תחולה/קדימות (universal מוקדם; checklist→appeal_type) מוצגת **בהקשר** דרך progressive disclosure, לא במסמך נפרד. *(תופס MET-4/5/6/7.)*
|
||||
- Don't Make Me Think — Krug's First Law (self-evident) — Steve Krug — https://www.oreilly.com/library/view/dont-make-me/0789723107/ch02.html
|
||||
- Plain language / write for users (Design principles) — U.S. Web Design System (USWDS) — https://designsystem.digital.gov/design-principles/
|
||||
- Progressive Disclosure — Nielsen Norman Group — https://www.nngroup.com/articles/progressive-disclosure/
|
||||
|
||||
---
|
||||
|
||||
## משטח-היעד (Target IA)
|
||||
|
||||
### שלושה משטחי-intent ברמת-העל
|
||||
| משטח | intent | בעלים | כלל |
|
||||
|------|--------|-------|-----|
|
||||
| **`/approvals`** | **לאשר** (החלטה-אנושית) | תיבת-הגייטים הקנונית | המקום **היחיד** שפועלים על שער. כרטיס לכל סוג (הלכות/פסיקה-חסרה/הערות/QA) עם מונה+קישור. |
|
||||
| **`/operations`** | **לנטר** (קריאה-בלבד) | משטח-המכונה | בולע את `/diagnostics`. שירותים+תורים+סוכנים+בריאות+`halacha_backlog`. **אפס** שער נפעל כאן; מצביע ל-`/approvals`. |
|
||||
| **`/settings`** | **להגדיר** | משטח-התצורה | Paperclip/סוכנים/env/כלים/בלוקים. עריכת-env משלימה-את-עצמה (staleness+redeploy באותה שורה). |
|
||||
|
||||
### משטחי-תחום (בעלים-יחיד לכל ישות)
|
||||
| תחום | יעד |
|
||||
|------|-----|
|
||||
| **תיק** | **workspace-החלטה אחד** — block-editing + DOCX-פעיל, מחוון-מקור-אמת אחד בבעלות-המערכת, cache-slice משותף. אזור "השלמה והעברה" אחד לשערי-הסיום. |
|
||||
| **למידה** | **תיבת-אישור אחת** (לפי זוג draft↔final) · **ערוץ-כותב אחד + סטטוס "זורם-לכותב" אחד** (`review_status='approved'`) · `applied_to_skill` **מוסר** · כל artifact תלוי-בזוג (progressive disclosure). |
|
||||
| **מתודולוגיה** | **`/methodology` = העורך הקנוני היחיד** (PUT אחד; תג-מקור "ידני/מאומץ-מלמידה"); הלמידה מנותבת-דרכו ומבטלת שני-caches; explainer-תחולה inline. |
|
||||
| **פסיקה** | 3 קורפוסים **נפרדים** (גבול אמיתי, G2/INV-DIG1) אך **מתפעלים אחיד** — שם-חיפוש עקבי, תבנית-"ממתין" אחת, authority בכל-מקום. |
|
||||
|
||||
---
|
||||
|
||||
## דלתות-ספ (deltas — לאישור-יו"ר לפני יישום)
|
||||
> כל שינוי-ספ דורש ≥3 מקורות (לעיל) + אישור-יו"ר. עד אז — המלצות.
|
||||
|
||||
1. **[X6](X6-ui-api-contract.md):** להוסיף INV-UI7 (aggregate-נגזר=SSoT; mutation מבטל queryKey; אין מונה-מתחרה — מקדד INV-IA1/IA2) · INV-UI8 (שדה-response מרונדר-או-מוסר; חלקיות מוצגת — INV-IA5).
|
||||
2. **[07-learning §0.4/§0.6](07-learning.md):** שער-אישור **אחד**, טרנזקציית-כותב **אחת**, `applied_to_skill` מוסר; לקחים-מאושרים נכתבים רק דרך מסלול-המתודולוגיה (מקדד INV-IA3; מיישב את "שני-השערים" של [[feedback_operational_simplicity]]).
|
||||
3. **[00-constitution §G2 "הפרות ידועות"](00-constitution.md):** להוסיף את תאום-המתודולוגיה (`discussion_rules['universal']` נכתב ע"י PUT וגם promote — MET-2/3).
|
||||
|
||||
## הפניות-אחיות
|
||||
- [`../ia-audit-redesign.md`](../ia-audit-redesign.md) — מצב-קיים: 34 משטחים, 37 ממצאים (file:line), כיוון-יעד פר-אשכול.
|
||||
- [X6-ui-api-contract.md](X6-ui-api-contract.md) (UI1–UI6 — X17 מעליו) · [ui-audit.md](ui-audit.md) (ממצאי-קוד פר-רכיב — שכבה מתחת).
|
||||
- [00-constitution.md](00-constitution.md) — [G2](00-constitution.md) (מקור-אמת יחיד) · G10 (שערים-אנושיים) — X17 מרים אותם לשכבת-המשטח.
|
||||
Reference in New Issue
Block a user