51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
from collections import Counter
|
|
|
|
from review_agent.models import RegulatoryIssue, RegulatoryReviewBatch
|
|
from review_agent.regulatory_review.schemas import Finding
|
|
|
|
from .rag_citation import retrieve_citations
|
|
|
|
|
|
SEVERITY_ORDER = ["blocking", "high", "medium", "low", "info"]
|
|
|
|
|
|
def persist_findings(batch: RegulatoryReviewBatch, findings: list[Finding]) -> list[RegulatoryIssue]:
|
|
RegulatoryIssue.objects.filter(batch=batch).delete()
|
|
unique = {}
|
|
for finding in findings:
|
|
unique.setdefault((finding.rule_code, finding.category, finding.title), finding)
|
|
|
|
issues = []
|
|
for finding in unique.values():
|
|
citations = finding.citations or _safe_citations(finding)
|
|
issues.append(
|
|
RegulatoryIssue.objects.create(
|
|
batch=batch,
|
|
rule_code=finding.rule_code,
|
|
category=finding.category,
|
|
severity=finding.severity,
|
|
title=finding.title,
|
|
detail=finding.detail,
|
|
suggestion=finding.suggestion,
|
|
evidence=finding.evidence,
|
|
citations=citations,
|
|
)
|
|
)
|
|
batch.risk_summary = _risk_summary(issues)
|
|
batch.save(update_fields=["risk_summary"])
|
|
return issues
|
|
|
|
|
|
def _safe_citations(finding: Finding) -> list[dict[str, object]]:
|
|
try:
|
|
return retrieve_citations(finding.title)
|
|
except Exception:
|
|
return [{"source": "原文依据待补充", "text": "RAG 索引不可用或无命中", "score": None}]
|
|
|
|
|
|
def _risk_summary(issues: list[RegulatoryIssue]) -> dict[str, int]:
|
|
counts = Counter(issue.severity for issue in issues)
|
|
return {severity: counts.get(severity, 0) for severity in SEVERITY_ORDER}
|