Add interactive case creation wizard + document upload with auto-rename
New SPA UI with 4 views: - Case list (#/) with status cards and document counts - New case wizard (#/new) with 4-step form: details, parties, schedule, review+create - Case view (#/case/:id) with grouped documents and drag-drop upload with tagging - Legacy upload (#/upload) for backwards compatibility Auto-creation pipeline in wizard step 4: 1. Creates case in legal-ai DB with local git repo 2. Creates Gitea repo in 'cases' org and pushes initial commit 3. Creates Paperclip project via direct DB insert Document upload with smart rename: - scan_001.pdf -> כתב-ערר-קובר-1130-25.pdf - Based on doc_type + party_name + case_number New files: - web/gitea_client.py: Gitea REST API client - web/paperclip_client.py: Paperclip embedded DB client Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
98
web/gitea_client.py
Normal file
98
web/gitea_client.py
Normal file
@@ -0,0 +1,98 @@
|
||||
"""Gitea REST API client — create repos in the 'cases' org and push."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import httpx
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
GITEA_ORG = "cases"
|
||||
|
||||
|
||||
def _host() -> str:
|
||||
return os.environ.get("GITEA_HOST", "https://gitea.nautilus.marcusgroup.org")
|
||||
|
||||
|
||||
def _token() -> str:
|
||||
return os.environ.get("GITEA_ACCESS_TOKEN", "")
|
||||
|
||||
|
||||
async def create_repo(case_number: str, title: str, description: str = "") -> dict:
|
||||
"""Create a private repo in the 'cases' org on Gitea."""
|
||||
repo_name = case_number # e.g. "1130-25"
|
||||
async with httpx.AsyncClient(verify=False, timeout=30) as client:
|
||||
resp = await client.post(
|
||||
f"{_host()}/api/v1/orgs/{GITEA_ORG}/repos",
|
||||
headers={"Authorization": f"token {_token()}"},
|
||||
json={
|
||||
"name": repo_name,
|
||||
"description": f"ערר {case_number} — {title}"[:255],
|
||||
"private": True,
|
||||
"auto_init": False,
|
||||
},
|
||||
)
|
||||
if resp.status_code == 409:
|
||||
# Repo already exists — fetch it
|
||||
resp2 = await client.get(
|
||||
f"{_host()}/api/v1/repos/{GITEA_ORG}/{repo_name}",
|
||||
headers={"Authorization": f"token {_token()}"},
|
||||
)
|
||||
resp2.raise_for_status()
|
||||
return resp2.json()
|
||||
resp.raise_for_status()
|
||||
return resp.json()
|
||||
|
||||
|
||||
def setup_remote_and_push(case_dir: str | Path, repo_clone_url: str) -> bool:
|
||||
"""Add Gitea as remote 'origin' (or update it) and push."""
|
||||
case_dir = Path(case_dir)
|
||||
if not (case_dir / ".git").exists():
|
||||
return False
|
||||
|
||||
env = {
|
||||
"GIT_AUTHOR_NAME": "Ezer Mishpati",
|
||||
"GIT_AUTHOR_EMAIL": "legal@local",
|
||||
"GIT_COMMITTER_NAME": "Ezer Mishpati",
|
||||
"GIT_COMMITTER_EMAIL": "legal@local",
|
||||
"PATH": os.environ.get("PATH", "/usr/bin:/bin"),
|
||||
}
|
||||
|
||||
# Inject token into clone URL for auth
|
||||
auth_url = repo_clone_url.replace("https://", f"https://chaim:{_token()}@")
|
||||
|
||||
# Check if remote exists
|
||||
result = subprocess.run(
|
||||
["git", "remote", "get-url", "origin"],
|
||||
cwd=case_dir, capture_output=True, text=True,
|
||||
)
|
||||
if result.returncode == 0:
|
||||
subprocess.run(
|
||||
["git", "remote", "set-url", "origin", auth_url],
|
||||
cwd=case_dir, capture_output=True, env=env,
|
||||
)
|
||||
else:
|
||||
subprocess.run(
|
||||
["git", "remote", "add", "origin", auth_url],
|
||||
cwd=case_dir, capture_output=True, env=env,
|
||||
)
|
||||
|
||||
# Push
|
||||
push_result = subprocess.run(
|
||||
["git", "push", "-u", "origin", "main"],
|
||||
cwd=case_dir, capture_output=True, text=True, env=env,
|
||||
)
|
||||
if push_result.returncode != 0:
|
||||
# Try master branch
|
||||
push_result = subprocess.run(
|
||||
["git", "push", "-u", "origin", "master"],
|
||||
cwd=case_dir, capture_output=True, text=True, env=env,
|
||||
)
|
||||
if push_result.returncode != 0:
|
||||
logger.warning("Git push failed: %s", push_result.stderr)
|
||||
return False
|
||||
return True
|
||||
Reference in New Issue
Block a user