📚 Docs / Architecture — Lawyer Assistant

Architecture — Lawyer Assistant

A local-first legal research desktop app: an Electron shell that launches a Vite/React frontend and a Python FastAPI backend, with a RAG (retrieval- augmented generation) engine over legal documents plus a compliance "playbook scan" feature. The app's UI, prompts and OCR are English, and retrieval itself is language-agnostic (the BGE-M3 embedding model handles many languages, so non-English source text can still be searched).

1. Big picture

┌─────────────────────────────────────────────────────────────────────┐
│                    ELECTRON SHELL (frontend/electron/)                │
│  • Creates the BrowserWindow                                        │
│  • Starts Python backend (auto .venv, port 8765)                    │
│  • Starts Vite dev server (port 5173, dev mode only)                │
│  • Kills stale processes on 8765/5173 at startup                    │
│  • IPC: window controls, python:port, python:health                 │
└───────────────┬─────────────────────────────────────────────────────┘
                │ loads
┌───────────────▼─────────────────────────────────────────────────────┐
│                      FRONTEND (frontend/, Vite+React+TS)             │
│  • ChatArea, InputBar, SourcesPanel, ScanPanel, PipelineEditor      │
│  • Zustand stores (chat, persist 'freebuff-chat-storage')           │
│  • Services layer → HTTP + SSE to backend (http://localhost:8765)   │
└───────────────┬─────────────────────────────────────────────────────┘
                │ HTTP + SSE (text/event-stream)
┌───────────────▼─────────────────────────────────────────────────────┐
│                      BACKEND (backend/main.py, FastAPI)              │
│  • /api/chat/stream (SSE), /api/upload, /api/chat/resume            │
│  • /api/playbooks, /api/scan[/stream|/upload], /api/flags           │
│  • Warmup: preloads BGE-M3, BGE-Reranker, Ollama LLM on startup     │
└───────────────┬─────────────────────────────────────────────────────┘
                │
┌───────────────▼─────────────────────────────────────────────────────┐
│            LEGAL RETRIEVAL ENGINE (backend/legal_retrieval/)         │
│  • router_intent.py / router.py  (AI orchestration)                 │
│  • tools.py: search_documents, verify_relevance, scan_document,     │
│             ingest_file                                             │
│  • retrieval.py: dense (ChromaDB) + sparse (BM25) + rerank          │
│  • playbook/: compliance scanner (classifier → rules → flags)       │
│  • llm.py → Ollama (localhost:11434)                                │
└─────────────────────────────────────────────────────────────────────┘

Local-first: models (BGE-M3 embeddings, BGE-Reranker-v2-M3) live in models/; the vector store lives in data/chroma_db; LLM inference is Ollama running locally on http://localhost:11434. No cloud dependency.


2. Ports & processes

PortOwnerPurpose
8765backend/main.py (uvicorn)FastAPI "Lawyer Assistant API" — the frontend's only backend
5173Vite dev serverServes the React app in development (npm run dev)
11434OllamaLocal LLM inference (ChatOllama / OllamaLLM)

The Electron main process kills anything listening on 8765/5173 at startup to avoid EADDRINUSE, then starts the Python backend (auto-creating/using .venv) and, in dev mode, the Vite server.


3. Runtime modes

ModeDevProduction
Electron loadmainWindow.loadURL(viteUrl) (Vite dev server)mainWindow.loadFile(frontend/dist/index.html)
Backendspawned by Electron (python main.py)bundled into extraResources (backend/**/*.py + requirements)
Run commandnpm run dev (root → runs Electron, which boots backend + Vite itself)npm run build then npm run package:win/mac/linux

4. The three AI flows

4a. Chat / RAG (search → answer)

/api/chat/stream → intent router → tools (search_documents, verify_relevance) → retrieval (dense+sparse+rerank) → LLM answer with citations → SSE events streamed to the UI. Details: BACKEND.md.

4b. Compliance scan (document → flags)

/api/scan/stream (or /api/scan/upload for new files) → chunk → classify clause type (embedding classifier) → check playbook rules → emit flags → persist to SQLite. Details: BACKEND.md → "Playbook scan".

4c. Pipeline editor (visual config → backend reconfiguration)

A ReactFlow canvas that visualizes the pipeline as nodes (intent, planner, dense, sparse, rerank, ingest, scan, answer) with removable/toggleable sub-nodes, localStorage persistence, and JSON export/import. Since the /api/pipeline/config endpoint, the exported layout also reconfigures the Python backend at runtime (rerank on/off, search mode + dense/sparse fusion weights, top_k overrides) via backend/legal_retrieval/pipeline_config.py; RetrievalPipeline reads the active config on construction. Details: PIPELINE_EDITOR.md, PIPELINE_JSON.md §10.


5. Key architectural decisions

Questions, answered

Short, self-contained answers about this guide.

How is the app structured?

An Electron shell hosts a Vite/React frontend and a FastAPI backend (port 8765). The backend runs a RAG pipeline — BGE-M3 embeddings, ChromaDB vector store, BM25 index, and BGE-Reranker — over a local Ollama LLM, with optional cloud API providers.

Which ports does the app use?

The backend binds to 8765, the Vite dev server to 5173, and the launcher setup page to 8770. All are localhost-only — nothing is exposed to the network.

What are the runtime modes?

The app supports full desktop mode and split dev modes (backend-only, frontend-only). The architecture doc maps each component to its source folder under backend/ and frontend/.