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>
This commit is contained in:
@@ -52,9 +52,29 @@ ANTHROPIC_API_KEY = os.environ.get("ANTHROPIC_API_KEY", "")
|
|||||||
|
|
||||||
# Data directory
|
# Data directory
|
||||||
DATA_DIR = Path(os.environ.get("DATA_DIR", str(Path.home() / "legal-ai" / "data")))
|
DATA_DIR = Path(os.environ.get("DATA_DIR", str(Path.home() / "legal-ai" / "data")))
|
||||||
CASES_DIR = DATA_DIR / "cases"
|
|
||||||
TRAINING_DIR = DATA_DIR / "training"
|
TRAINING_DIR = DATA_DIR / "training"
|
||||||
|
|
||||||
|
# Cases directory — new structure: cases/{new,in-progress,completed}/{case_number}/
|
||||||
|
CASES_BASE = Path(os.environ.get("CASES_BASE", str(Path.home() / "legal-ai" / "cases")))
|
||||||
|
CASES_NEW = CASES_BASE / "new"
|
||||||
|
CASES_IN_PROGRESS = CASES_BASE / "in-progress"
|
||||||
|
CASES_COMPLETED = CASES_BASE / "completed"
|
||||||
|
CASES_DIR = CASES_NEW # backwards compatibility — new cases default here
|
||||||
|
|
||||||
|
_STATUS_DIRS = [CASES_NEW, CASES_IN_PROGRESS, CASES_COMPLETED]
|
||||||
|
|
||||||
|
|
||||||
|
def find_case_dir(case_number: str) -> Path:
|
||||||
|
"""Find a case directory across all status folders.
|
||||||
|
|
||||||
|
Returns the existing directory, or defaults to CASES_NEW/{case_number}.
|
||||||
|
"""
|
||||||
|
for base in _STATUS_DIRS:
|
||||||
|
candidate = base / case_number
|
||||||
|
if candidate.exists():
|
||||||
|
return candidate
|
||||||
|
return CASES_NEW / case_number
|
||||||
|
|
||||||
# Chunking parameters
|
# Chunking parameters
|
||||||
CHUNK_SIZE_TOKENS = 600
|
CHUNK_SIZE_TOKENS = 600
|
||||||
CHUNK_OVERLAP_TOKENS = 100
|
CHUNK_OVERLAP_TOKENS = 100
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ async def export_decision(case_id: UUID, output_path: str | None = None) -> str:
|
|||||||
|
|
||||||
# Determine output path
|
# Determine output path
|
||||||
if not output_path:
|
if not output_path:
|
||||||
case_dir = config.CASES_DIR / case["case_number"] / "output"
|
case_dir = config.find_case_dir(case["case_number"]) / "output"
|
||||||
case_dir.mkdir(parents=True, exist_ok=True)
|
case_dir.mkdir(parents=True, exist_ok=True)
|
||||||
output_path = str(case_dir / f"החלטה-{case['case_number']}.docx")
|
output_path = str(case_dir / f"החלטה-{case['case_number']}.docx")
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ async def case_create(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Initialize git repo for the case
|
# Initialize git repo for the case
|
||||||
case_dir = config.CASES_DIR / case_number
|
case_dir = config.find_case_dir(case_number)
|
||||||
case_dir.mkdir(parents=True, exist_ok=True)
|
case_dir.mkdir(parents=True, exist_ok=True)
|
||||||
(case_dir / "documents").mkdir(exist_ok=True)
|
(case_dir / "documents").mkdir(exist_ok=True)
|
||||||
(case_dir / "drafts").mkdir(exist_ok=True)
|
(case_dir / "drafts").mkdir(exist_ok=True)
|
||||||
@@ -167,7 +167,7 @@ async def case_update(
|
|||||||
updated = await db.update_case(UUID(case["id"]), **fields)
|
updated = await db.update_case(UUID(case["id"]), **fields)
|
||||||
|
|
||||||
# Git commit the update
|
# Git commit the update
|
||||||
case_dir = config.CASES_DIR / case_number
|
case_dir = config.find_case_dir(case_number)
|
||||||
if case_dir.exists():
|
if case_dir.exists():
|
||||||
case_json = case_dir / "case.json"
|
case_json = case_dir / "case.json"
|
||||||
case_json.write_text(json.dumps(updated, default=str, ensure_ascii=False, indent=2))
|
case_json.write_text(json.dumps(updated, default=str, ensure_ascii=False, indent=2))
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ async def document_upload(
|
|||||||
title = source.stem
|
title = source.stem
|
||||||
|
|
||||||
# Copy file to case directory
|
# Copy file to case directory
|
||||||
case_dir = config.CASES_DIR / case_number / "documents"
|
case_dir = config.find_case_dir(case_number) / "documents"
|
||||||
case_dir.mkdir(parents=True, exist_ok=True)
|
case_dir.mkdir(parents=True, exist_ok=True)
|
||||||
dest = case_dir / source.name
|
dest = case_dir / source.name
|
||||||
shutil.copy2(str(source), str(dest))
|
shutil.copy2(str(source), str(dest))
|
||||||
@@ -68,7 +68,7 @@ async def document_upload(
|
|||||||
doc["doc_type"] = classified_type
|
doc["doc_type"] = classified_type
|
||||||
|
|
||||||
# Git commit
|
# Git commit
|
||||||
repo_dir = config.CASES_DIR / case_number
|
repo_dir = config.find_case_dir(case_number)
|
||||||
if repo_dir.exists():
|
if repo_dir.exists():
|
||||||
subprocess.run(["git", "add", "."], cwd=repo_dir, capture_output=True)
|
subprocess.run(["git", "add", "."], cwd=repo_dir, capture_output=True)
|
||||||
doc_type_hebrew = {
|
doc_type_hebrew = {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ async def workflow_status(case_number: str) -> str:
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from legal_mcp import config
|
from legal_mcp import config
|
||||||
|
|
||||||
case_dir = config.CASES_DIR / case_number
|
case_dir = config.find_case_dir(case_number)
|
||||||
draft_path = case_dir / "drafts" / "decision.md"
|
draft_path = case_dir / "drafts" / "decision.md"
|
||||||
has_draft = draft_path.exists()
|
has_draft = draft_path.exists()
|
||||||
draft_size = draft_path.stat().st_size if has_draft else 0
|
draft_size = draft_path.stat().st_size if has_draft else 0
|
||||||
|
|||||||
10
web/app.py
10
web/app.py
@@ -613,7 +613,7 @@ async def api_gitea_create_repo(req: GiteaRepoRequest):
|
|||||||
raise HTTPException(502, f"Gitea error: {e}")
|
raise HTTPException(502, f"Gitea error: {e}")
|
||||||
|
|
||||||
clone_url = repo.get("clone_url") or repo.get("html_url", "")
|
clone_url = repo.get("clone_url") or repo.get("html_url", "")
|
||||||
case_dir = config.CASES_DIR / req.case_number
|
case_dir = config.find_case_dir(req.case_number)
|
||||||
|
|
||||||
pushed = False
|
pushed = False
|
||||||
if case_dir.exists():
|
if case_dir.exists():
|
||||||
@@ -676,7 +676,7 @@ async def api_upload_tagged_document(
|
|||||||
new_filename = generate_doc_filename(doc_type, case_number, party_name, ext)
|
new_filename = generate_doc_filename(doc_type, case_number, party_name, ext)
|
||||||
|
|
||||||
# Save to case directory
|
# Save to case directory
|
||||||
case_dir = config.CASES_DIR / case_number / "documents"
|
case_dir = config.find_case_dir(case_number) / "documents"
|
||||||
case_dir.mkdir(parents=True, exist_ok=True)
|
case_dir.mkdir(parents=True, exist_ok=True)
|
||||||
dest = case_dir / new_filename
|
dest = case_dir / new_filename
|
||||||
|
|
||||||
@@ -719,7 +719,7 @@ async def _process_tagged_document(task_id: str, dest: Path, case_number: str, c
|
|||||||
result = await processor.process_document(doc_id, case_id)
|
result = await processor.process_document(doc_id, case_id)
|
||||||
|
|
||||||
# Git commit + push
|
# Git commit + push
|
||||||
repo_dir = config.CASES_DIR / case_number
|
repo_dir = config.find_case_dir(case_number)
|
||||||
if repo_dir.exists():
|
if repo_dir.exists():
|
||||||
env = {
|
env = {
|
||||||
"GIT_AUTHOR_NAME": "Ezer Mishpati", "GIT_AUTHOR_EMAIL": "legal@local",
|
"GIT_AUTHOR_NAME": "Ezer Mishpati", "GIT_AUTHOR_EMAIL": "legal@local",
|
||||||
@@ -779,7 +779,7 @@ async def _process_case_document(task_id: str, source: Path, req: ClassifyReques
|
|||||||
|
|
||||||
# Copy to case directory
|
# Copy to case directory
|
||||||
_progress[task_id] = {"status": "copying", "filename": req.filename}
|
_progress[task_id] = {"status": "copying", "filename": req.filename}
|
||||||
case_dir = config.CASES_DIR / req.case_number / "documents"
|
case_dir = config.find_case_dir(req.case_number) / "documents"
|
||||||
case_dir.mkdir(parents=True, exist_ok=True)
|
case_dir.mkdir(parents=True, exist_ok=True)
|
||||||
# Use original name without timestamp prefix
|
# Use original name without timestamp prefix
|
||||||
original_name = re.sub(r"^\d+_", "", source.name)
|
original_name = re.sub(r"^\d+_", "", source.name)
|
||||||
@@ -800,7 +800,7 @@ async def _process_case_document(task_id: str, source: Path, req: ClassifyReques
|
|||||||
result = await processor.process_document(UUID(doc["id"]), case_id)
|
result = await processor.process_document(UUID(doc["id"]), case_id)
|
||||||
|
|
||||||
# Git commit
|
# Git commit
|
||||||
repo_dir = config.CASES_DIR / req.case_number
|
repo_dir = config.find_case_dir(req.case_number)
|
||||||
if repo_dir.exists():
|
if repo_dir.exists():
|
||||||
subprocess.run(["git", "add", "."], cwd=repo_dir, capture_output=True)
|
subprocess.run(["git", "add", "."], cwd=repo_dir, capture_output=True)
|
||||||
doc_type_hebrew = {
|
doc_type_hebrew = {
|
||||||
|
|||||||
Reference in New Issue
Block a user