Commit Graph

58 Commits

Author SHA1 Message Date
726498126d Add Track Changes architecture for draft revisions (CMP + CMPA)
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m29s
Fixes critical bug in 1033-25: user-uploaded עריכה-*.docx files were
orphaned on disk while exports kept rebuilding from stale DB blocks.

New architecture:
- User-uploaded DOCX becomes the source of truth (cases.active_draft_path)
- System edits via XML surgery with real Word <w:ins>/<w:del> revisions
- User can Accept/Reject each change from within Word

Components:
- docx_reviser.py: XML surgery for Track Changes (15 tests)
- docx_retrofit.py: retroactive bookmark injection with Hebrew marker
  detection + heading heuristic (9 tests)
- docx_exporter.py: emits bookmarks around each of the 12 blocks
- 3 new MCP tools: apply_user_edit, list_bookmarks, revise_draft
- 4 new/updated endpoints: upload (auto-registers active draft),
  /exports/revise, /exports/bookmarks, /exports/{filename}/retrofit,
  /active-draft
- DB migration: cases.active_draft_path column
- UI: correct banner using real v-numbers, "מקור האמת" badge,
  detailed upload toast with bookmarks_added/missing_blocks
- agents: legal-exporter (3 export modes), legal-ceo (stage G for
  revision handling), legal-writer (revision mode)

Multi-tenancy:
- Works for both CMP (1xxx cases) and CMPA (8xxx/9xxx cases)
- New revise-draft skill added to both companies
- deploy-track-changes.sh syncs skills CMP ↔ CMPA
- retrofit_case.py: one-off retrofit of existing files

Tests: 34 passing (15 reviser + 9 retrofit + 4 exporter bookmarks + 6 e2e)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 18:49:30 +00:00
d7a79cf5ec Show per-case agent status instead of global — fix Hebrew translation of "running"
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 3m41s
Agent status widget now checks heartbeat_runs + wakeup_requests to determine
if an agent is running on *this* case. Agents running on other cases show as idle.
Added "running" to STATUS_DOT/STATUS_LABEL maps so it displays in Hebrew.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 14:47:42 +00:00
3288624349 Add methodology settings page with golden ratios, discussion rules, and checklists
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m29s
New /methodology page with 3 tabs for viewing and editing decision
writing methodology. Uses DB override pattern: hardcoded Python
constants serve as defaults, edits saved to appeal_type_rules table,
delete restores default.

Backend: 3 generic endpoints (GET/PUT/DELETE /api/methodology/{category}/{key})
with validation per category type.

Frontend: methodology.ts hooks, GoldenRatiosPanel (number inputs per
outcome/section), DiscussionRulesPanel (accordion with textarea per
rule), ContentChecklistsPanel (markdown editor with preview toggle).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 16:30:39 +00:00
c9a8cca35f Link agents to CMPA company, route CEO wakeup per-company
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 8s
Created 7 agents in CMPA (betterment levy) company, mirroring
the CMP agents with same config and hierarchy. CEO_AGENTS dict
maps company_id to the correct CEO for wakeup routing.

wake_ceo_agent and post_comment now resolve the correct CEO
based on company_id. create_workflow_issue returns company_id.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 12:09:37 +00:00
1e4c5c1518 Add Paperclip agent activity mirror to case detail page
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 3m16s
New "Agents" tab in case detail shows all Paperclip agent comments,
issue status, and agent status for each case — eliminating the need
to switch between Legal-AI and Paperclip UIs.

Backend: 4 new DB query functions in paperclip_client.py (issues,
comments, agents, post_comment) + 2 new API endpoints (GET/POST
/api/cases/{case_number}/agents). Comment posting uses Board API
with DB+wakeup fallback to ensure CEO routing.

Frontend: agents.ts hooks (10s polling), AgentActivityFeed component
(markdown timeline + comment input), AgentStatusWidget (sidebar),
4th tab in case detail page.

