Skip to content

#102 — explore view toggle (CTE ⇄ model) + tests.html unit-test viewer - #221

Merged
cmbays merged 4 commits into
mainfrom
adapters-102-explore-view-toggle
Jun 11, 2026
Merged

cmbays merged 4 commits into
mainfrom
adapters-102-explore-view-toggle

Conversation

@cmbays

@cmbays cmbays commented Jun 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Epic #99 V3. Closes #102

  • dag.html — CTE ⇄ model view toggle. The toolbar gains a two-arm toggle. The lineage view stays the boot view; the CTE arm renders the selected model's CTE DAG with the same vendored Cytoscape core + cytoscape-dagre layout the lineage view uses (no new asset). The carrier (explore-dag-data) gains a cte_dags map — full model node id → the same DagPayload the report renders for that model (role-classified nodes, join-typed edges; the build_payload reuse seam, parsed once in Rust). A new first-party engine (templates/explore-cte.js, banner-pinned cute-dbt explore CTE engine v1) owns the toggle + CTE render.
  • tests.html — unit-test viewer. The page now renders the unit-test card through a shared askama partial (templates/partials/test-card.html) extracted from report.html and included by both pages — not a fork. A new light engine (templates/explore-tests.js, cute-dbt explore tests viewer v1) fills the card from the embedded cute-dbt-data payload: selector optgrouped by model, Given/Expected grids off the Rust FixtureTable POD (NULL/absent cell vocabulary preserved), sql-format code blocks, external-fixture provenance notes, and index-row jump buttons. The page embeds no Cytoscape, no dagre, no Mermaid, no DataTables, no jQuery and passes the zero-egress gate on its own.
  • BDD: features/explore_view_toggle.feature + tests/steps/explore_view_toggle.rs; feature-count mirror bumped 17 → 18 in BOTH ci.yml and lefthook.yml atomically (verified 18 in tree).

CTE-view binding decision (documented per the slice brief)

The CTE view binds to the highlighted model — the same in-page selection that click / fuzzy-search-select drives (a Space focus commit implies a highlight, so a committed model is always viewable). With no highlight the CTE arm is disabled (the hint says so); while the CTE view is active a search-select retargets it in place, and a cleared highlight falls back to the lineage view. Chrome + selection persist: the lineage Cytoscape instance is never rebuilt — only cy.resize() runs after un-hiding, so pan/zoom/highlight survive the round trip (proven headlessly). The CTE instance rebuilds only on model retarget (the cyto-dag.js model-switch precedent). data-selected-model stays Space-commit-only — explore-cte.js never writes it (pinned by an asset_embed test).

Fail-open contract

An uncompiled model (dbt parse) ships no cte_dags entry; the client renders a labeled degraded CTE view (" has no compiled SQL in this manifest (dbt parse) — run dbt compile…"), never an error. A compiled CTE-less model renders the "no CTE structure" sparse state. PreflightError keeps its four variants.

Discovery answer — what extracted cleanly vs stayed report-specific

