Skip to content

[HDX-5080] Chart editor UI for metric formulas - #2909

Merged
kodiakhq[bot] merged 4 commits into
mainfrom
warren/HDX-5080-render-metric-formula-UI
Aug 20, 2026
Merged

[HDX-5080] Chart editor UI for metric formulas#2909
kodiakhq[bot] merged 4 commits into
mainfrom
warren/HDX-5080-render-metric-formula-UI

Conversation

@wrn14897

@wrn14897 wrn14897 commented Aug 14, 2026

Copy link
Copy Markdown
Member

Summary

Exposes metric formulas (HDX-5078's formulas config, rendered by HDX-5079) in the chart editor for metric sources, so a derived series like A / (A + B + C) * 100 can be built, validated, saved, and reloaded from the UI.

Rebased onto main now that #2908 (HDX-5079 rendering) has merged.

Editor

  • Formula rows (ChartFormulaEditor) on metric-source builder charts (time series / table / number): "Add Formula" appends a row with a monospace letter-ref expression input, an alias, a per-formula number format (reuses the per-series format drawer), and "Remove Formula".
  • Inline validation with the structured validator from HDX-5078 (validateFormula): malformed expressions, unknown series refs, constant-only expressions, etc. surface live under the input; validateChartForm blocks save/run with the same messages so an invalid expression can never reach ClickHouse.
  • Letter badges (A, B, C, ...) on metric series rows so formula refs are discoverable.
  • "Show input series" toggle drives showOperandSeries (formula + raw operand series vs formula column(s) only). Adding a formula on a Number tile defaults operands to hidden, since Number tiles render the first value column.
  • Mutual exclusion with ratio: the "As Ratio" switch is hidden while a formula exists, and "Add Formula" is hidden while ratio mode is on (formulas supersede ratio in the renderer).
  • The Number-tile series cap (1, or 2 for ratio) is lifted when formulas exist, so operand-only series like A / (A + B + C) can be built.
  • normalizeChartConfig strips formulas/showOperandSeries on save for non-metric sources and for display types the composed metric query does not render (pie/bar/heatmap/search/patterns), mirroring the existing metricName/having stripping. The form state keeps them, so switching back restores the rows.

Rendering consumers (positional value-column contract)

The composed metric query projects operand columns (unless hidden) then formula columns, ahead of group-by passthrough columns. Updated the consumers that map columns positionally:

  • useChartNumberFormats: operand columns → select[i].numberFormat, formula columns → formulas[j].numberFormat, both falling back to the chart-wide format; chart-wide axis format prefers formula formats when operands are hidden.
  • New getBuilderValueColumnCount helper (formula/ratio-aware) used by DBTableChart for group-by column inference; per-column color mapping skips hidden-operand formula configs.
  • DBTimeChart drill-down skips the value-range filter when operands are hidden (formula columns don't map onto select expressions).
  • Legend/tooltip naming needs no changes — formula columns arrive as named result columns (alias || expression).

Persistence needs no API changes: tiles validate against SavedChartConfigSchema, which already carries formulas/showOperandSeries, and builderToRawSql already rejects formula configs with a clear message on the Builder → SQL switch.

Alerts on formula tiles (packages/api)

Contrary to #2908's "alerts work with no changes" claim, the alert task does not run the tile config as-is — getChartConfigFromAlert rebuilds it from an explicit field list that dropped formulas/showOperandSeries. An alert on a formula tile therefore queried only the raw operand series and compared the threshold against the last operand's value (e.g. 740442112.0 meets or exceeds 0.1 for a byte-valued operand), regardless of the tile's "Show input series" toggle. Fixed here:

  • formulas is passed through, and operand columns are always dropped from the alert query (showOperandSeries: false) so the formula is the value column parseAlertData picks — the alert evaluates exactly what the tile displays.
  • Drive-by with the same omission shape: ratioMode is now passed through, so grouped share_of_total ratio tile alerts no longer silently evaluate as per_group.
  • New integration tests (make dev-int FILE=checkAlerts, 168 passing): formula value drives the alert (fixture chosen so the formula result differs from both operands), toggle-independence, NULL formula (zero denominator) skipped without NaN history, and share_of_total honored (asserting the exact share value a per_group fallback couldn't produce).

Testing

  • make ci-lint, make ci-unit pass.
  • New unit tests:
    • DBEditTimeChartForm.test.tsx: Add/Remove Formula, inline validation (malformed / unknown ref / clears when fixed), save round-trip, save blocked on invalid expression, ratio mutual exclusion, showOperandSeries toggle, non-metric sources show no formula controls.
    • ChartEditor/utils.test.ts: validateChartForm formula rules (including the Number-tile cap lift) and normalization stripping/round-trip.
    • source.test.ts: useChartNumberFormats formula-column mapping (operands shown/hidden, ratio precedence, chart-format fallbacks) and getBuilderValueColumnCount.
  • New dashboard E2E (make dev-e2e FILE=dashboard GREP="Metric formulas", passing): creates a metric table tile with two gauge series + A / (A + B) * 100, asserts the inline error for an invalid ref, hides operands, saves, reloads the page, verifies the formula column renders with a finite value, and reopens the editor to verify the round-trip.

How to test on Vercel preview

  1. Open a dashboard → Add tile → select a metrics source.
  2. Add two series (note the A/B badges), click Add Formula, enter A / (A + B) * 100.
  3. Try A / C to see the inline error; toggle Show input series; save, reload, and confirm the tile renders the formula series.

References

Screenshots

image

@changeset-bot

changeset-bot Bot commented Aug 14, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f50b9bf

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@hyperdx/api Minor
@hyperdx/app Minor
@hyperdx/common-utils Patch
@hyperdx/otel-collector Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Aug 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hyperdx-oss Ready Ready Preview Aug 20, 2026 11:20am
hyperdx-storybook Ready Ready Preview Aug 20, 2026 11:20am

Request Review

@greptile-apps

greptile-apps Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR exposes metric formulas in the chart editor and updates rendering metadata, number-chart normalization, and alert evaluation to consume formula columns correctly.

  • Adds formula rows, validation, formatting, operand visibility controls, and ratio-mode exclusion.
  • Updates positional value-column handling for tables, time charts, and number formats.
  • Preserves formula and ratio configuration when rebuilding metric tile alerts and adds integration, unit, and end-to-end coverage.

Confidence Score: 4/5

The PR is not yet safe to merge because series mutations can silently rebind positional formula operands or leave formulas unsavable.

Moving or duplicating a series changes the indices represented by formula letters without rewriting the expression, and removing a referenced series makes validation fail; the existing series controls remain enabled and unsynchronized with the formula field array.

Files Needing Attention: packages/app/src/components/DBEditTimeChartForm/ChartSeriesEditor.tsx, packages/app/src/components/DBEditTimeChartForm/ChartEditorControls.tsx

Important Files Changed

Filename Overview
packages/app/src/components/DBEditTimeChartForm/ChartEditorControls.tsx Adds formula field-array controls and operand visibility behavior, but series mutations remain unsynchronized with positional formula references.
packages/app/src/components/DBEditTimeChartForm/ChartFormulaEditor.tsx Adds formula expression, alias, formatting, and live validation UI.
packages/app/src/components/ChartEditor/utils.ts Adds formula-aware normalization and save-time validation, including number-chart constraints.
packages/api/src/tasks/checkAlerts/index.ts Preserves formulas and ratio mode when rebuilding metric tile alert configurations and hides formula operands for evaluation.
packages/app/src/source.ts Adds formula-aware value-column counting and number-format mapping.
packages/common-utils/src/core/utils.ts Normalizes formula number-chart configurations to expose the formula as the displayed value.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Editor[Metric chart editor] --> Series[Operand series A, B, C]
  Editor --> Formula[Validated formula expression]
  Series --> Config[Saved chart config]
  Formula --> Config
  Config --> Query[Composed metric query]
  Query --> Columns[Operand and formula columns]
  Columns --> Charts[Table, time, or number chart]
  Config --> Alert[Alert configuration rebuild]
  Alert --> FormulaOnly[Formula-only alert query]
  FormulaOnly --> Threshold[Threshold evaluation]
Loading

Reviews (8): Last reviewed commit: "Merge branch 'main' into warren/HDX-5080..." | Re-trigger Greptile

@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Deep Review

✅ No critical issues found.

The formula expression path is safe: core/formula.ts is a strict tokenizer/parser that produces an AST of only numbers, series-refs, and + - * /, and the renderer compiles from that AST (compileFormulaAst) rather than the raw string — division is guarded with nullif, and column names pass through quotedColumnName (double-quoted, quotes escaped). No SQL-injection surface is introduced. The positional value-column contract (operands → formulas → group-by passthrough) is applied consistently across useChartNumberFormats, getBuilderValueColumnCount, DBTableChart, and DBTimeChart, and matches the renderer's projection order.

🟡 P2 -- recommended

  • packages/api/src/tasks/checkAlerts/index.ts:731 -- For a grouped formula alert (Line/StackedBar tile with a group-by), the renderer projects the formula column before the group-by passthrough columns, but parseAlertData treats every numeric-typed column as a value column and lets the last one win, so a numeric group-by key would override the formula value the alert is supposed to evaluate.

    • Fix: Scope alert value selection to the projected formula/value columns (e.g. by position or explicit name) instead of "last numeric column," so trailing numeric group-by columns cannot shadow the formula.
    • correctness, reliability
  • packages/app/src/components/ChartEditor/utils.ts:485 -- The formula guardrails (single-formula-on-Number, formulas only on metric sources / formula-capable display types) are enforced only in the client form layer; a config written directly through the dashboards API can persist combinations the UI forbids, since SavedChartConfigSchema does not encode these constraints. The renderer still rejects malformed expressions, but not these structural rules.

    • Fix: Mirror the Number-single-formula and metric-source constraints as schema-level (Zod) or API-layer validation so non-UI callers get the same protection.
    • ce-agent-native-reviewer
🔵 P3 nitpicks (2)
  • packages/app/src/source.ts:610 -- The "operands hidden" / value-column-count concept is reimplemented in several places (getFormulaConfig in source.ts, inline checks in DBTimeChart.tsx and DBTableChart.tsx, and convertToNumberChartConfig in common-utils), and the encodings differ subtly: getFormulaConfig additionally requires metricTables != null while the inline checks do not, so they can disagree for an unnormalized config.

    • Fix: Route the inline formulas?.length && showOperandSeries === false checks through the shared getFormulaConfig/getBuilderValueColumnCount helpers so the positional contract has one source of truth.
  • packages/common-utils/src/core/utils.ts:892 -- convertToNumberChartConfig only sets showOperandSeries: false when config.formulas?.length is truthy; this correctly no-ops for non-formula configs, but the invariant "Number charts never render operand columns" now lives in both this render choke point and normalizeChartConfig, so keep them documented as a pair to avoid drift.

    • Fix: Add a cross-reference comment (or a shared helper) linking the two enforcement sites.

Reviewers (2): ce-agent-native-reviewer, ce-learnings-researcher, plus orchestrator-level diff verification (formula grammar, alert column contract, positional column mapping, AST compilation).

Coverage note: The eight dispatched persona reviewers (correctness, testing, maintainability, project-standards, kieran-typescript, reliability, adversarial, security) had not returned results at synthesis time; the findings above were confirmed directly against the diff and surrounding code, and the P0/P1-clean verdict reflects that independent verification rather than their input. ce-learnings-researcher found no relevant prior learnings in docs/solutions/.

Testing gaps: New unit/integration/E2E coverage is substantial; the untested edge is the grouped-formula-alert value-selection path (P2 above) — add an integration case with a numeric group-by key.

@wrn14897
wrn14897 force-pushed the warren/HDX-5079-render-formulas branch from 8d9e37e to 41b2354 Compare August 17, 2026 19:03
@wrn14897
wrn14897 force-pushed the warren/HDX-5080-render-metric-formula-UI branch from 2067484 to 226e1a9 Compare August 17, 2026 23:08
@wrn14897
wrn14897 changed the base branch from warren/HDX-5079-render-formulas to main August 17, 2026 23:09
@wrn14897
wrn14897 force-pushed the warren/HDX-5080-render-metric-formula-UI branch from 226e1a9 to 1010ee4 Compare August 17, 2026 23:23
@github-actions github-actions Bot added the review/tier-3 Standard — full human review required label Aug 17, 2026
@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

🟡 Tier 3 — Standard

Introduces new logic, modifies core functionality, or touches areas with non-trivial risk.

Why this tier:

  • Diff size: 551 production lines changed (Tier 2 max: < 250)
  • Cross-layer change: touches frontend (packages/app) + backend (packages/api) + shared utils (packages/common-utils)

Additional context: touches background tasks or the delivery pipeline lightly (11 lines, under the 30-line bar for Tier 4)

Review process: Full human review — logic, architecture, edge cases.
SLA: First-pass feedback within 1 business day.

Stats
  • Production files changed: 9
  • Production lines changed: 551 (+ 1232 in test files, excluded from tier calculation)
  • Branch: warren/HDX-5080-render-metric-formula-UI
  • Author: wrn14897

To override this classification, remove the review/tier-3 label and apply a different review/tier-* label. Manual overrides are preserved on subsequent pushes.

@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

E2E Test Results

All tests passed • 306 passed • 1 skipped • 1003s

Status Count
✅ Passed 306
❌ Failed 0
⚠️ Flaky 1
⏭️ Skipped 1

Tests ran across 4 shards in parallel.

View full report →

@pulpdrew

pulpdrew commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

One thing I noticed while testing: HAVING is applied within each CTE instead of to the final join, which is (to me at least) unexpected/unclear, and makes it hard to know what aliases/series/formulas I can reference.

Same with order by - I would expect to be able to reference any of the columns which are being outputted in the table in ORDER BY or HAVING.

Screenshot 2026-08-18 at 9 05 06 AM

@pulpdrew

pulpdrew commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Also, for number charts I suspect we need to make sure that (a) only one formula is allowed (b) show input series is hardcoded to false and (c) the chart renders the formula column and not any series columns.

I see we do (b) already when adding a formula, but not when a formula already exists and the display type is changed to number

Screenshot 2026-08-18 at 9 10 25 AM

Expose metric formulas (HDX-5078 schema, HDX-5079 rendering) in the chart
editor for metric sources:

- Formula rows in the builder (Add Formula / Remove Formula) with a
  letter-ref expression input, alias, and per-formula number format
- Inline validation via the structured validator (malformed expressions,
  unknown series refs) plus save-time validation in validateChartForm
- Letter badges (A, B, C) on metric series rows so refs are discoverable
- Show input series toggle (showOperandSeries) for formula-only output;
  Number tiles default to hidden operands since they render the first
  value column
- Formulas and the As Ratio toggle are mutually exclusive in the editor
- normalizeChartConfig strips formulas for non-metric sources and
  display types the composed metric query does not render
- useChartNumberFormats / DBTableChart / DBTimeChart updated for the
  formula-aware value-column projection (operands first unless hidden,
  then formula columns)
getChartConfigFromAlert rebuilds a builder tile's chart config from an
explicit field list and dropped formulas/showOperandSeries, so an alert
on a formula tile queried only the raw operand series and compared the
threshold against the last operand's value (e.g. raw bytes) instead of
the formula result — regardless of the tile's "Show input series"
toggle.

- Pass formulas through and always drop operand columns from the alert
  query (showOperandSeries: false) so the formula is the value column
  parseAlertData picks
- Also pass ratioMode through: grouped share_of_total ratio tile alerts
  previously evaluated as per_group (the default)
- Integration tests: formula value drives the alert (value distinct from
  both operands), toggle-independence, NULL formula (zero denominator)
  skipped, and share_of_total ratioMode honored
Number charts display the first value column of the result, so a formula
Number tile must project exactly one column: the formula.

- convertToNumberChartConfig (common-utils) forces showOperandSeries:
  false for formula configs — the choke point every Number render passes
  through (dashboard tiles, editor preview, standalone charts,
  builderToRawSql), covering stale saved configs and display-type
  switches (formula defined on Line, then switched to Number)
- normalizeChartConfig persists showOperandSeries: false on saved Number
  formula tiles so the stored config is self-describing; other display
  types keep the tile's own toggle value
- validateChartForm rejects multiple formulas on Number charts; the
  editor hides Add Formula once a Number tile has one, and hides the
  Show input series toggle on Number (it would be a no-op)
- The add-time setValue special case is removed in favor of the
  systematic enforcement above, so switching Number -> Line restores the
  user's operand-visibility choice
- useSingleSeriesNumberFormat resolves the displayed format from
  formulas[0].numberFormat for formula configs instead of an operand
  that isn't rendered
@wrn14897

Copy link
Copy Markdown
Member Author

Addressed in f5b76b1 — all three, plus the display-type-switch gap you called out:

(a) Single formula on NumbervalidateChartForm rejects formulas.length > 1 on Number charts ("Number charts support a single formula"), and the editor hides "Add Formula" once a Number tile has one. The validation path covers your switch case: a multi-formula chart switched to Number blocks run/save with a clear message rather than silently dropping a formula.

(b) showOperandSeries hardcoded to false — enforced systematically instead of only at add time:

  • convertToNumberChartConfig (common-utils) forces showOperandSeries: false for formula configs. That's the choke point every Number render passes through (dashboard tiles, editor preview, standalone charts, builderToRawSql), so it holds for a formula defined on Line and then switched to Number, and heals stale saved configs too.
  • normalizeChartConfig persists false on saved Number formula tiles so the stored config is self-describing.
  • The "Show input series" toggle is hidden on Number tiles (it would be a no-op).
  • The add-time setValue special case is removed in favor of the above — nice side effect: switching a tile Number → Line now restores the user's operand-visibility choice instead of permanently mutating it to false.

(c) Renders the formula column — follows from (a)+(b): the Number query projects exactly one column, the formula. Also fixed a related gap found while implementing: useSingleSeriesNumberFormat resolved the display format from select[0].numberFormat (an operand that isn't rendered); it now prefers formulas[0].numberFormat for formula configs.

Unit tests added at each enforcement point (common-utils convertToNumberChartConfig, app normalize/validate, editor UI gating + save, format resolution).

@wrn14897

Copy link
Copy Markdown
Member Author

One thing I noticed while testing: HAVING is applied within each CTE instead of to the final join, which is (to me at least) unexpected/unclear, and makes it hard to know what aliases/series/formulas I can reference.

Same with order by - I would expect to be able to reference any of the columns which are being outputted in the table in ORDER BY or HAVING.

Screenshot 2026-08-18 at 9 05 06 AM

Yeah, I agree that the HAVING or ORDER BY should be outside the final join. That should be handled in a separate PR. I’d file a ticket and address it separately.

kodiakhq Bot pushed a commit that referenced this pull request Aug 20, 2026
…ot per-series branches (#2946)

Fixes [HDX-5126](https://linear.app/clickhouse/issue/HDX-5126/apply-having-order-by-limit-to-the-composed-metric-join-not-per-series) — follow-up to [review feedback on #2909](#2909): "HAVING is applied within each CTE instead of to the final join … Same with order by."

## Why

The composed multi-series metric query (HDX-5077) builds each per-series branch as `{ ...chartConfig, select: [...] }`, so `having`, `orderBy` and `limit` leaked into every UNION branch:

- **HAVING** ran in a scope where the user-facing output names don't exist (the value column is renamed `__hdx_value`), and filtered each series independently before the join — making it impossible to know what aliases/series/formulas can be referenced.
- **ORDER BY** ran per branch and was then discarded by the outer join — the final row order was nondeterministic. This also made table header-click sorting and `convertToTableChartConfig`'s default group ordering silent no-ops on composed metric tables.
- **LIMIT/OFFSET** truncated each series to its own arbitrary group window before the join → mismatched group sets across series (spurious NULL cells) and incoherent table pagination (`useOffsetPaginatedQuery` injects page offsets into `limit`).

## What

All three clauses now render once, on the final joined SELECT, where they reference the **output columns**: operand aliases (when shown), formula names/aliases, the ratio column, group-by passthroughs and the time bucket. Time charts stay bucket-ordered first, with the user sort as a tiebreaker. Row-level filters (`where`, `filters`, per-series `aggCondition`) stay per-branch, where they belong.

### Reference contract (pinned by integration tests on CH 26.5)

Quoted output names or user aliases — e.g. `HAVING "err rate" > 0.5`, `ORDER BY "avg(metric.total)" DESC`, or a group-by `alias`. Raw expressions over source columns (e.g. `ResourceAttributes['service.name']`) do **not** resolve in the outer scope — verified `UNKNOWN_IDENTIFIER` under the new analyzer — so an expression group-by is referenced via its quoted ClickHouse-derived name (`"arrayElement(ResourceAttributes, 'service.name')"`) or, better, a group-by alias. Hidden operand series (`showOperandSeries: false`) are not referenceable: the contract is "reference what the result outputs".

## Tests

- **Unit/snapshot** (`renderChartConfig.test.ts`): clauses render exactly once, on the outer statement, in HAVING → ORDER BY → LIMIT order; bucket ordering stays first with the user sort appended; HAVING can reference a formula output column. Existing composed snapshots are byte-identical (no clause fields → no change).
- **Integration** (`queryChartConfig.int.test.ts`, 8 new): HAVING on an operand output column (including dropping a group whose *other* series fails the predicate — inexpressible per-branch) and on a formula alias; ORDER BY on a plain group column, an output value column, a quoted derived expression-group-by name, and a group-by alias; bucket-first ordering on time series; ratio-column HAVING/ORDER BY; LIMIT/OFFSET pages are disjoint windows of one consistent joined ordering.

## Out of scope (noted in HDX-5126)

- `seriesLimit` top-N ranking still runs per-branch.
- App-side: `DBTableChart` header-click sorting only quotes explicit user aliases — auto-aliased metric columns and formula columns produce unquoted `orderBy` expressions that don't resolve (broken before this change too, since branch scopes couldn't resolve them either). Editor autocomplete for output names in the Having/Order By inputs is a separate follow-up.
@kodiakhq
kodiakhq Bot merged commit e153f46 into main Aug 20, 2026
27 checks passed
@kodiakhq
kodiakhq Bot deleted the warren/HDX-5080-render-metric-formula-UI branch August 20, 2026 11:24
wrn14897 added a commit that referenced this pull request Aug 20, 2026
Plumb metric formula configs through every surface that persists or
accepts chart configs:

- External dashboards API v2: formulas/showOperandSeries on line,
  stacked_bar, table and number builder tile schemas, round-tripped
  through both converters, with write-time expression validation and a
  metric-source-only gate. OpenAPI spec regenerated with the new
  Formula component.
- Shared validation: validateChartConfigFormulas in common-utils
  dashboardValidation mirrors the chart editor's save-time rules;
  isFormulaDisplayType moves to common-utils core/utils so the editor
  and server gates cannot drift.
- MCP: save_dashboard / patch_dashboard tile schemas accept formulas,
  query_tile computes formula columns, and the dashboards query-guide
  prompt documents the feature.
- CLI: number/table tile config transforms delegate to the shared
  formula-aware common-utils implementations; AGENTS.md pipeline notes
  updated.

Alert-on-formula-tile support and its checkAlerts integration tests
landed with HDX-5080 (#2909); verified green on this branch.
wrn14897 added a commit that referenced this pull request Aug 21, 2026
Plumb metric formula configs through every surface that persists or
accepts chart configs:

- External dashboards API v2: formulas/showOperandSeries on line,
  stacked_bar, table and number builder tile schemas, round-tripped
  through both converters, with write-time expression validation and a
  metric-source-only gate. OpenAPI spec regenerated with the new
  Formula component.
- Shared validation: validateChartConfigFormulas in common-utils
  dashboardValidation mirrors the chart editor's save-time rules;
  isFormulaDisplayType moves to common-utils core/utils so the editor
  and server gates cannot drift.
- MCP: save_dashboard / patch_dashboard tile schemas accept formulas,
  query_tile computes formula columns, and the dashboards query-guide
  prompt documents the feature.
- CLI: number/table tile config transforms delegate to the shared
  formula-aware common-utils implementations; AGENTS.md pipeline notes
  updated.

Alert-on-formula-tile support and its checkAlerts integration tests
landed with HDX-5080 (#2909); verified green on this branch.
wrn14897 added a commit that referenced this pull request Aug 21, 2026
Plumb metric formula configs through every surface that persists or
accepts chart configs:

- External dashboards API v2: formulas/showOperandSeries on line,
  stacked_bar, table and number builder tile schemas, round-tripped
  through both converters, with write-time expression validation and a
  metric-source-only gate. OpenAPI spec regenerated with the new
  Formula component.
- Shared validation: validateChartConfigFormulas in common-utils
  dashboardValidation mirrors the chart editor's save-time rules;
  isFormulaDisplayType moves to common-utils core/utils so the editor
  and server gates cannot drift.
- MCP: save_dashboard / patch_dashboard tile schemas accept formulas,
  query_tile computes formula columns, and the dashboards query-guide
  prompt documents the feature.
- CLI: number/table tile config transforms delegate to the shared
  formula-aware common-utils implementations; AGENTS.md pipeline notes
  updated.

Alert-on-formula-tile support and its checkAlerts integration tests
landed with HDX-5080 (#2909); verified green on this branch.
wrn14897 added a commit that referenced this pull request Aug 21, 2026
Plumb metric formula configs through every surface that persists or
accepts chart configs:

- External dashboards API v2: formulas/showOperandSeries on line,
  stacked_bar, table and number builder tile schemas, round-tripped
  through both converters, with write-time expression validation and a
  metric-source-only gate. OpenAPI spec regenerated with the new
  Formula component.
- Shared validation: validateChartConfigFormulas in common-utils
  dashboardValidation mirrors the chart editor's save-time rules;
  isFormulaDisplayType moves to common-utils core/utils so the editor
  and server gates cannot drift.
- MCP: save_dashboard / patch_dashboard tile schemas accept formulas,
  query_tile computes formula columns, and the dashboards query-guide
  prompt documents the feature.
- CLI: number/table tile config transforms delegate to the shared
  formula-aware common-utils implementations; AGENTS.md pipeline notes
  updated.

Alert-on-formula-tile support and its checkAlerts integration tests
landed with HDX-5080 (#2909); verified green on this branch.
wrn14897 added a commit that referenced this pull request Aug 21, 2026
Plumb metric formula configs through every surface that persists or
accepts chart configs:

- External dashboards API v2: formulas/showOperandSeries on line,
  stacked_bar, table and number builder tile schemas, round-tripped
  through both converters, with write-time expression validation and a
  metric-source-only gate. OpenAPI spec regenerated with the new
  Formula component.
- Shared validation: validateChartConfigFormulas in common-utils
  dashboardValidation mirrors the chart editor's save-time rules;
  isFormulaDisplayType moves to common-utils core/utils so the editor
  and server gates cannot drift.
- MCP: save_dashboard / patch_dashboard tile schemas accept formulas,
  query_tile computes formula columns, and the dashboards query-guide
  prompt documents the feature.
- CLI: number/table tile config transforms delegate to the shared
  formula-aware common-utils implementations; AGENTS.md pipeline notes
  updated.

Alert-on-formula-tile support and its checkAlerts integration tests
landed with HDX-5080 (#2909); verified green on this branch.
wrn14897 added a commit that referenced this pull request Aug 21, 2026
Plumb metric formula configs through every surface that persists or
accepts chart configs:

- External dashboards API v2: formulas/showOperandSeries on line,
  stacked_bar, table and number builder tile schemas, round-tripped
  through both converters, with write-time expression validation and a
  metric-source-only gate. OpenAPI spec regenerated with the new
  Formula component.
- Shared validation: validateChartConfigFormulas in common-utils
  dashboardValidation mirrors the chart editor's save-time rules;
  isFormulaDisplayType moves to common-utils core/utils so the editor
  and server gates cannot drift.
- MCP: save_dashboard / patch_dashboard tile schemas accept formulas,
  query_tile computes formula columns, and the dashboards query-guide
  prompt documents the feature.
- CLI: number/table tile config transforms delegate to the shared
  formula-aware common-utils implementations; AGENTS.md pipeline notes
  updated.

Alert-on-formula-tile support and its checkAlerts integration tests
landed with HDX-5080 (#2909); verified green on this branch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automerge review/tier-3 Standard — full human review required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants