# SmartAssistant v1.0.3 — סיכום מנהלים לפריסה בפיתוח

**תאריך:** 2026-03-31
**גרסה:** 1.0.3 | **תאריך שחרור:** 2026-03-29
**סביבת יעד:** EspoCRM Development (https://espocrm.dev.marcus-law.co.il)
**מחבר:** klear | **דרישות:** EspoCRM >= 8.0.0, PHP >= 8.1

---

## 1. תיאור כללי

SmartAssistant הוא מודול עוזר AI מאוחד למשרד עורכי דין.

המודול מספק:
- **ממשק צ'אט צף** (Floating Action Button) בכל דפי המערכת
- **מצב משרד** — סקירה כללית, התראות, סטטיסטיקות עומס עבודה
- **מצב תיק** — סיוע מעמיק בתיק ספציפי עם הקשר מלא
- **מערכת זיכרון תיק** (CaseMemory) — מאגר ידע מובנה לכל תיק ב-7 קטגוריות
- **ביצוע פעולות באישור** — יצירת משימות, פתקים, דיונים, שינוי סטטוס
- **אינטגרציה עם Stream** — כל אינטראקציה מופיעה בציר הזמן של התיק
- **התראות בסרגל ניווט** — תיקים לא פעילים, משימות באיחור, דיונים קרובים

---

## 2. מה בוצע

### 2.1 Backend (PHP) — 16 קבצים

| רכיב | קובץ | תפקיד |
|-------|------|--------|
| Controller | `Controllers/SmartAssistant.php` | 10 נקודות קצה API (chat, execute, summary, alerts, history, conversations, conversationMessages, searchHistory, caseMemory, saveMemory) |
| שירות ראשי | `Services/SmartAssistantService.php` | תזמור מלא: בניית הקשר → קריאת webhook → טיפול בפעולות → שמירת שיחה |
| בונה הקשר תיק | `Services/CaseContextBuilder.php` | אוסף: נתוני תיק, אנשי קשר, משימות פתוחות, דיונים קרובים, פתקים אחרונים, זיכרון |
| בונה הקשר משרד | `Services/OfficeContextBuilder.php` | סטטיסטיקות כלליות, התראות, עומס עבודה לפי משתמש, drill-down לתיקים |
| מחשבון התראות | `Services/AlertCalculator.php` | 6 סוגי התראות: תיקים לא פעילים (14/30 יום), משימות באיחור, דיונים קרובים, תיקים ללא שיוך, משימות בעדיפות גבוהה |
| מבצע פעולות | `Services/ActionExecutor.php` | 8 כלים: create_task, add_note, change_status, create_meeting, schedule_hearing, list_documents, analyze_document, save_memory, rename_document |
| שירות זיכרון | `Services/CaseMemoryService.php` | CRUD מלא לאנטיטי CaseMemory |
| ספק הקשר זיכרון | `Services/CaseMemoryContextProvider.php` | הזרקת זיכרון מוצמד/חשוב להקשר AI |
| מאגר שיחות | `Services/ConversationRepository.php` | שמירה ואחזור שיחות ב-AssistantConversation |
| מנתח מסמכים | `Services/DocumentAnalyzer.php` | סריקת מסמכים דרך FileStorage |
| Hook - שינוי תיק | `Hooks/Case/CaseFieldChangeMemory.php` | זיכרון אוטומטי בשינוי: סטטוס, שופט, בית משפט, מועד דיון |
| Hook - דיון | `Hooks/Meeting/HearingScheduledMemory.php` | זיכרון אוטומטי בקביעת דיון חדש |
| FileStorage | `Classes/FileStorage/*` | 4 קבצים: Interface, Factory, WebDav, NextCloud |

### 2.2 Frontend (JavaScript) — 9 קבצים

| רכיב | תפקיד |
|-------|--------|
| `floating-chat.js` | ממשק צ'אט צף (~1500 שורות): שליחת הודעות, היסטוריה, זיכרון, אישור/דחיית פעולות, עיצוב RTL, Material Design |
| `site/navbar.js` | אייקון התראות בסרגל ניווט עם badge מספרי |
| `dashlets/smart-assistant.js` | דשלט לדשבורד: סיכום מדדים + התראות אחרונות |
| `dashlets/options/smart-assistant.js` | הגדרות דשלט |
| `case/modals/add-memory.js` | מודל להוספת זיכרון ידנית לתיק |
| `stream/notes/smart-request.js` | תצוגת הודעת משתמש ב-Stream |
| `stream/notes/smart-response.js` | תצוגת תשובת עוזר ב-Stream |
| `stream/notes/smart-action.js` | תצוגת פעולה שבוצעה ב-Stream |

### 2.3 מטא-נתונים וקונפיגורציה — 17 קבצי JSON

- **routes.json** — 10 נתיבי API
- **module.json** — רישום מודול עם clientModule
- **entityDefs/** — CaseMemory (אנטיטי חדש, 15 שדות, 4 אינדקסים), Case (שדה cNextHearing), Note (סוגי stream חדשים)
- **scopes/CaseMemory.json** — הגדרות scope
- **layouts/CaseMemory/** — 4 layouts (list, detail, listSmall, detailSmall)
- **dashlets/SmartAssistant.json** — הגדרת דשלט
- **integrations/SmartAssistant.json** — 6 שדות הגדרה (webhookUrl, apiKey, maxMessagesPerHour, inactivityWarningDays, inactivityCriticalDays, upcomingHearingDays)
- **clientDefs/App.json** — רישום navbar

### 2.4 תרגומים — 10 קבצים

- **en_US** — 5 קבצי תרגום (SmartAssistant, CaseMemory, Case, Global, Integration)
- **fa_IR** — 5 קבצי תרגום מקבילים (עברית/פרסית)

### 2.5 בנייה והפצה

- **build.sh** — סקריפט בנייה: קורא גרסה מ-manifest.json, מעדכן README, יוצר ZIP
- **composer.json** — הגדרת חבילה ל-Composer Registry
- **4 גרסאות ZIP** — 1.0.0, 1.0.1, 1.0.2, 1.0.3

---

## 3. היסטוריית גרסאות ותיקוני באגים

### v1.0.0 — `a148e0f`
- **פיצ'ר ראשוני** — מודול SmartAssistant מלא עם case memory

### v1.0.0 → v1.0.1 — תיקונים
| Commit | תקלה | תיקון |
|--------|-------|--------|
| `0cdbf6d` | דשלט ירש מ-DashletView שלא קיים בגרסאות חדשות | שונה ל-base View + הוספת getTitle() |
| `ffd966a` | לא היה composer.json לפרסום אוטומטי | נוסף composer.json |
| `bd1cd17` | גרסה ב-README לא מתעדכנת אוטומטית | build.sh מעדכן README |
| `95ca8a0` | חסר תיעוד מקיף | נוסף README מלא בעברית |
| `fbe4f82` | נתיבי client לא תואמים לפורמט מודולים של EspoCRM | מיגרציה לנתיבי מודול תקניים |

### v1.0.1 → v1.0.2 — `f380542`
| תקלה | תיקון |
|-------|--------|
| נתיבי CSS ו-script שגויים ב-app/client.json metadata | תיקון הנתיבים ל-format הנכון |

### v1.0.2 → v1.0.3 — `d5c8a60`
| תקלה | תיקון |
|-------|--------|
| EspoCRM לא מצליח לרזולב templates בצד לקוח כי חסר clientModule | הוספת `clientModule` ל-module.json |

### סיכום תקלות שנמצאו ותוקנו

| # | תקלה | חומרה | סטטוס |
|---|-------|--------|--------|
| 1 | דשלט ירש מ-class לא קיים | גבוהה | תוקן v1.0.1 |
| 2 | נתיבי client לא תקניים לפורמט מודולים | גבוהה | תוקן v1.0.1 |
| 3 | נתיבי CSS/script שגויים ב-metadata | בינונית | תוקן v1.0.2 |
| 4 | חסר clientModule לרזולוציית templates | גבוהה | תוקן v1.0.3 |

---

## 4. מה נבדק

### נבדק ידנית (על סמך תיקוני הבאגים)
- רישום מודול וטעינת client-side assets
- תצוגת דשלט בדשבורד
- רזולוציית templates בצד לקוח
- נתיבי metadata (CSS, scripts)

### לא נבדק (אין קבצי טסט בפרויקט)
- **אין בדיקות יחידה (unit tests)** לקוד PHP
- **אין בדיקות אינטגרציה** ל-API endpoints
- **אין בדיקות E2E** לממשק הצ'אט
- **אין CI/CD pipeline** (אין GitHub Actions / Gitea Actions)

---

## 5. דרישות קדם לפריסה בפיתוח

| דרישה | סטטוס | פירוט |
|--------|--------|--------|
| EspoCRM >= 8.0.0 | לאמת | לוודא גרסה בסביבת dev |
| PHP >= 8.1 | לאמת | לוודא גרסה בשרת |
| Webhook URL | **נדרש הגדרה** | יש להגדיר n8n workflow שיקבל את הפניות |
| API Key | אופציונלי | לאימות webhook |
| AssistantConversation entity | לאמת | נדרש שהאנטיטי קיים |
| WebDAV/NextCloud | אופציונלי | רק לפיצ'ר ניתוח מסמכים |

---

## 6. מה נשאר לעשות

### קריטי לפני פריסה
| # | משימה | עדיפות |
|---|--------|---------|
| 1 | **הגדרת n8n workflow** לקבלת webhook מהעוזר (chat endpoint) | קריטי |
| 2 | **בדיקת תאימות** עם גרסת EspoCRM בסביבת dev | קריטי |
| 3 | **לוודא שאין שאריות** של מודולים ישנים בסביבת dev | קריטי |
| 4 | **הגדרת Integration** — webhookUrl + apiKey ב-Admin > Integrations | קריטי |
| 5 | **בדיקה שאנטיטי AssistantConversation קיים** או שצריך ליצור אותו | קריטי |

### חשוב אחרי פריסה
| # | משימה | עדיפות |
|---|--------|---------|
| 6 | **בדיקות ידניות מקיפות** — צ'אט במצב משרד ומצב תיק | גבוהה |
| 7 | **בדיקת פעולות** — create_task, add_note, schedule_hearing, change_status | גבוהה |
| 8 | **בדיקת hooks** — שינוי סטטוס תיק → זיכרון אוטומטי | גבוהה |
| 9 | **בדיקת התראות** — navbar badge + דשלט | בינונית |
| 10 | **בדיקת היסטוריה** — שמירה ואחזור שיחות, חיפוש | בינונית |

### שיפורים עתידיים
| # | משימה | עדיפות |
|---|--------|---------|
| 11 | כתיבת בדיקות יחידה ל-PHP | בינונית |
| 12 | הוספת CI/CD pipeline (Gitea Actions) | בינונית |
| 13 | הוספת תרגום עברי (he_IL) — כרגע en_US + fa_IR בלבד | בינונית |
| 14 | Rate limiting בצד client (כרגע רק בצד server) | נמוכה |
| 15 | הצפנת שיחות | נמוכה |

---

## 7. תיעוד מפורט של הקוד והקבצים

### 7.1 ארכיטקטורה כללית

```
┌─────────────────────────────────────────────────┐
│                   Frontend (JS)                  │
│  floating-chat.js ←→ navbar.js ←→ dashlet.js    │
│       │              │              │            │
│  [צ'אט צף]    [התראות navbar]  [דשלט דשבורד]     │
└───────────────────────┬─────────────────────────┘
                        │ REST API (10 endpoints)
┌───────────────────────┴─────────────────────────┐
│              Controller/SmartAssistant.php        │
│  chat | execute | summary | alerts | history ... │
└───────────────────────┬─────────────────────────┘
                        │
┌───────────────────────┴─────────────────────────┐
│           SmartAssistantService.php               │
│  תזמור: הקשר → webhook → פעולות → שמירה          │
├──────────┬──────────┬──────────┬─────────────────┤
│ Context  │ Action   │ Memory   │ Conversation    │
│ Builders │ Executor │ Service  │ Repository      │
├──────────┴──────────┴──────────┴─────────────────┤
│  CaseContext  │ OfficeContext │ AlertCalculator   │
│  Builder      │ Builder      │                   │
└───────────────┴──────────────┴───────────────────┘
                        │
              ┌─────────┴──────────┐
              │   External n8n     │
              │   Webhook (AI)     │
              └────────────────────┘
```

### 7.2 זרימת צ'אט (Chat Flow)

```
1. משתמש שולח הודעה ← floating-chat.js
2. POST /SmartAssistant/action/chat { message, caseId?, conversationId }
3. Controller → SmartAssistantService::chat()
4. בניית הקשר:
   ├─ מצב תיק → CaseContextBuilder (נתוני תיק + אנשי קשר + משימות + דיונים + זיכרון)
   └─ מצב משרד → OfficeContextBuilder (סטטיסטיקות + התראות)
5. קריאת webhook חיצוני (n8n) עם: message + context + history
6. קבלת תשובה: { text, actions[] }
7. פעולות מיידיות (list_documents, save_memory) → ביצוע אוטומטי
8. פעולות הדורשות אישור → שמירה + החזרה למשתמש
9. שמירת שיחה ב-ConversationRepository
10. שמירת הודעות ב-Stream (smart-request + smart-response notes)
```

### 7.3 פירוט קבצי Backend

#### `Controllers/SmartAssistant.php` (168 שורות)
- **actionChat()** — מקבל message, caseId, conversationId. בודק ACL ל-Case. קורא ל-SmartAssistantService::chat()
- **actionExecute()** — מקבל actionId, conversationId. מבצע פעולה שאושרה
- **actionSummary()** — מחזיר סיכום משרדי + התראות
- **actionAlerts()** — רשימת התראות מלאה
- **actionHistory()** — היסטוריית שיחות (לפי caseId או אחרונה)
- **actionConversations()** — רשימת שיחות אחרונות
- **actionConversationMessages()** — הודעות שיחה ספציפית
- **actionSearchHistory()** — חיפוש חופשי בשיחות
- **actionCaseMemory()** — זיכרון תיק לפי קטגוריה
- **actionSaveMemory()** — שמירת זיכרון ידנית

#### `Services/SmartAssistantService.php` (~500 שורות)
הקובץ המרכזי ביותר. אחראי על:
- **chat()** — הזרימה המלאה: בניית הקשר, קריאת webhook, עיבוד פעולות, שמירת שיחה
- **callWebhook()** — קריאת CURL ל-n8n עם timeout, headers (X-Api-Key), JSON payload
- **processActions()** — מיון פעולות: מיידיות vs. דורשות אישור
- **executeAction()** — ביצוע פעולה שאושרה דרך ActionExecutor
- **getSummary()** / **getAlerts()** — מצב משרד
- **getConversations()** / **getHistory()** / **searchHistory()** — ניהול שיחות

#### `Services/CaseContextBuilder.php` (~150 שורות)
בונה הקשר עשיר לתיק:
```php
[
  'case' => [...],           // שדות תיק מרכזיים
  'contacts' => [...],       // אנשי קשר מקושרים
  'openTasks' => [...],      // משימות פתוחות (עד 10)
  'upcomingMeetings' => [...], // דיונים קרובים (עד 5)
  'recentNotes' => [...],    // פתקים אחרונים (עד 10)
  'memories' => [...],       // זיכרון מוצמד + חשוב
  'stats' => [...]           // מספרי סיכום
]
```

#### `Services/OfficeContextBuilder.php` (~80 שורות)
בונה סיכום משרדי:
```php
[
  'totalActiveCases' => int,
  'casesByStatus' => [...],
  'overdueTasks' => int,
  'upcomingHearings' => int,
  'userWorkload' => [...],   // עומס לפי משתמש
  'alerts' => [...]
]
```

#### `Services/ActionExecutor.php` (~250 שורות)
מבצע 8 סוגי פעולות:

| כלי | פרמטרים | פעולה |
|------|----------|--------|
| `create_task` | name, dateEnd, priority, description | יצירת Task מקושר לתיק |
| `add_note` | text | הוספת Post ב-Stream של התיק |
| `change_status` | status | שינוי סטטוס (עם validation מול enum) |
| `create_meeting` | name, dateStart, dateEnd, description | יצירת Meeting |
| `schedule_hearing` | date, description | עדכון cNextHearing + יצירת Meeting |
| `list_documents` | — | רשימת מסמכים (read-only, ללא אישור) |
| `analyze_document` | documentId | ניתוח מסמך דרך DocumentAnalyzer |
| `save_memory` | name, content, category, importance | שמירת CaseMemory (ללא אישור) |
| `rename_document` | documentId, newName | שינוי שם קובץ |

#### `Services/AlertCalculator.php` (~200 שורות)
6 סוגי התראות:

| סוג | לוגיקה | חומרה |
|------|--------|--------|
| תיק לא פעיל (אזהרה) | modifiedAt < now - 14 יום | warning |
| תיק לא פעיל (קריטי) | modifiedAt < now - 30 יום | critical |
| משימה באיחור | dateEnd < now, status != Completed | critical |
| דיון קרוב | dateStart < now + 7 ימים | warning |
| תיק ללא שיוך | status = New, assignedUserId = null | warning |
| משימה בעדיפות גבוהה | priority = Urgent, dateEnd < now + 5 ימים | warning |

#### `Services/CaseMemoryService.php` (106 שורות)
CRUD פשוט:
- **getMemories()** — לפי caseId, עם סינון אופציונלי לפי category
- **saveMemory()** — יצירת רשומת CaseMemory
- **updateMemory()** — עדכון
- **deleteMemory()** — מחיקה רכה

#### `Services/CaseMemoryContextProvider.php`
מזריק זיכרון להקשר AI:
- זיכרון מוצמד (isPinned = true)
- זיכרון בחשיבות high/critical
- ממוין לפי importance DESC, modifiedAt DESC

#### `Services/ConversationRepository.php` (~120 שורות)
- **save()** — שמירת שיחה באנטיטי AssistantConversation
- **getHistory()** — אחזור לפי caseId או אחרון
- **getConversations()** — רשימה ממוינת (עד limit)
- **getMessages()** — הודעות שיחה ספציפית
- **search()** — חיפוש חופשי בתוכן

#### Hooks
- **CaseFieldChangeMemory** — afterSave hook על Case. בודק אם שדות key השתנו (status, cJudge, cCourt, cNextHearing). אם כן, יוצר CaseMemory אוטומטי מסוג `auto` בקטגוריה המתאימה.
- **HearingScheduledMemory** — afterSave hook על Meeting. אם סוג Meeting = "Hearing", יוצר CaseMemory בקטגוריה timeline.

### 7.4 פירוט קבצי Frontend

#### `floating-chat.js` (~1500 שורות)
הקובץ הגדול ביותר. View יחיד שמנהל:
- **תצוגת צ'אט** — קלט הודעה, בועות הודעות (משתמש/עוזר), פעולות בהמתנה
- **תצוגת היסטוריה** — רשימת שיחות קודמות, טעינת שיחה
- **תצוגת זיכרון** — tabs לפי קטגוריה, הוספה/מחיקה/הצמדה
- **RTL layout** — כל ה-CSS מותאם לעברית
- **עיצוב Material Design** — צבע ראשי #5c6bc0 (אינדיגו), אנימציות slide-up
- **רספונסיבי** — breakpoint ב-480px למובייל
- **Inline CSS** — כל הסגנונות מוטמעים בקובץ (לא CSS חיצוני)

#### `site/navbar.js`
- מרחיב את navbar הרגיל של EspoCRM
- מוסיף אייקון התראות עם badge מספרי
- קורא ל-GET /SmartAssistant/action/alerts ומציג ספירה
- רענון אוטומטי כל X דקות

#### `dashlets/smart-assistant.js`
- דשלט לדשבורד הראשי
- מציג: סה"כ תיקים פעילים, משימות באיחור, דיונים קרובים
- רשימת 5 התראות אחרונות
- ACL scope = Case

#### Stream Notes (3 קבצים)
- **smart-request.js** — מציג הודעת משתמש עם אייקון שאלה
- **smart-response.js** — מציג תשובת עוזר עם markdown rendering
- **smart-action.js** — מציג פעולה שבוצעה עם סטטוס (approved/rejected/executed)

#### `case/modals/add-memory.js`
- מודל Espo.Views.Modal סטנדרטי
- שדות: name, category (dropdown), content (textarea), importance (dropdown)
- POST ל-/SmartAssistant/action/saveMemory

### 7.5 אנטיטי CaseMemory — מבנה מלא

```
שדות:
├── name (varchar, required) — כותרת הזיכרון
├── case (link → Case, required) — תיק משויך
├── category (enum) — key_facts | strategy | decisions | contacts_notes | timeline | documents_notes | billing_notes
├── content (text, required) — תוכן מלא
├── source (enum, readOnly) — manual | assistant | auto
├── importance (enum) — low | normal | high | critical
├── isPinned (bool) — הצמדה לגישה מהירה
├── isArchived (bool) — הסתרת רשומות ישנות
├── sourceEntityType (varchar, readOnly) — סוג מקור (למעקב)
├── sourceEntityId (varchar, readOnly) — ID מקור
├── assignedUser (link → User)
├── teams (linkMultiple → Team)
├── createdAt, modifiedAt (datetime)
└── createdBy, modifiedBy (link → User)

אינדקסים:
├── caseId + deleted
├── caseId + category + deleted
├── caseId + isPinned + deleted
└── importance + deleted
```

### 7.6 הגדרות אינטגרציה

**Admin > Integrations > Smart Assistant:**

| שדה | סוג | ברירת מחדל | תיאור |
|------|------|------------|--------|
| webhookUrl | url | — | כתובת webhook (n8n) |
| apiKey | varchar(255) | — | מפתח אימות, נשלח כ-X-Api-Key header |
| maxMessagesPerHour | int | 30 | הגבלת קצב |
| inactivityWarningDays | int | 14 | סף אזהרה לחוסר פעילות |
| inactivityCriticalDays | int | 30 | סף קריטי |
| upcomingHearingDays | int | 7 | חלון דיונים קרובים |

### 7.7 פורמט Webhook

**Request (נשלח ל-n8n):**
```json
{
  "message": "מה המצב של תיק כהן?",
  "context": {
    "case": { "name": "כהן נ' לוי", "status": "Active", ... },
    "contacts": [...],
    "openTasks": [...],
    "memories": [...]
  },
  "conversationId": "conv_abc123",
  "conversationHistory": [
    { "role": "user", "content": "..." },
    { "role": "assistant", "content": "..." }
  ],
  "mode": "case"
}
```

**Response (נדרש מ-n8n):**
```json
{
  "text": "תיק כהן פעיל. יש 3 משימות פתוחות ודיון ב-15 באפריל.",
  "actions": [
    {
      "tool": "create_task",
      "params": { "name": "הכנת סיכומים לדיון", "dateEnd": "2026-04-14" },
      "actionId": "action_xyz789",
      "displayText": "יצירת משימה: הכנת סיכומים לדיון"
    }
  ]
}
```

---

## 8. סיכום מוכנות לפריסה

| קריטריון | סטטוס | הערות |
|-----------|--------|--------|
| קוד backend | מוכן | 16 קבצי PHP, ארכיטקטורה נקייה |
| קוד frontend | מוכן | 9 קבצי JS, עיצוב RTL |
| מטא-נתונים | מוכן | תוקן ב-v1.0.1-1.0.3 |
| תרגומים | חלקי | en_US + fa_IR, חסר he_IL ייעודי |
| קובץ התקנה | מוכן | SmartAssistant-1.0.3.zip |
| n8n workflow | **חסר** | צריך לבנות workflow שיטפל ב-chat |
| בדיקות אוטומטיות | **אין** | אין unit/integration/E2E tests |
| CI/CD | **אין** | אין pipeline |
| תיעוד | מוכן | README מקיף בעברית |

**המלצה:** המודול מוכן טכנית לפריסה בסביבת פיתוח. יש להגדיר webhook URL (n8n workflow) לפני שהצ'אט יהיה פונקציונלי. מומלץ לבצע בדיקות ידניות מקיפות לאחר ההתקנה.
