{# Audit's object-overview detail page. Lists EVERY active issue + EVERY available SQL-rewrite suggestion for the requested opportunity's destination_table - not just one rule's findings. The cohort view at /jobs/{table} stays as the deep-dive (cost chart, Query versions). PR / dry-run / shadow surfaces are deliberately absent - audit is read-only and never generates solutions. #} {% extends "layout.html" %} {% block content %} {% from "components/_page_header.html" import back_link, header_card %} {# Hoisted from per-section conditional blocks because Jinja {% from %} scope is the enclosing block: when issue_cards is empty (suggestion- only opportunity) the issue-section's import never fires, but later sections like Available improvements still reference the macro - produces ``'section_title' is undefined``. Hoisting once at the top of the content block makes the macro available everywhere below. #} {% from "components/_section_title.html" import section_title %} {% from "components/_signal_chip.html" import signal_chip %}
{{ back_link("/opportunities", "Issues & Suggestions") }} {% set _path_parts = (row.affected_table or '').split('.') %} {% set _dataset = _path_parts[1] if _path_parts | length >= 2 else '' %} {% set _table = _path_parts[2] if _path_parts | length >= 3 else (row.affected_table or '') %} {% set _title %}{% if _dataset %}{{ _dataset }}.{% endif %}{{ row.dbt_model_name or _table }}{% endset %} {% call header_card(_title) %} {# Build vs consumption - same classification the dashboard uses (build = writes a destination; consumption = read-only). Makes it explicit on the detail page which kind of workload this is. #} {% if row.query_workload_kind == 'build' %} {{ signal_chip("Build", color="brand", title="Build - this query writes a destination table") }} {% elif row.query_workload_kind == 'consumption' %} {{ signal_chip("Consumption", color="teal", title="Consumption - read-only query, no destination written") }} {% endif %} {% if issue_cards %} {% for issue in issue_cards[:3] %} {{ signal_chip(issue.display_name, color="rose", title="Issue found on this object") }} {% endfor %} {% if issue_cards | length > 3 %} {{ signal_chip("issues", color="rose", overflow=("+" ~ (issue_cards | length - 3)), title="More issue rules found on this object") }} {% endif %} {% endif %} {% if row.dbt_model_name %} dbt {% endif %} {% if row.author_email %} {% set _author_label %}{{ row.author_email }}{% endset %} {{ signal_chip(_author_label, color="slate") }} {% endif %} {# Spec 156 - origin chip in the header. Mirrors the Origin column on /opportunities. Click filters the workspace to this origin. Suppress it when it would just duplicate the green "dbt" marker above (origin 'dbt' on a dbt model) - keep it for Looker / Hex / Fivetran / etc. where it adds information. #} {% if row.origin_tool and row.origin_tool != 'ad_hoc' and not (row.origin_tool == 'dbt' and row.dbt_model_name) %} {% set _origin_label %}{{ row.origin_tool | replace('_', ' ') }}{% endset %} {{ signal_chip(_origin_label, color="slate") }} {% endif %} {% endcall %} {# "What changed" signal for the current query version - the same chips the /jobs version cards show. A resolved rule (e.g. "cross join unaggregated resolved") is good news: it fired on an earlier version and the current query no longer triggers it. This is why the suggestion count can be 0 here while /jobs' history shows the rule - it was already fixed. #} {% if resolved_rules_current or new_rules_current %}
{% for rt in resolved_rules_current %} {{ rt | replace('_', ' ') }} resolved in current version {% endfor %} {% for rt in new_rules_current %} {{ rt | replace('_', ' ') }} new in current version {% endfor %}
{% endif %} {%- set _runs = row.execution_count or 1 -%} {%- set _last_ts = latest_job.creation_time.strftime("%Y-%m-%d %H:%M UTC") if (latest_job and latest_job.creation_time) else "" -%} {%- set _agg_bytes = row.aggregated_bytes_processed or (job.total_bytes_processed if job else none) -%} {%- set _agg_slot_ms = row.aggregated_slot_time_ms or (job.total_slot_ms if job else none) -%} {%- set _cost_meta = ( "last " ~ ((latest_job.total_cost or 0) | float | format_usd) ~ ((" · " ~ _last_ts) if _last_ts else "") ) if latest_job else None -%} {%- set _bytes_meta = ( "last " ~ (latest_job.total_bytes_processed | format_bytes) ~ ((" · billed " ~ (latest_job.total_bytes_billed | format_bytes)) if latest_job.total_bytes_billed is not none else "") ) if (latest_job and latest_job.total_bytes_processed is not none) else None -%} {%- set _slot_meta = ( ("last " ~ (latest_job.duration_ms | format_duration) ~ " wall") if (latest_job and latest_job.duration_ms is not none) else None ) -%} {%- set _primary_issue = issue_cards[0] if issue_cards else none -%} {%- set _primary_materialization = none -%} {% if audit_mv_candidates %} {% set _primary_materialization = audit_mv_candidates[0] %} {% elif bq_mv_recommendations %} {% set _primary_materialization = bq_mv_recommendations[0] %} {% endif %} {%- set _object_label = row.dbt_model_name or _table or row.affected_table -%} {% if _primary_materialization %} {% set _next_step_href = "#recommendations" %} {% elif _primary_issue %} {% set _next_step_href = "#findings" %} {% elif improvements %} {% set _next_step_href = "#sql-changes" %} {% else %} {% set _next_step_href = "#technical-details" %} {% endif %}

Recommended next step

{% if _primary_materialization %} Review materialization change {% elif _primary_issue %} Address {{ _primary_issue.display_name }} {% elif improvements %} Review deterministic SQL changes {% else %} Review opportunity evidence {% endif %}

Object {{ _object_label }} · {{ row.query_cost_value | format_usd }} across {{ "{:,}".format(_runs) }} {{ "execution" if _runs == 1 else "executions" }} {% if _primary_issue %} · {{ _primary_issue.action_text }}{% endif %}

{% if issue_cards %} {{ issue_cards | length }} {{ "issue" if issue_cards | length == 1 else "issues" }} {% endif %} {% if improvements %} {{ improvements | length }} SQL {{ "change" if improvements | length == 1 else "changes" }} {% endif %} {% if _primary_materialization %} materialization signal {% endif %} Open section
{# Cohesive metric strip - one connected band of columns (cost / bytes / slot / executions) rather than separate boxes. Big aggregated value up top, latest-execution detail on the muted line beneath. #}

Cost

{{ row.query_cost_value | format_usd }}

{% if _cost_meta %}

{{ _cost_meta }}

{% endif %}

Bytes processed

{{ (_agg_bytes | format_bytes) if _agg_bytes is not none else "-" }}

{% if _bytes_meta %}

{{ _bytes_meta }}

{% endif %}

Slot time

{{ ("%.1f" | format((_agg_slot_ms or 0) / 3600000) ~ " hrs") if _agg_slot_ms is not none else "-" }}

{% if _slot_meta %}

{{ _slot_meta }}

{% endif %}

Executions

{{ "{:,}".format(_runs) }}

in scan window

{# Cost trend stays expanded: the chart is useful context rather than noisy forensic detail. #} {% if chart_points_payload %} {% set chart_title = "Cost trend and issues" %} {# Subtitle is derived from the payload granularity inside the partial (per-execution vs daily roll-up). The chart spans every query version, matching the headline cost/executions (both full history) and the /jobs page. Amber rings mark version changes; red points tripped a detection rule. #} {% set chart_collapsible = false %} {% set chart_history_href = "/jobs/" ~ row.affected_table %} {% include "jobs/_cost_chart.html" %} {% endif %} {# Issues found - one decision card per detector/advisory rule surfaced on this table. The card mirrors the Materialization rhythm: Evidence / Action / Impact. SQL rewrite cards stay below only when there is a deterministic before/after change to review. #} {% if issue_cards %}
{{ section_title( "Issues found", description="One card per issue that fired on this table. Each card pairs the detector evidence with the action and expected operational impact.", aside=((issue_cards | length) ~ (' issue' if issue_cards | length == 1 else ' issues')) ) }}
{% for issue in issue_cards %}
{{ signal_chip(issue.display_name, color="rose", title="Issue found on this object") }}

{{ issue.evidence_text }}

Evidence

{{ issue.evidence_text }}

Action

{{ issue.action_text }}

Impact

{{ issue.impact_text }}

{% endfor %}
{% endif %} {% if layout_recommendation or audit_mv_candidates or bq_mv_recommendations or unused_candidates %}
{# Spec 148 - Recommended physical layout. Read-only suggestion of partition + cluster keys based on how the table is queried. The partial gates on ``layout_recommendation`` so a None recommendation produces zero markup. #} {% include "opportunities/_layout_recommendation.html" %} {# Spec 154 v2 - Materialization recommendations folded into the opportunity detail page. Renders one card per audit-detected MV candidate (with generated CREATE MATERIALIZED VIEW SQL) and per BigQuery MV Recommender pass-through. The partial gates on non-empty input lists so it produces zero markup when this table has no MV signals. #} {% include "opportunities/_materialization.html" %} {# Spec 155 - Unused destination table section. Renders when the anchor opportunity_type is "unused_destination_table". The partial gates on a non-empty input list so it produces zero markup otherwise. Kept separate from the Materialization section because the question is different (should the table exist at all? vs. how should it be persisted?). #} {% include "opportunities/_unused_table.html" %}
{% endif %} {# Recommended SQL changes - every SQL-rewrite suggestion that fired on any opportunity for this table, deduped by rule_type. Each is a deterministic rewrite (no LLM) and renders inline as its own green/red diff. #} {% if improvements %}
{{ section_title( "Recommended SQL changes", description="Deterministic before/after rewrites. Expand a row to inspect the diff, original SQL, suggested SQL, and rollback path.", aside=((improvements | length) ~ (' change' if improvements | length == 1 else ' changes')) ) }}
{% for imp in improvements %}
{{ imp.display_name }} {% if imp.template_id %} deterministic rewrite {% endif %} {% if imp.occurrences and imp.occurrences > 1 %} ×{{ imp.occurrences }} {% endif %}

{% if imp.diff_lines or imp.before_content %} Diff, original SQL, and suggested SQL are available. {% else %} Expand for the recommendation details. {% endif %}

{# Only show the explanation prose when there's NO diff to render - the diff already conveys "what changed" visually, and the prose generated by core's templates duplicates the column / CTE names plus a boilerplate "What changed" paragraph that adds nothing. #} {% if imp.explanation and not (imp.diff_lines or imp.before_content) %}

{{ imp.explanation }}

{% endif %} {% if imp.diff_lines or imp.before_content %}
{% if imp.after_content %} {% endif %}
{% if imp.diff_lines %} {% set diff_lines = imp.diff_lines %} {% set file_path = imp.template_id %} {% include "components/code_diff.html" %} {% else %}

No diff available - template did not produce a change.

{% endif %}
{% if imp.after_content %} {% endif %}
{% endif %} {% if imp.rollback %}
Rollback instructions

{{ imp.rollback }}

{% endif %}
{% endfor %}
{% endif %} {# Query fallback - when no suggestion card already carries SQL, the user still needs to see the underlying query so they can manually inspect what's running. Rewrite cards include an "Original SQL" tab; advisory-only cards (slot contention, etc.) do not. Renders only when we have a representative job with a query body. #} {% if not improvements_have_sql and job and job.query %}

Query

No deterministic SQL rewrite is available. Expand only when you need to inspect the latest execution.

minimized
{% for line in job.query.split('\n') %}{{ loop.index }}{{ line }}
{% endfor %}
{% endif %} {# Technical details - raw detector evidence plus the BigQuery lookup SQL. Kept in one minimized drawer so the page leads with decisions and keeps forensic data available on demand. #} {% if visible_evidence or job_lookup_sql %}

Technical details

Raw detector fields and BigQuery lookup SQL for verification.

minimized
{% if visible_evidence %}

Evidence

{% if row.opportunity_type == "slot_contention" and visible_evidence.slot_contention_flag is sameas false and visible_evidence.queue_ratio_percent is defined %}

Slot Contention can be detected from queue time even when BigQuery's explicit slot-contention flag is false. This job waited {{ visible_evidence.queue_time_seconds }}s before running, with {{ visible_evidence.queue_ratio_percent }}% of total elapsed time spent queued.

{% endif %}
{% for key, value in visible_evidence.items() %}
{{ key }}
{% if value is mapping or (value is iterable and value is not string) %} {{ value | tojson }} {% else %} {{ value }} {% endif %}
{% endfor %}
{% endif %} {% if job_lookup_sql %}

Job lookup SQL

Paste into BigQuery to inspect the representative job row.

{{ job_lookup_sql }}
{% endif %}
{% endif %}
{# Generic tab toggler - picks up every ``[data-tab]`` / ``[data-tab-pane]`` pair inside an ancestor with ``[data-active-tab]``. Same script as the cohort page so suggestion cards' Diff / Original SQL tabs work without coupling to the class name. #} {% endblock %}