This repository has been archived on 2026-07-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
SmartAssistant/ARCHITECTURE.md
T
chaim 7811943178 feat: place AI-generated documents in the CaseFiles case folder (P7)
GenericTemplateGenerator and FreeDocumentGenerator now, when CaseFilesCore is
installed (soft-detected), set the generated Document's folderId to the case
"מסמכים" folder via CaseFolderService so it shows in the CaseDocs panel.
Existing Case link + NetworkStorage upload unchanged.

Verified on dev (P7_OK): php -l clean on both generators; relate/find junction
consistency confirmed; folder placement works.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 10:53:24 +00:00

63 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SmartAssistant — Architecture (developer reference)
> Internal developer doc. Not shipped to clients. Customer overview: `README.md`. Security/dead-code findings: `_AUDIT/SmartAssistant/findings.md`.
**Module:** `SmartAssistant` · **Client module:** `smart-assistant` · **Load order:** 37 · **Requires:** EspoCRM ≥ 8.0.0, PHP ≥ 8.1
## What it is
A floating AI legal assistant. A chat widget (case mode / office mode) sends the user message plus rich context (case data, case memory, behavioral rules, prompt sections, learned skills, user profile) to the **shira-hermes** FastAPI backend via a webhook; shira returns response text + a list of tools, which `ActionExecutor` runs against the CRM (task/call/meeting CRUD, status changes, document + memory ops, rule saving), optionally looping tool results back to shira (agentic loop, max 3). Also computes office-wide alerts. Owns 6 entities (AssistantPrompt, AssistantRule, AssistantSkill, CaseMemory, UserProfile, AssistantConversation) and extends `Note` with 3 timeline note types.
## File-by-file
### Lifecycle
| File | Purpose |
|---|---|
| `scripts/AfterInstall.php` | Idempotently seeds 7 default AssistantPrompt sections (`skipAll`; admin edits win). No uninstall script (seeded entities persist). |
### Controllers
| File | Purpose |
|---|---|
| `Controllers/SmartAssistant.php` | ~30 actions: chat, execute, executeTool, alerts, summary, history, conversations, caseMemory, saveMemory, document read/analyze/upload/generate/rename/list/browse/write/move. (S1S6 — **ACL fixed 2026-06-20**: `assertCaseAccess()` on chat/caseMemory/saveMemory/history; document-read endpoints require `caseId` + ACL + `isPathWithinCase()` containment.) |
| `Controllers/{AssistantRule,AssistantPrompt,AssistantSkill,CaseMemory,UserProfile}.php` | Thin Record CRUD. **AssistantRule has no owner field — S5.** |
### Services
| File | Purpose |
|---|---|
| `SmartAssistantService.php` | Orchestrator: webhook call, agentic loop, conversation persistence, stream notes (SmartRequest/Response/Action), office drill-down. (**fixed 2026-06-20**: `detectDrillDown` ACL-filters matched cases (S6); dead static `$conversations` removed (D1).) Forwards espocrmApiKey — S9 still open. |
| `ConversationRepository.php` | File-based conversation JSON under `data/conversations/`. |
| `ActionExecutor.php` | Executes all shira tools. (**ACL fixed 2026-06-20**: resolves the acting user in `execute()`; central `CASE_TOOL_ACCESS` record-ACL gate for case-bound tools (S1); `assertEntityAccess(...,'delete')` on every delete tool (S4); `save_rule` admin-only (S5); plugin tools with a caseId require case edit — also closes LegalAssistance S1.) |
| `CaseContextBuilder.php` / `OfficeContextBuilder.php` | Build case / office context dicts. **Case context IDOR S3.** |
| `CaseMemoryContextProvider.php`, `AssistantRuleContextProvider.php`, `AssistantPromptContextProvider.php`, `AssistantSkillContextProvider.php`, `UserProfileContextProvider.php` | Load memories/rules/prompts/skills/profile into the prompt. |
| `CaseMemoryService.php` | CaseMemory CRUD (category/importance/pinned). **IDOR S3.** |
| `DocumentAnalyzer.php` | Text extraction/analysis; uses NetworkStorageIntegration NetworkDocumentService. (**fixed 2026-06-20**: added `isPathWithinCase()` containment helper the controller calls before any read — S2.) |
| `CaseFolderManager.php` | Write/rename/move constrained to the case folder (`resolveSafePath`/`sanitizeRelSegments` — safe). |
| `GenericTemplateGenerator.php` / `FreeDocumentGenerator.php` | Template-based / free-form document generation. |
| `AlertCalculator.php` | Office alerts (inactive cases, overdue tasks, hearings without prep, unassigned new cases, deadlines). |
### Hooks
| File | Trigger |
|---|---|
| `Hooks/Case/CaseFieldChangeMemory.php` | afterSave — auto-seed CaseMemory on status/judge/court/next-hearing change. |
| `Hooks/Meeting/HearingScheduledMemory.php` | afterSave — memory when a hearing Meeting is created. |
### Resources / client
| Path | Purpose |
|---|---|
| `entityDefs/{AssistantPrompt,AssistantRule,AssistantSkill,CaseMemory,UserProfile,Note,Case}.json` | 6 entities + Note.type extension + Case.caseMemories link. **AssistantRule/UserProfile ACL — S5/S7.** |
| `integrations/SmartAssistant.json` | webhookUrl, apiKey, espocrmApiKey, thresholds, agenticLoop. **Keys are varchar — S8.** |
| `routes.json` (12), `clientDefs/*`, `scopes/*`, `layouts/*`, `dashlets/SmartAssistant.json`, `i18n/{en_US,fa_IR}/*`, `data/default-prompts.json` | Routes, UI, ACL, dashlet, translations, seed prompts. |
| `client/.../src/views/floating-chat.js` | Main chat widget (history, memory browser, mode badge). escape-then-markdown — XSS-safe. |
| `client/.../src/views/dashlets/smart-assistant.js` | Alerts card. **Unescaped caseId href S10.** |
| `client/.../src/views/{case/modals/add-memory,fields/prompt-editor,site/navbar}.js`, `stream/notes/smart-{request,response,action}.js` | Memory modal, prompt editor, navbar inject, timeline note item views. |
## Dependencies
- **NetworkStorageIntegration (hard):** DocumentAnalyzer document ops.
- **shira-hermes (external, hard):** webhook (Integration record `SmartAssistant`). No chat without it.
- **KnowledgeBase → SmartAssistant (REVERSE, critical):** KnowledgeBase reuses this extension's Integration record. **Do not uninstall SmartAssistant while KnowledgeBase is installed.**
- **LegalCrm (soft):** Note.type extension.
## Post-install gotchas
- Configure the `SmartAssistant` Integration (webhookUrl + apiKey + espocrmApiKey) — scope the espocrmApiKey to a minimal API user (S9).
- Known deploy gotchas: a backup-in-modules folder breaks hooks; AfterInstall needs `skipAll`; new role entries need api-key role grant.
- shira-hermes `/opt/data` must be a named volume (else skills/profiles/cases wiped on redeploy).