fix: harden forensic report ingestion
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models.domain import Domain
|
||||
@@ -10,7 +11,7 @@ from app.utils.domain_validator import DomainValidationError, validate_domain
|
||||
|
||||
def forensic_report_exists(db: Session, report_id: str) -> bool:
|
||||
"""Return True when a forensic report ID is already persisted."""
|
||||
if not report_id:
|
||||
if not str(report_id or "").strip():
|
||||
return False
|
||||
return (
|
||||
db.query(ForensicReport.id).filter(ForensicReport.report_id == report_id).first()
|
||||
@@ -40,7 +41,10 @@ def save_forensic_report(db: Session, report: Dict[str, Any]) -> tuple[ForensicR
|
||||
Returns ``(row, created)``. The caller owns the transaction and should
|
||||
commit after related work has completed.
|
||||
"""
|
||||
report_id = str(report.get("report_id") or "")
|
||||
report_id = str(report.get("report_id") or "").strip()
|
||||
if not report_id:
|
||||
raise ValueError("Forensic report_id is required")
|
||||
|
||||
existing = db.query(ForensicReport).filter(ForensicReport.report_id == report_id).first()
|
||||
if existing is not None:
|
||||
return existing, False
|
||||
@@ -72,12 +76,26 @@ def save_forensic_report(db: Session, report: Dict[str, Any]) -> tuple[ForensicR
|
||||
feedback_headers=feedback_headers,
|
||||
)
|
||||
db.add(row)
|
||||
db.flush()
|
||||
try:
|
||||
db.flush()
|
||||
except IntegrityError:
|
||||
db.rollback()
|
||||
existing = db.query(ForensicReport).filter(ForensicReport.report_id == report_id).first()
|
||||
if existing is not None:
|
||||
return existing, False
|
||||
raise
|
||||
return row, True
|
||||
|
||||
|
||||
def forensic_report_to_dict(row: ForensicReport) -> Dict[str, Any]:
|
||||
"""Convert a forensic report row to an API-safe dictionary."""
|
||||
feedback_headers = {}
|
||||
if row.feedback_headers:
|
||||
try:
|
||||
feedback_headers = json.loads(row.feedback_headers)
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
feedback_headers = {}
|
||||
|
||||
return {
|
||||
"id": row.id,
|
||||
"report_id": row.report_id,
|
||||
@@ -98,6 +116,6 @@ def forensic_report_to_dict(row: ForensicReport) -> Dict[str, Any]:
|
||||
"original_subject": row.original_subject,
|
||||
"original_message_id": row.original_message_id,
|
||||
"original_date": row.original_date,
|
||||
"feedback_headers": json.loads(row.feedback_headers) if row.feedback_headers else {},
|
||||
"feedback_headers": feedback_headers,
|
||||
"processed_at": row.processed_at.isoformat() if row.processed_at else None,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user