from tht.execute import ExecResult, PlanSummary from tht.sqlcheck import CheckResult NOTE_HEADING = "## Note del reviewer" def _markdown_table(columns: list[str], rows: list[tuple]) -> str: lines = [ "| " + " | ".join(columns) + " |", "|" + "---|" * len(columns), ] for row in rows: lines.append("| " + " | ".join(str(v) for v in row) + " |") return "\n".join(lines) def render_validation_report( *, session_id: str, check: CheckResult, plan: PlanSummary, plan_warnings: list[str], result: ExecResult, runtime_warnings: list[str], static_warnings: list[str], limit: int, reviewer_notes: str = "", ) -> str: """Sezioni fattuali del validation report. La sezione note e' di Pi/reviewer: se gia' scritta, va passata in reviewer_notes per preservarla.""" def warn(ws: list[str]) -> str: return "\n".join(f"- warning: {w}" for w in ws) if ws else "- nessun warning" parts = [ f"# Validation report — {session_id}", "", "> Avvertenza: questo report contiene sample di dati del database.", "", "## Parsing e read-only", "", "- parsing: OK" if check.ok else "- parsing: ERRORI", "- statement read-only per struttura: OK" if check.ok else "\n".join(f"- ERRORE: {e}" for e in check.errors), warn(check.warnings + static_warnings), "", "## Piano di esecuzione", "", f"- costo totale stimato: {plan.total_cost}", f"- righe stimate: {plan.plan_rows}", f"- nodi: {', '.join(plan.node_types)}", warn(plan_warnings), "", "## Preview / aggregato", "", f"- tempo di esecuzione: {result.execution_ms} ms (limit {limit})", "", _markdown_table(result.columns, result.rows), "", warn(runtime_warnings), "", NOTE_HEADING, "", reviewer_notes.strip(), "", ] return "\n".join(parts) def extract_reviewer_notes(report_md: str) -> str: """Estrae il contenuto della sezione note da un report esistente.""" if NOTE_HEADING not in report_md: return "" return report_md.split(NOTE_HEADING, 1)[1].strip()