{# Integrity report HTMX fragment (S-133).
Rendered by ``dbsprout.web.routers.validate.validate_run`` when the request
carries ``HX-Request: true``. The panel surfaces a clean "pass" state when no
violations exist, and a per-table summary plus detail rows when there are
violations. Detail rows carry stable ``data-table`` / ``data-column`` /
``data-row`` attributes so the S-135 drill-down can wire ``studio:focus-cell``
events on click.
Variables:
* ``no_run`` (bool) — render the 409 NO_RUN state when ``True``.
* ``message`` (str | None) — friendly message for the NO_RUN state.
* ``summary`` (dict | None) — ``{tables, rows, violations}``.
* ``by_table`` (list[dict]) — per-table counters.
* ``details`` (list[dict]) — capped at ``max_detail_rows`` failed checks.
* ``max_detail_rows`` (int) — cap echoed in the header when truncated.
* ``fidelity`` (dict | None) — ``{overall_score, passed, metrics}`` (S-134); omit when ``None``.
* ``detection`` (dict | None) — ``{overall_score, passed, metrics}`` (S-134); omit when ``None``.
#}
{% if no_run %}
NO_RUN — no generation result yet
{{ message }}
{% else %}
Integrity report
{% if summary.violations == 0 %}
0 violations — all checks passed
{% else %}
{{ summary.violations }} violations
{% endif %}
Validated {{ summary.tables }} table(s), {{ summary.rows }} row(s).
| Table |
FK |
UNIQUE |
NOT NULL |
CHECK |
{% for row in by_table %}
{{ row.table }} |
{{ row.fk_violations }} |
{{ row.unique_violations }} |
{{ row.not_null_violations }} |
{{ row.check_violations }} |
{% endfor %}
{% if details %}
Violation details
{% if details|length >= max_detail_rows %}
truncated to first {{ max_detail_rows }}
{% endif %}
| Check |
Table |
Column |
Details |
{% for d in details %}
| {{ d.check }} |
{{ d.table }} |
{{ d.column }} |
{{ d.details }} |
{% endfor %}
{% endif %}
{# S-134: Fidelity block — only rendered when source-data reference rows are available. #}
{% if fidelity %}
Fidelity
{% if fidelity.passed %}
overall {{ "%.3f"|format(fidelity.overall_score) }}
{% else %}
overall {{ "%.3f"|format(fidelity.overall_score) }}
{% endif %}
{% if fidelity.metrics %}
| Metric |
Table |
Column |
Score |
{% for m in fidelity.metrics %}
| {{ m.metric }} |
{{ m.table }} |
{{ m.column }} |
{{ "%.3f"|format(m.score) }} |
{% endfor %}
{% endif %}
{% endif %}
{# S-134: Detection block — C2ST classifier accuracy per table. Lower = better. #}
{% if detection %}
Detection
{% if detection.passed %}
overall {{ "%.3f"|format(detection.overall_score) }}
{% else %}
overall {{ "%.3f"|format(detection.overall_score) }}
{% endif %}
{% if detection.metrics %}
| Metric |
Table |
Accuracy |
{% for m in detection.metrics %}
| {{ m.metric }} |
{{ m.table }} |
{{ "%.3f"|format(m.accuracy) }} |
{% endfor %}
{% endif %}
{% endif %}
{% endif %}
{# ── S-135 boot: wire violation rows → studio:focus-cell window event.
The fragment self-bootstraps so HTMX swaps (POST /api/validate replaces
the panel in place) re-wire the dispatcher on each render. #}