feat(ui): interactive decision-block viewer + inline editor on case page

Adds a new "ההחלטה" tab to the case detail page showing all 12 decision
blocks with rendered markdown content and inline editing that saves back
to the DB via two new FastAPI endpoints.

Backend (web/app.py):
- GET  /api/cases/{n}/decision-blocks   — returns all 12 blocks (empty
  ones included) merged from BLOCK_CONFIG + decision_blocks table.
  Exposes source_of_truth ("docx"|"blocks") and active_draft_path.
- PUT  /api/cases/{n}/decision-blocks/{block_id} — inline save via
  block_writer.save_block_content; warns (does not block) when an
  active DOCX draft exists.

Frontend:
- src/lib/api/decision-blocks.ts    — typed hooks (useDecisionBlocks,
  useSaveBlock) following the cases.ts hand-written-module pattern.
- src/components/cases/decision-blocks-panel.tsx — accordion of 12
  blocks; view mode renders Markdown component; edit mode is a textarea
  with on-blur save (derived from ChairEditor pattern, setState-during-
  render for re-sync to avoid effect cascade).
- BLOCK_LABELS in feedback.ts extended from 7 → 12 blocks.
- cases/[caseNumber]/page.tsx — new "ההחלטה" tab wired to the panel.

No DB migration required — decision_blocks + active_draft_path exist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-06 09:36:51 +00:00
parent 6dd125c491
commit c35e0e50ed
5 changed files with 445 additions and 0 deletions

View File

@@ -125,6 +125,10 @@ export const CATEGORY_COLORS: Record<FeedbackCategory, string> = {
/** Block ID labels */
export const BLOCK_LABELS: Record<string, string> = {
"block-alef": "א — כותרת מוסדית",
"block-bet": "ב — הרכב הוועדה",
"block-gimel": "ג — צדדים",
"block-dalet": "ד — החלטה",
"block-he": "ה — פתיחה",
"block-vav": "ו — רקע עובדתי",
"block-zayin": "ז — טענות הצדדים",
@@ -132,4 +136,5 @@ export const BLOCK_LABELS: Record<string, string> = {
"block-tet": "ט — תכניות חלות",
"block-yod": "י — דיון והכרעה",
"block-yod-alef": "יא — סיכום",
"block-yod-bet": "יב — חתימות",
};