Also includes new-company-setup-guide.md documenting the process
for setting up the betterment levy (CMPA) company.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 10:44:42 +00:00
3b260a094d Remove legacy vanilla frontend, clarify web/ vs web-ui/ in CLAUDE.md
- Delete web/static/index.html and design-system.css (replaced by Next.js)
- Remove GET / HTML route and StaticFiles import from app.py
- CLAUDE.md: document that web/ = FastAPI API, web-ui/ = Next.js frontend

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 16:41:02 +00:00
43b8106f55 Fix wakeup API source/triggerDetail enum values
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 10s
Paperclip expects source ∈ {timer, assignment, on_demand, automation}
and triggerDetail ∈ {manual, ping, callback, system}.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 16:08:07 +00:00
6228846223 Add "Start Workflow" button to trigger CEO agent from web UI
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 49s
New endpoint POST /api/cases/{case_number}/start-workflow creates a
Paperclip issue, wakes the CEO agent via wakeup API, and transitions
case status to "processing". Button appears on case page only when
status is "new" or "documents_ready".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 15:51:23 +00:00
82ba4663ba Fix case repo sync + auto-create Gitea repos + add sync indicator
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m30s
- auto-sync-cases.sh: fix broken directory scan (was looking for
  status subdirs that don't exist), fix env var word-splitting bug,
  add safe.directory handling and error logging
- cases.py: auto-create Gitea repo on case_create, fix
  documents/original → documents/originals naming mismatch
- app.py: add GET /api/cases/{case_number}/git-status endpoint
- web-ui: add SyncIndicator component in case header showing
  sync status (synced/pending/no remote) with last commit time
- pyproject.toml: add httpx dependency
- CLAUDE.md: update Paperclip wakeup API docs
- settings page: switch tag input from Select to free-text with datalist

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 15:28:16 +00:00
1133272e34 Fix Paperclip integration (identifier→issue_prefix) + add settings page
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 34s
- Fix column name mismatch in paperclip_client.py and app.py: Paperclip's
  companies table uses `issue_prefix`, not `identifier`
- Fix _LEGAL_DB_URL to read from POSTGRES_URL env var (used in container)
- Add settings page (/settings) for managing tag → Paperclip company mappings
- Replace "תיק חדש" nav item with "הגדרות" (new case is on home page)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 14:09:08 +00:00
23f6b5d825 Remove Paperclip Docker references — runs locally via pm2
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 3m38s
- Deleted from Coolify (was exited:unhealthy since Apr 7)
- Updated CLAUDE.md service table: Paperclip is now pm2/local
- Removed Docker skills path fallback in app.py (always use local)
- Removed old paperclip-bug-report.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 13:13:26 +00:00
a093944967 Add delete button for draft files in case drafts panel
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 45s
- Add DELETE /api/cases/{case_number}/exports/{filename} endpoint
- Add useDeleteDraft hook in exports API
- Add trash icon + confirmation dialog in drafts panel UI
- Final files (סופי-) cannot be deleted as a safety measure

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 13:05:30 +00:00
e698419faf Fix git not found error crashing document uploads in container
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 3m13s
Install git in Docker image and wrap all subprocess git calls in
try/except so a missing or failing git binary never kills an upload
that already succeeded.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 12:38:40 +00:00
5028f677f1 Fix English statuses and labels throughout UI to Hebrew
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 7s
- Complete STATUS_LABELS in case view (added outcome_set, direction_approved,
  drafting, qa_review, reviewed)
- Add DOC_STATUS_LABELS for diagnostics page (failed/stuck documents)
- Add completed/failed/pending/error to global STEP_LABELS
- Translate settings page table headers to Hebrew

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 06:32:03 +00:00
2faae002e7 Add settings page for tag-to-company mappings and auto-create Paperclip projects
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m22s
When a case is created, a Paperclip project is now automatically created in
the correct company based on the appeal_subtype tag. Tag-to-company mappings
are managed via a new Settings page that pulls companies from Paperclip DB.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 06:24:23 +00:00
140a2e442d Add drafts & feedback tab to case page, remove global feedback page
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 32s
Move draft management (export DOCX, download, upload revised version, mark
final) and chair feedback into a new "טיוטות והערות" tab on the case detail
page. Remove the standalone /feedback page and its nav link since feedback
is now case-scoped.

Also fix /api/admin/skills 500 error when Paperclip DB is unreachable by
adding a connection timeout and graceful fallback to disk-only skills.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 05:55:46 +00:00
b248e1414d Add upload endpoint for updated analysis files
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 34s
PUT /api/cases/{n}/research/analysis/upload accepts a markdown file and
validates: UTF-8 encoding, parseable structure, at least one threshold
or issue section, matching case number. Backs up existing file before
replacing. UI adds "העלה ניתוח מעודכן" button with status feedback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 19:34:06 +00:00
fdbf22c699 Add download button for analysis-and-research.md
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m22s
New GET /api/cases/{n}/research/analysis/download endpoint returns the
raw markdown file. UI adds a "הורד ניתוח" button next to "חזרה לתיק"
on the compose page, visible only when analysis data is loaded.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 19:08:07 +00:00
2b431e75ab Add document preview, delete, and fix scroll in documents panel
Documents tab was limited to ~9 visible items due to fixed max-height
without overflow-hidden. Now uses 70vh with proper overflow. Added
click-to-preview (shows extracted text in dialog) and delete button
with confirmation dialog + backend DELETE endpoint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 17:45:01 +00:00
50eaa887db Add chair feedback system and content checklists for block-yod
Backend changes cherry-picked from ui-rewrite branch to enable
feedback API endpoints for the Next.js staging UI.

- chair_feedback DB table + API endpoints (GET/POST/PATCH)
- Content checklists by appeal subtype injected into block-yod prompt
- MCP tools for recording and listing chair feedback
- Corpus analysis documentation (24 decisions)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 21:05:53 +00:00
e2088a4f60 Add case_precedents: attached legal support for the compose phase
New self-contained table + MCP tools + FastAPI endpoints for letting
the chair attach external case-law quotes (quote + citation מראה מקום,
optional chair note, optional archived PDF) to either a specific
threshold_claim / issue or the case as a whole.

Data model
  - case_precedents (SCHEMA_V5_SQL) — case_id, section_id NULL/
    "threshold_N"/"issue_N", quote, citation (free-text), chair_note,
    pdf_document_id FK to documents, denormalized practice_area for
    cross-case library filtering.
  - Deliberately NOT linked to the existing case_law table — that one
    has UNIQUE(case_number) which would force parsing the free-text
    citation into a structured key. A backfill pass into case_law is
    a later follow-up once the UI stabilizes.
  - db.py gains 4 helpers: create_case_precedent, list_case_precedents,
    delete_case_precedent, search_precedent_library. The last uses
    DISTINCT ON (citation) for the cross-case typeahead so each
    precedent appears once even if reused across many cases.

MCP tools (legal_mcp/tools/precedents.py)
  - precedent_attach, precedent_list, precedent_remove,
    precedent_search_library — registered in server.py.

FastAPI (web/app.py)
  - POST /api/cases/{n}/precedents — create, with PrecedentCreateRequest
  - POST /api/cases/{n}/precedents/upload-pdf — one-shot PDF upload to
    a dedicated documents/precedents/ subdirectory, creates a
    documents row with doc_type="precedent_archive" and no text
    extraction (archive only)
  - GET /api/cases/{n}/precedents — list
  - DELETE /api/precedents/{id} — uses path param since precedent_id
    is a UUID (slash-safe, unlike case numbers)
  - GET /api/precedents/search?q=...&practice_area=... — library
    typeahead

Block-writer integration into _build_precedents_context is a deferred
follow-up — Phase 1 surfaces the feature in the compose UI only.

Plan: ~/.claude/plans/woolly-cooking-graham.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 19:16:48 +00:00
8989ad9a9b Add case_delete: MCP tool + DELETE endpoint + DB helper
Wires a new case-deletion path across the three layers that needed it:

- db.delete_case(case_id) — single SQL DELETE; documents, chunks, and
  qa_results cascade via existing schema FKs, audit_log nullifies.
- cases_tools.case_delete(case_number, remove_files=False) — MCP tool
  wrapper. File tree on disk is kept by default (audit trail); pass
  remove_files=True for a hard delete.
- DELETE /api/cases?case_number=... — FastAPI endpoint taking the case
  number as a QUERY param rather than a path segment. Case numbers
  like "1000/0426" can't be passed through a path parameter because
  FastAPI routing decodes %2F before matching, so a query param is
  the only shape that works for historical data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 16:47:50 +00:00
26d09d648f Practice area separation: multi-tenant axis across DB, RAG, and UI
Adds two orthogonal columns — practice_area (top-level legal domain:
appeals_committee / national_insurance / labor_law) and appeal_subtype
(building_permit / betterment_levy / compensation_197) — denormalized
into cases, documents, document_chunks, decisions, and style_corpus so
vector searches can filter without JOINs.

Why: the system handles two unrelated sub-domains under the same
appeals committee (1xxx building permits and 8xxx/9xxx betterment/197),
with different rules and writing style. Without a separation axis,
search_similar() and the block-writer's precedent lookup were free to
surface betterment-levy paragraphs while drafting a building-permit
decision — a real risk of cross-domain contamination. The same axis
also lets future domains (national insurance, labor law) coexist
without separate schemas.

Schema (V4 migration in db.py):
- ALTER ... ADD COLUMN IF NOT EXISTS on all five tables + composite
  indexes (practice_area first).
- Idempotent backfill: case_number ~ '^1' → building_permit, '^8' →
  betterment_levy, '^9' → compensation_197; propagated to documents,
  chunks, and decisions via case_id; training-corpus rows (case_id NULL)
  default to appeals_committee.

Code:
- New services/practice_area.py with derive_subtype, validate, and
  is_override + enum constants.
- db.create_case / create_document / store_chunks / create_decision
  inherit practice_area from the parent case (or take an explicit
  override for the case_id=None training corpus).
- db.search_similar and search_similar_paragraphs accept practice_area
  + appeal_subtype filters using the denormalized columns.
- tools/search.py auto-resolves the filter from case_number when given.
- block_writer._build_precedents_context now passes the active case's
  practice_area to search_similar_paragraphs — closes the contamination
  hole for the discussion-block precedent fetch.
- tools/cases.case_create auto-derives subtype from case_number; an
  explicit override that disagrees writes a case_subtype_override entry
  to audit_log so we can spot bad classifications later.
- tools/documents.document_upload_training tags new training material
  with practice_area + subtype end-to-end (corpus, document, chunks).

UI (web/static/index.html + web/app.py):
- New-case wizard gets a practice_area dropdown (others disabled until
  national_insurance / labor_law arrive) and an appeal_subtype dropdown
  with JS auto-fill from the case-number prefix; manual edits stick.
- Case header shows a blue badge with practice_area · subtype.
- CaseCreateRequest plumbs both fields through to cases_tools.case_create.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 16:36:48 +00:00
a8b79822bf Remove '+ תיק חדש' nav link (redundant with home page button)
The home page already has a prominent '+ תיק חדש' button in the hero.
Cases are always opened by clicking a case card on the home list, so
the top-nav link is noise. Keyboard shortcut 'n' still opens the
wizard directly for power users.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 13:05:38 +00:00
753fe0d57d Research analysis cards with inline chair-position editor
New feature on case view: the analysis-and-research.md produced by the
legal-analyst agent is now rendered as structured cards in the UI,
with inline editing of "עמדת ועדת הערר" that writes directly back to
the markdown file (atomic rename).

Backend (research_md.py):
- parse(Path) → dict with header, prose sections, threshold_claims[],
  issues[], conclusions, other_sections
- Tolerant field extractor handles both block ("**LABEL:**\ncontent")
  and inline ("**LABEL:** content") variants
- Detects [ימולא ע"י יו"ר הוועדה] placeholder → empty chair_position
- update_chair_position(path, section_id, text) locates the exact
  subsection by ordinal, replaces or appends the chair field, writes
  atomically via temp file + os.replace
- Section IDs: threshold_N / issue_N (1-based)

Endpoints:
- GET /api/cases/{n}/research/analysis — returns parsed JSON or 404
- PATCH /api/cases/{n}/research/analysis/chair-position — {section_id, position}

Frontend (#page-case):
- New card "ניתוח משפטי ומחקר" below local-files card
- Prose sections as justified text panels (background + gold border)
- Threshold claims and issues as collapsible <details> items with
  gold right-border on open, numbered pills
- Each item shows all extracted fields with label above content
- Chair position editor: gold-wash background, 📝 icon label, textarea
  with placeholder prompt
- onblur → PATCH with save indicator:  שומר → ✓ נשמר HH:MM → fade
- Status pill next to each item title: "ממתין לעמדה" / "✓ עמדה נקבעה"
- First threshold claim opens by default, rest closed
- Card hidden entirely when no analysis file exists (404)

Tested against real file: case 1033-25 with 3 threshold claims and
6 issues, all chair positions correctly empty, update writes only the
targeted section, atomic rewrite preserves all other content.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 12:47:36 +00:00
ffa089e1df Fix compare sections query: match by number segment
Document titles are '[קורפוס] ARAR-23-1188 - ...' but decision_number
is '1188/23' — previous LIKE %1188/23% wouldn't match. Now extracts
the first numeric segment and matches against title.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 12:28:52 +00:00
5cb0be473c 5 new features: dark mode, shortcuts, SSE tasks, compare, compose
Dark mode:
- body.dark overrides CSS variables (navy→cream reverse)
- Persisted in localStorage, applied before paint to avoid flash
- Toggle button in nav (moon/sun icon), Shift+D shortcut

Keyboard shortcuts:
- g h/n/u/t/s/c/w/d/k for page navigation
- n for new case, ? for help (Shift+/)
- Esc closes any open dialog, blurs focused input
- Help modal via showShortcutsHelp() with styled kbd elements

SSE tasks stream:
- /api/system/tasks/stream pushes snapshots whenever _progress changes
- Client uses EventSource instead of 3s polling
- Auto-reconnect after 5s on error
- 15s heartbeat keeps proxies alive

Compare decisions (new #/compare page):
- /api/training/compare?a=id&b=id serializes both decisions' metadata,
  section breakdown from document_chunks, and three buckets of patterns
  (only in A, only in B, shared) using variant matching
- Two-column header with section-length breakdown + patterns count
- Three-column diff row (only_a / shared / only_b)

Compose with suggestions (new #/compose page):
- Large RTL justified textarea with Hebrew display font title input
- Sidebar lists all 47 style_patterns grouped by type with filter chips
- Click a pattern → inserts at cursor, replacing [placeholders] with ___
- Live section guess (פתיחה / רקע / טענות / דיון / סוף דבר) based on
  most-recent 400 chars
- Auto-save draft to localStorage every second; restore on page load
- "העתק טקסט" copies title+body to clipboard

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 12:24:45 +00:00
ea3ef5963e Page polish + print styles + skeletons + responsive
Case view:
- Header card gets gold right-border, serif display title, pill-style
  action links with gold hover
- Document groups: gold-underlined section headers, hover rows with
  parchment background

Wizard (new case):
- Step tabs in display font with separators; active/done states use
  navy/success colors with proper background contrast
- Nav buttons separated by hairline divider

Skills page:
- Pill badges for ok/warn, gold icon, hover elevation

Upload zone:
- Larger dashed border, serif header, gold-wash hover state

Loading skeletons:
- .skeleton / .skeleton-line classes with shimmer animation
- Case list shows 3 skeleton cards while loading
- Style report shows skeleton hero while loading

Empty states:
- Case list gets ornamental ❦ + emotional copy in display font
- Error messages include underlying error detail

Print stylesheet:
- Hides header/nav/sidebar/buttons
- Forces card borders and page-break-inside for portrait printing
- Expands details elements so content prints

Responsive:
- Mobile: simplified hero, narrower process panel, wrapping header
- Tablet: home grid collapses to single column

Fixes:
- DONUT_COLORS reverts to hex literals (was var(--color-gold) string
  which doesn't interpolate in conic-gradient reliably across browsers)
- Sig-phrase headline now prefers clean phrases over template-heavy ones

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 12:07:42 +00:00
3e0221ccec Management UI: corpus delete, process panel, activity feed, diagnostics
- DELETE /api/training/corpus/{id} + delete button on training page,
  with confirmation dialog and recompute hint
- /api/system/tasks + floating process panel (bottom-left) showing
  active background tasks with live 3s polling
- /api/system/recent-activity derives a feed from cases, style_corpus,
  and last style_patterns run; sidebar on home page renders with
  relative timestamps
- /api/system/diagnostics + /#/diagnostics page showing DB health,
  row counts per table, active tasks, stuck documents (>10 min),
  failed extractions
- Cosmetic: signature phrase headline now prefers clean phrases over
  bracket-heavy templates for display

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 12:04:13 +00:00
fcb2e1a325 Switch to Heebo — Google's standard Hebrew font
Replaces Frank Ruhl Libre + Assistant with single-family Heebo for both
display and body. Weight contrast (900/700 for headings, 400 for body,
300 for light captions) provides the hierarchy. Single font family reduces
network requests and renders consistently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 11:55:44 +00:00
d5164e2875 Editorial/Judicial design system — Phase B visual overhaul
- New design-system.css: CSS variables for Navy/Cream/Gold palette,
  Frank Ruhl Libre (display) + Assistant (body) typography via Google Fonts,
  spacing/shadow/motion tokens, RTL-safe utilities
- All body paragraphs justify to both sides (text-align: justify, inter-word)
- Existing inline <style> migrated from hardcoded #e94560/#1a1a2e/#27ae60 to
  CSS variables
- Header: deep navy with gold accent rule under, display-font brand mark,
  active nav link marked with gold underline
- Buttons: navy primary, gold-wash focus rings, elevation on hover
- Case cards: gold right-border, hairline top glow on hover, display font
  on case number
- Home dashboard: new hero with eyebrow/title/subtitle, 4 KPI cards with
  gold-rule side marker, loadKPIs() fetches case count, corpus size,
  pattern count, processing queue
- Style report: larger hero h1, ornamental pull-quote headline with
  drop-cap open quote, gold divider under section titles
- Toast, status bar, form inputs: navy/gold palette, serif italics for
  subtitles and empty states

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 11:47:13 +00:00
858333b386 Add style report dashboard — Dafna's style portrait
Visual dashboard at #/style-report with 4 sections:
- Hero: 24 decisions, char counts, subject donut, timeline
- Anatomy: average section-length breakdown (intro → ruling → conclusion)
- Signature Phrases Wall: pattern cards with real corpus frequencies, filter
  chips by type, click → modal with examples
- Contribution: per-decision "new vs confirmed" patterns, growth curve SVG

Backend:
- /api/training/style-report endpoint computes all 4 sections in one call
- Headlines in Hebrew are computed server-side from real data
- Backfill script for style_patterns.frequency using _strip_nikud +
  pattern-variant extraction (templates with [placeholders], / alternatives,
  ellipsis all handled)

Real findings from the 24-decision corpus:
- דיון משפטי = 49% of avg decision (the focus)
- 23/24 use "לפנינו ערר" opening formula
- 21/24 use "ניתנה פה אחד" closing
- After 7 decisions we already learned 85% of her style patterns

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 11:34:37 +00:00
32f18de049 Add training corpus UI with Nevo proofreading pipeline
- New proofreader service strips Nevo editorial additions (front matter,
  postamble, page headers, watermarks, inline codes) from DOCX/PDF/MD
- PDF pages use Google Vision OCR for clean Hebrew RTL extraction
- New training page at #/training with drag-and-drop upload, automatic
  metadata extraction (decision number, date, categories), reviewable
  preview, and style pattern report grouped by type
- API endpoints: /api/training/{analyze,upload,corpus,patterns,
  analyze-style,analyze-style/status}
- Fix claude_session.query to pipe prompt via stdin, avoiding ARG_MAX
  overflow when analyzing 900K+ char corpus
- CLI scripts for batch proofreading and corpus upload

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 11:04:58 +00:00
ecda95d610 Add committee position field to analyst template and fix UI
- Add "עמדת ועדת הערר" placeholder to legal-analyst agent template
  for each legal issue, to be filled by the chair as guidance for the
  writing agent
- Fix green checkmark not showing for proofread documents (treat
  'proofread' status same as 'completed')
- Show time alongside date in local files listing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 18:00:01 +00:00
3f759d3610 Improve document processing pipeline and agent workflows
- Add delete_document_chunks for reprocessing, save extracted text to disk
- Expand case directory structure (original/extracted/proofread/backup)
- Update classifier patterns (תגובה, הודעת עמדה)
- Fix proofreader agent paths for new directory layout
- Update HEARTBEAT to notify on every task completion
- Improve bidi_table with LRE/PDF directional embedding
- Add Paperclip project verification and auto-close setup issue
- Add auto-sync-cases.sh for Gitea synchronization

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 16:45:49 +00:00
63c9ca184b Fix processing badge: treat 'proofread' status as completed
Documents with extraction_status='proofread' were incorrectly shown
as "in processing" on the case list page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:36:16 +00:00
bfcbb6708a Add local files section to case view (research, drafts, proofread)
- New API endpoint /api/cases/{num}/local-files lists files from disk
- New API endpoint /api/cases/{num}/local-files/{folder}/{file} serves file content
- Case view now shows research/analysis files, proofread texts, and draft decisions
- Files are clickable and open in new tab

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:43:02 +00:00
22e819363e Flatten cases directory structure and unify paths
- Remove cases/new|in-progress|completed subdivision (status managed in DB)
- Rename documents/original → documents/originals (consistent plural)
- Move exports from global data/exports/ into cases/{num}/exports/
- Add documents/research/ for case law and analysis files
- Update all agents, scripts, config, web API endpoints, and DB paths

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:33:27 +00:00
d8e888ad6a Add sync-to-DB and delete-from-DB actions for skills
- POST /api/admin/skills/{slug}/sync — read SKILL.md from disk, insert/update DB
- DELETE /api/admin/skills/{slug} — remove skill from DB (keeps disk files)
- UI: Sync/Re-sync and Delete buttons per skill in the skills list

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 17:52:00 +00:00
2d265d2f0e Add Paperclip skill install/upgrade UI and API
- POST /api/admin/skills/install — upload ZIP, extract to skills dir, update DB
- GET /api/admin/skills — list installed skills with DB/disk sync status
- POST /api/admin/paperclip/restart — restart Paperclip (pm2 or flag file)
- New Skills page in web UI with drag-and-drop ZIP upload
- Coolify volume mount for /paperclip-skills
- Host-side crontab watcher for restart flag file

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 17:38:29 +00:00
6a62edbdb4 Fix: add /api/health endpoint for Coolify healthcheck
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 12:15:11 +00:00
5a8d5cac0a Add exports panel: versioned drafts, download, upload revisions, mark final
Export DOCX now saves to data/exports/{case_number}/ with auto-versioning
(טיוטה-v1, v2...). The case view UI shows all drafts with download buttons,
allows uploading revised versions (עריכה-v1...), and marking a version as
final (copies to training corpus for style learning).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 12:10:02 +00:00
85880c482e Revert Paperclip DB URL to host embedded-postgres (localhost:54329)
Paperclip moved back from Docker to pm2 on host.
Reverts c83dcd6 (Docker migration URL change).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 12:03:08 +00:00
c83dcd660e Update Paperclip DB URL for Docker migration
Paperclip moved from embedded PG (localhost:54329) to Coolify-managed
PostgreSQL container (10.0.2.13:5432).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 11:17:57 +00:00
e5dc037088 Create Paperclip issue + plugin state link when opening new case
Wizard now creates: project + issue (CMP-N) + plugin_state entry
linking the issue to the legal-ai case number. This enables the
sync job in the marcusgroup.legal-ai plugin to track case status.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 13:44:49 +00:00
40406b5fde Keep original filename when doc_type is auto instead of 'auto-{case}.ext'
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:52:18 +00:00
561a4f7bcf Allow .md file uploads alongside PDF, DOCX, RTF, TXT
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:44:30 +00:00
10071d7f18 Prevent duplicate Paperclip projects: check existing before creating
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 11:21:06 +00:00
5fc52ce530 Switch to cases/{new,in-progress,completed}/ directory structure
Replace single CASES_DIR with find_case_dir() that searches across
all status directories. New cases created in cases/new/{number}/.

Config: CASES_BASE, CASES_NEW, CASES_IN_PROGRESS, CASES_COMPLETED
Docker: added -v /home/chaim/legal-ai/cases:/cases volume mount

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 10:45:47 +00:00
dc6026100c Improve case-not-found error: show clear message with create button
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 10:27:36 +00:00