3df85fdb04
Includes legal document generation workflows, prompt governance runtime wiring, legal change impact scans, operation KPI dashboards, invoice files, sales follow-up events, mobile review polish, deployment automation, and updated project docs.
210 lines
7.8 KiB
Python
210 lines
7.8 KiB
Python
from typing import Any, Optional
|
|
|
|
from fastapi import APIRouter, Depends, Header, HTTPException, Request
|
|
from pydantic import BaseModel, Field
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.response import success_response
|
|
from app.db import get_db_session
|
|
from app.services.audit_log_service import AuditLogService
|
|
from app.services.auth_service import AuthService
|
|
from app.services.contract_generation_service import ExportFormat
|
|
from app.services.legal_document_draft_service import LegalDocumentDraftService
|
|
|
|
router = APIRouter(prefix="/legal-document-drafts", tags=["legal-document-drafts"])
|
|
ROUTE_PERMISSION_SCOPE = "legal_document_drafts"
|
|
ROUTE_PERMISSION_ACTIONS = {
|
|
"list": "legal_document_drafts:list",
|
|
"create": "legal_document_drafts:create",
|
|
"detail": "legal_document_drafts:detail",
|
|
"update": "legal_document_drafts:update",
|
|
"delete": "legal_document_drafts:delete",
|
|
"generate": "legal_document_drafts:generate",
|
|
}
|
|
|
|
|
|
class LegalDocumentDraftCreateRequest(BaseModel):
|
|
document_type_code: str
|
|
element_values: dict[str, Any] = Field(default_factory=dict)
|
|
title: Optional[str] = None
|
|
template_id: Optional[str] = None
|
|
|
|
|
|
class LegalDocumentDraftUpdateRequest(BaseModel):
|
|
element_values: Optional[dict[str, Any]] = None
|
|
title: Optional[str] = None
|
|
template_id: Optional[str] = None
|
|
|
|
|
|
class LegalDocumentDraftGenerateRequest(BaseModel):
|
|
export_format: str = "docx"
|
|
template_id: Optional[str] = None
|
|
options: dict[str, Any] = Field(default_factory=dict)
|
|
|
|
|
|
def get_legal_document_draft_service(db: Session = Depends(get_db_session)) -> LegalDocumentDraftService:
|
|
return LegalDocumentDraftService(db)
|
|
|
|
|
|
def get_audit_log_service(db: Session = Depends(get_db_session)) -> AuditLogService:
|
|
return AuditLogService(db)
|
|
|
|
|
|
def require_current_user(
|
|
authorization: Optional[str] = Header(default=None),
|
|
db: Session = Depends(get_db_session),
|
|
):
|
|
return AuthService(db).require_current_user(authorization)
|
|
|
|
|
|
@router.get("")
|
|
def list_legal_document_drafts(
|
|
document_type_code: Optional[str] = None,
|
|
status: Optional[str] = "draft",
|
|
limit: int = 20,
|
|
legal_document_draft_service: LegalDocumentDraftService = Depends(get_legal_document_draft_service),
|
|
current_user: dict = Depends(require_current_user),
|
|
):
|
|
result = legal_document_draft_service.list_drafts(
|
|
current_user,
|
|
document_type_code=document_type_code,
|
|
status_value=status,
|
|
limit=limit,
|
|
)
|
|
return success_response(result)
|
|
|
|
|
|
@router.post("")
|
|
def create_legal_document_draft(
|
|
payload: LegalDocumentDraftCreateRequest,
|
|
request: Request,
|
|
legal_document_draft_service: LegalDocumentDraftService = Depends(get_legal_document_draft_service),
|
|
audit_log_service: AuditLogService = Depends(get_audit_log_service),
|
|
current_user: dict = Depends(require_current_user),
|
|
):
|
|
result = legal_document_draft_service.create_draft(
|
|
current_user,
|
|
document_type_code=payload.document_type_code,
|
|
element_values=payload.element_values,
|
|
title=payload.title,
|
|
template_id=payload.template_id,
|
|
)
|
|
audit_log_service.record_event(
|
|
tenant_id=current_user.get("tenant_id"),
|
|
user_id=current_user.get("id"),
|
|
action="save_legal_document_draft",
|
|
resource_type="legal_document_draft",
|
|
resource_id=result["id"],
|
|
detail_json={
|
|
"document_type_code": result["document_type_code"],
|
|
"template_id": result.get("template_id"),
|
|
"valid": (result.get("validation_result") or {}).get("valid"),
|
|
},
|
|
ip_address=request.client.host if request.client else None,
|
|
user_agent=request.headers.get("user-agent"),
|
|
)
|
|
return success_response(result)
|
|
|
|
|
|
@router.get("/{draft_id}")
|
|
def get_legal_document_draft(
|
|
draft_id: str,
|
|
legal_document_draft_service: LegalDocumentDraftService = Depends(get_legal_document_draft_service),
|
|
current_user: dict = Depends(require_current_user),
|
|
):
|
|
return success_response(legal_document_draft_service.get_draft(current_user, draft_id))
|
|
|
|
|
|
@router.put("/{draft_id}")
|
|
def update_legal_document_draft(
|
|
draft_id: str,
|
|
payload: LegalDocumentDraftUpdateRequest,
|
|
request: Request,
|
|
legal_document_draft_service: LegalDocumentDraftService = Depends(get_legal_document_draft_service),
|
|
audit_log_service: AuditLogService = Depends(get_audit_log_service),
|
|
current_user: dict = Depends(require_current_user),
|
|
):
|
|
result = legal_document_draft_service.update_draft(
|
|
current_user,
|
|
draft_id,
|
|
element_values=payload.element_values,
|
|
title=payload.title,
|
|
template_id=payload.template_id,
|
|
)
|
|
audit_log_service.record_event(
|
|
tenant_id=current_user.get("tenant_id"),
|
|
user_id=current_user.get("id"),
|
|
action="update_legal_document_draft",
|
|
resource_type="legal_document_draft",
|
|
resource_id=result["id"],
|
|
detail_json={
|
|
"document_type_code": result["document_type_code"],
|
|
"template_id": result.get("template_id"),
|
|
"valid": (result.get("validation_result") or {}).get("valid"),
|
|
},
|
|
ip_address=request.client.host if request.client else None,
|
|
user_agent=request.headers.get("user-agent"),
|
|
)
|
|
return success_response(result)
|
|
|
|
|
|
@router.delete("/{draft_id}")
|
|
def delete_legal_document_draft(
|
|
draft_id: str,
|
|
request: Request,
|
|
legal_document_draft_service: LegalDocumentDraftService = Depends(get_legal_document_draft_service),
|
|
audit_log_service: AuditLogService = Depends(get_audit_log_service),
|
|
current_user: dict = Depends(require_current_user),
|
|
):
|
|
result = legal_document_draft_service.delete_draft(current_user, draft_id)
|
|
audit_log_service.record_event(
|
|
tenant_id=current_user.get("tenant_id"),
|
|
user_id=current_user.get("id"),
|
|
action="delete_legal_document_draft",
|
|
resource_type="legal_document_draft",
|
|
resource_id=result["id"],
|
|
detail_json={"document_type_code": result["document_type_code"]},
|
|
ip_address=request.client.host if request.client else None,
|
|
user_agent=request.headers.get("user-agent"),
|
|
)
|
|
return success_response(result)
|
|
|
|
|
|
@router.post("/{draft_id}/generate")
|
|
def generate_contract_from_legal_document_draft(
|
|
draft_id: str,
|
|
payload: LegalDocumentDraftGenerateRequest,
|
|
request: Request,
|
|
legal_document_draft_service: LegalDocumentDraftService = Depends(get_legal_document_draft_service),
|
|
audit_log_service: AuditLogService = Depends(get_audit_log_service),
|
|
current_user: dict = Depends(require_current_user),
|
|
):
|
|
try:
|
|
export_format = ExportFormat(payload.export_format.lower())
|
|
except ValueError:
|
|
raise HTTPException(status_code=400, detail=f"unsupported export format: {payload.export_format}")
|
|
result = legal_document_draft_service.generate_from_draft(
|
|
current_user,
|
|
draft_id,
|
|
export_format=export_format,
|
|
template_id=payload.template_id,
|
|
options=payload.options,
|
|
)
|
|
audit_log_service.record_event(
|
|
tenant_id=current_user.get("tenant_id"),
|
|
user_id=current_user.get("id"),
|
|
action="generate_contract_from_legal_document_draft",
|
|
resource_type="legal_document_draft",
|
|
resource_id=result["draft"]["id"],
|
|
detail_json={
|
|
"document_type_code": result["draft"]["document_type_code"],
|
|
"template_id": result["draft"].get("template_id"),
|
|
"generated_contract_id": result["draft"].get("generated_contract_id"),
|
|
"element_schema_id": result["draft"].get("element_schema_id"),
|
|
"element_schema_version_label": result["draft"].get("element_schema_version_label"),
|
|
},
|
|
ip_address=request.client.host if request.client else None,
|
|
user_agent=request.headers.get("user-agent"),
|
|
)
|
|
return success_response(result)
|