{# Storage Billing recommendations - dataset-level LOGICAL→PHYSICAL switches surfaced from the ``storage_billing_optimization`` rule. Each card shows the savings, current vs. proposed cost, a per-table breakdown, and a copyable ALTER SCHEMA snippet. #} {% extends "layout.html" %} {% block content %}

Storage Billing

{# Info-icon toggle. Same pattern as the Audit AI page: the description is one click away but doesn't take up space on every render. Aria wiring keeps it screen-reader-usable. #}
{# Page-description toggle. Runs unconditionally (not gated by any state) so it works even on first paint. #} {% if not recommendations %}

No material storage billing savings

No dataset clears the ${{ "%.2f" | format(materiality_usd) }}/month switch-saving threshold - every dataset is already on PHYSICAL billing, compresses too poorly for PHYSICAL to help, or saves only a trivial amount. Every scanned dataset is still listed below so you can see the full picture.

{% else %} {# Scan-period disclaimer. Unlike query-based findings, storage billing figures are a point-in-time snapshot of dataset size at the latest scan - the period selector at the top of the page (e.g. "30d") doesn't apply here. Subtle blue banner so it reads as info, not warning. #}

Heads up: The selected scan period doesn't apply to storage figures. These cards reflect the dataset's current size at the time of the latest scan and the resulting monthly cost projection - they would look the same regardless of whether you scanned over 7, 30, or 180 days.

{# Roll-up strip - total opportunity across all flagged datasets. Uses the standard stat_card macro so the label / value / accent typography matches the dashboard, /opportunities, and /opportunities/{id} stat strips 1:1 (was inline ad-hoc before). #} {% from "components/_stat_card.html" import stat_card %}
{{ stat_card("Datasets flagged", recommendations | length) }} {{ stat_card("Total monthly savings", "$" ~ ("%.2f" | format(total_monthly_savings)), accent="emerald") }} {{ stat_card("Total annual savings", "$" ~ ("%.2f" | format(total_annual_savings)), accent="emerald") }}
{% if below_threshold_count %}

{{ below_threshold_count }} more dataset{{ 's' if below_threshold_count != 1 else '' }} have a positive but immaterial saving (under ${{ "%.2f" | format(materiality_usd) }}/mo) - see the full list below.

{% endif %} {# Two cards per row at lg+; single column on narrow viewports so the ALTER SCHEMA snippet and per-table table still have room to render without horizontal scroll. The internal stat-strip is already `grid-cols-2 sm:grid-cols-4` so it adapts to the narrower half-width column automatically. #}
{% for rec in recommendations %}
{# Header row: dataset (left) + headline saving (right). Intentionally NOT using ``ui-section-title`` / ``ui-card-value`` here - those force-uppercase the dataset name and inflate the headline to the same scale as the page-level roll-up above, making each card feel as heavy as a top-level section. Compact typography keeps the card scannable in the 2-column grid. #}

{{ rec.affected_table }}

{{ rec.table_count }} table{{ '' if rec.table_count == 1 else 's' }} · {{ '%.1f' | format(rec.compression_ratio) }}:1 compression

Monthly saving

${{ '%.2f' | format(rec.monthly_savings) }}

{{ '%.1f' | format(rec.savings_percentage) }}% reduction

{# Cost comparison strip - compact inline typography (no nested card chrome). Smaller than ``ui-card-value`` so the four numbers fit comfortably in the half-width card. #}

Current (logical)

${{ '%.2f' | format(rec.logical_cost_monthly) }}/mo

After switch (physical)

${{ '%.2f' | format(rec.physical_cost_monthly) }}/mo

Logical bytes

{{ '%.2f' | format(rec.total_logical_gb) }} GB

Physical bytes

{{ '%.2f' | format(rec.total_physical_gb) }} GB

{# ALTER SCHEMA snippet - same visual treatment as the BigQuery query lookup on the opportunity detail page (bordered surface + per-snippet Copy button), but without the
/ chrome since the "Apply" label above already names the block and a single ALTER SCHEMA line doesn't warrant a collapsible. ``whitespace-pre-wrap break-all`` lets the dataset name wrap onto a second line when the card is half-width instead of overflowing. #}

Apply

ALTER SCHEMA `{{ rec.affected_table }}` SET OPTIONS (storage_billing_model = 'PHYSICAL');
{# Per-table breakdown - collapsed by default to keep the card scannable. Tables with no savings still show so the user can see the full dataset shape. #} {% if rec.tables %}
Show per-table breakdown ({{ rec.tables | length }} table{{ '' if rec.tables|length == 1 else 's' }})
{% for t in rec.tables %} {% endfor %}
Table Logical GB Physical GB Compression Monthly saving
{{ t.table_name }} {{ '%.2f' | format(t.total_logical_gb) }} {{ '%.2f' | format(t.total_physical_gb) }} {{ '%.1f' | format(t.compression_ratio) }}:1 ${{ '%.2f' | format(t.monthly_savings) }}
{% endif %}
{% endfor %}
{# Copy-by-id helper, idempotent and shared with sql_panel callers. This page doesn't use the sql_panel macro (it'd add a heavy
/ chrome around a single ALTER SCHEMA line), so we register the helper locally. The macro's own definition guards on ``if (window.auditCopyById) return;`` so loading both is safe. #} {% endif %} {# ── All scanned datasets ────────────────────────────────────────── Every dataset the scan touched, so nothing looks silently dropped: material switches (cards above), immaterial savings, and datasets already on PHYSICAL billing or with no saving. #} {% if all_datasets %}
{% from "components/_section_title.html" import section_title %} {{ section_title("All scanned datasets", description="Every dataset in the latest scan - " ~ (all_datasets | length) ~ " total. The cards above highlight the material switches; this lists them all, including datasets already on PHYSICAL billing or with no material saving.") }}
{% for d in all_datasets %} {% endfor %}
Dataset Billing Tables Logical GB Physical GB Compression Monthly saving
{{ d.dataset }} {{ d.billing_model }} {{ d.table_count }} {{ '%.2f' | format(d.logical_gb) }} {{ '%.2f' | format(d.physical_gb) }} {% if d.compression_ratio %}{{ '%.1f' | format(d.compression_ratio) }}:1{% else %}-{% endif %} {% if d.state == 'already_physical' %} already physical {% elif d.monthly_savings > 0 %} ${{ '%.2f' | format(d.monthly_savings) }}/mo {% else %} - {% endif %}
{% endif %}
{% endblock %}