feat(prospecting): add security audit report generation (Workstream 2B)
- SecurityReportService generates standalone branded HTML reports from
stored audit data (grade badge, simulated hacked site, detailed
findings, business impact, call-to-action with contact info)
- GET /security-audit/report/{prospect_id} returns HTMLResponse
- "Generate Report" button on prospect detail security tab opens
report in new browser tab (printable to PDF)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ catch "batch" as a string before trying to parse it as int → 422.
|
||||
import logging
|
||||
|
||||
from fastapi import APIRouter, Depends, Path, Query
|
||||
from fastapi.responses import HTMLResponse
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.api.deps import get_current_admin_api
|
||||
@@ -34,6 +35,9 @@ from app.modules.prospecting.services.scoring_service import scoring_service
|
||||
from app.modules.prospecting.services.security_audit_service import (
|
||||
security_audit_service,
|
||||
)
|
||||
from app.modules.prospecting.services.security_report_service import (
|
||||
security_report_service,
|
||||
)
|
||||
from app.modules.prospecting.services.stats_service import stats_service
|
||||
from app.modules.tenancy.schemas.auth import UserContext
|
||||
|
||||
@@ -152,6 +156,28 @@ def compute_scores_batch(
|
||||
return ScoreComputeBatchResponse(scored=count)
|
||||
|
||||
|
||||
# ── Report endpoints ────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@router.get("/security-audit/report/{prospect_id}", response_class=HTMLResponse)
|
||||
def security_audit_report(
|
||||
prospect_id: int = Path(...),
|
||||
db: Session = Depends(get_db),
|
||||
current_admin: UserContext = Depends(get_current_admin_api),
|
||||
):
|
||||
"""Generate branded HTML security audit report."""
|
||||
prospect = prospect_service.get_by_id(db, prospect_id)
|
||||
if not prospect.security_audit:
|
||||
from app.exceptions.base import ResourceNotFoundException
|
||||
|
||||
raise ResourceNotFoundException("SecurityAudit", str(prospect_id))
|
||||
html = security_report_service.generate_html_report(
|
||||
audit=prospect.security_audit,
|
||||
domain=prospect.domain_name,
|
||||
)
|
||||
return HTMLResponse(content=html)
|
||||
|
||||
|
||||
# ── Single-prospect endpoints ───────────────────────────────────────────────
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user