report.html's unit-test rendering is split across static skeleton markup and JS-driven payload rendering (interaction.js):

  • Extracted cleanly (the shared partial): the entire static skeleton — the .test-section card (test selector, scope toggle, badges row, description, details body) plus the .panel-row Given/Expected panel pair. It contains zero askama expressions, so one partial serves both template contexts verbatim. The include is output-preserving: askama strips the included file's final newline, so the parent restores the separating blank line — all three report goldens regenerate byte-identical (verified, and gated by example-report-check).
  • Stayed report-specific (deliberately NOT extracted): everything dynamic in interaction.js — selector population tied to the model-select/scope state, diff toggles/tints (explore is full-manifest: no changed-set, no PR diff), DataTables enhancement, the YAML drawer, copy buttons, settings wiring. Per the lane boundary, interaction.js and report.css are untouched; tests.html gets a NEW explore-specific explore-tests.js (no jQuery/DataTables) and styles the shared markup with explore-local CSS. The partial's scope toggle (Updated only / All tests) is meaningless on a full-manifest page — it is hidden via explore-page CSS, not forked out of the shared markup.
  • Also reused rather than re-implemented: the FixtureTable POD cell contract ({display, key}, diff: show authored cell values — split cell IR into display/equality axes + POD-render fixture tables #138) and the cte_dags map reuses DagPayload directly (no parallel type).

Invariants held

Gate evidence (run directly in the worktree — lefthook skips in fresh worktrees)

Gate Result
cargo fmt --all --check exit 0
cargo clippy --all-targets --locked -- -D warnings exit 0 (judged by exit code)
cargo nextest run --all-targets --locked 1143 passed, 49 skipped (ignored headless)
cargo test --test bdd 132 scenarios / 836 steps passed (4 new)
cargo test --test headless_zero_egress -- --ignored 7 passed (incl. the 2 new #102 tests + per-page explore gates)
cargo test --test headless_toggle -- --ignored 42 passed
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --document-private-items --locked exit 0
cargo deny check exit 0
Report goldens (jaffle-shop, playground, diff-showcase) regenerated → byte-identical to committed (the partial extraction is output-preserving)
Explore goldens regenerated + committed; double-render byte-identical; git diff -- examples/ audited (only examples/explore/* changed)
insta intended-only (nextest green, no pending snapshots)
crap4rs v0.4.0 (CI-pinned, --config crap4rs.toml --coverage lcov.info) 1677 functions, 0 above threshold, worst 23.0 — PASS
feature-count mirror 18 in tree == ci.yml == lefthook.yml
baseline-required-grep awk mirror exit 0

🤖 Generated with Claude Code


Open in Stage

github-actions Bot and others added 3 commits June 11, 2026 01:31
…viewer via shared test-card partial (#102)

dag.html gains a two-arm view toggle: the lineage view (boot) and the
highlighted model's CTE DAG, rendered by the same vendored Cytoscape +
dagre engine (templates/explore-cte.js). The carrier's new cte_dags map
ships one DagPayload per CTE-bearing compiled model — the exact
role-classified, join-typed graph the report renders (build_payload
reuse seam, parsed once). An uncompiled model ships no entry and renders
the labeled fail-open degraded view, never an error; PreflightError
stays four variants. The lineage instance is never rebuilt, so its
pan/zoom/highlight persist across toggles (local state, same page).

tests.html now serves the unit-test viewer through a SHARED askama
partial (templates/partials/test-card.html) extracted from report.html
output-preservingly (the report goldens stay byte-identical) and filled
client-side by templates/explore-tests.js from the embedded
cute-dbt-data payload — no jQuery, no DataTables, no graph engine on
the page; createElement+textContent only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ts-viewer gates (#102)

features/explore_view_toggle.feature + its step module assert the
render-time surface: the gated toggle DOM, the per-model cte_dags
carrier (present for CTE-bearing models, absent for uncompiled — the
fail-open contract), the shared test-card partial on tests.html, the
index-row viewer wiring, the no-Cytoscape posture and the resource-ref
zero-egress scan. ExploreModelDecl grows compiled_sql so scenarios can
author a WITH clause.

The headless suite gains two real-Chromium file:// tests: the CTE/model
toggle (disabled-until-highlight, CTE render off the carrier, lineage
state persistence across the round trip, the labeled degraded view,
console-clean + zero external requests) and the tests.html viewer
(selector population, FixtureTable grid with the NULL-cell vocabulary,
expected row count, index jump wiring, no cytoscape global). The
committed-pages liveness oracle now also asserts the viewer booted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Both mirrors move atomically: the ci.yml feature-count job and the
lefthook.yml pre-push hook (expected=18), with the history comments
extended.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai

coderabbitai Bot commented Jun 11, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

@cmbays, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 7 minutes and 12 seconds. Learn how PR review limits work.

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4e1e2183-10af-4bd8-8d9b-a58e2b92f792

📥 Commits

Reviewing files that changed from the base of the PR and between 15e308a and d794d6a.

📒 Files selected for processing (20)
  • .github/workflows/ci.yml
  • examples/explore/dag.html
  • examples/explore/tests.html
  • features/explore_view_toggle.feature
  • lefthook.yml
  • src/adapters/asset_embed.rs
  • src/adapters/explore.rs
  • src/adapters/render.rs
  • templates/explore-cte.js
  • templates/explore-dag.html
  • templates/explore-lineage.js
  • templates/explore-tests.html
  • templates/explore-tests.js
  • templates/partials/test-card.html
  • templates/report.html
  • tests/headless_zero_egress.rs
  • tests/steps/explore_full_manifest.rs
  • tests/steps/explore_view_toggle.rs
  • tests/steps/mod.rs
  • tests/steps/world.rs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch adapters-102-explore-view-toggle

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ghost

ghost commented Jun 11, 2026 •

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jun 11, 2026 •

Copy link
Copy Markdown
Contributor

📄 Rendered report preview

All golden examples regenerated cleanly.

🟡 Golden examples

Committed to examples/ and byte-identity gated — the canonical reports contributors and consumers browse. Stable across PRs.

Report View Download
playground-report.html ▶ Open ↗ ⬇ Download
jaffle-shop-report.html ▶ Open ↗ ⬇ Download
diff-showcase-report.html ▶ Open ↗ ⬇ Download

🐶 Live dogfood preview

This PR doesn't touch dbt-project/, so there's no live dogfood preview.

▶ Open ↗ opens the report in your browser in one click —
published to this repo's GitHub Pages under /pr-221/.
⬇ Download fetches the same self-contained HTML as a workflow
artifact (auth-gated; works fully offline). Either way the report
makes zero external resource requests.

The Pages preview may take ~1 min to update after this comment
posts. On PRs from forks the Open link is unavailable (read-only
token) — use Download.

Alternative: GitHub CLI
# gh CLI >= 2.63 extracts into ./report-preview-playground/.
gh run download 27326277741 -R breezy-bays-labs/cute-dbt -n report-preview-playground
open report-preview-playground/playground-report.html

Posted by report-preview.yml for d794d6a7dfb14caf6484d47b956103653172557d. Affordance only — never blocks merge.

@cmbays
cmbays merged commit f84cb5e into main Jun 11, 2026
57 of 58 checks passed
@cmbays
cmbays deleted the adapters-102-explore-view-toggle branch June 11, 2026 05:44
github-actions Bot added a commit that referenced this pull request Jun 11, 2026
cmbays added a commit that referenced this pull request Jun 11, 2026
#222)

A Coverage intelligence switch in the report settings panel (default ON,
keyboard-operable checkbox per the #146 a11y discipline). OFF sets
html[data-coverage=off] and ONE report.css rule hides the .model-findings
panel — the only check-engine-derived surface in the report (checklist,
tier chips, suppressed-count reveal all live inside it). Purely a DISPLAY
toggle: the payload and rendered DOM stay untouched, so ON restores in
place with zero re-render.

Wired + persisted by theme.js as the coverage field of
cute-dbt.appearance.v1 ("on"/"off", absent = "on") — the same
mechanism as theme/density/the engine picker, and the cross-page contract
the explorer arm (#103/#104) adopts when check-derived content lands
there. Distinct from the producer-side [checks] selection/suppression
(#171): checks stay computed; an individual viewer hides the surface.

Headless guard: default-ON boot, focus + REAL Space keypress toggles OFF
(findings hidden, checklist rows stay in the DOM), click restores ON,
persistence across reload. Goldens regenerated (delta = settings markup +
theme.js + css only; explore pages untouched); insta snapshots accepted
intended-only.

Part of #219 (explorer arm deferred — no check-derived content renders
on the explore pages yet, and #221 owns their templates this cycle).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feature: explore view toggle (CTE/model) + tests.html unit-test viewer

1 participant