feat(api): support number-tile color in the external dashboards API#2428
feat(api): support number-tile color in the external dashboards API#2428alex-fedotyev wants to merge 3 commits into
Conversation
Number tiles can already set a static color and ordered conditional color rules in the editor, but the v2 external API carried neither, so dashboards-as-code could not author them. A raw SQL number tile that set a color in the UI also lost it on a GET then PUT round-trip because the external conversion never emitted it. Add `color` and `colorRules` to the builder number chart config and `color` to the raw SQL number chart config (the editor shows the rules section for raw SQL number tiles but its save path drops them, so rules stay builder-only). Round-trip both through the internal/external conversion and regenerate the OpenAPI spec. Colors are validated as hue-named palette tokens on input; tiles saved before the palette rename are normalized to hue names on read so older dashboards keep working. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 9e37785 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
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 |
🔴 Tier 4 — CriticalTouches auth, data models, config, tasks, OTel pipeline, ClickHouse, or CI/CD. Why this tier:
Review process: Deep review from a domain expert. Synchronous walkthrough may be required. Stats
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR extends the v2 external dashboards API to carry number-tile color fields (
Confidence Score: 5/5Safe to merge — additive fields only, validated input, normalized output, and full backward compatibility for stored legacy tokens. The change is purely additive: new optional fields on existing request/response schemas, strict Zod validation on write, and defensive normalization on read. The conversion helpers handle all known edge cases (legacy tokens, unresolvable tokens, string-match/regex rules written via direct DB access), and the previously flagged asymmetric-fallback issue was resolved before this review. Integration tests cover round-trips for both tile variants, every operator family, all rejection conditions, and three backward-compat scenarios. No existing behavior is altered. No files require special attention. Important Files Changed
Reviews (3): Last reviewed commit: "fix(api): restrict number-tile colorRule..." | Re-trigger Greptile |
E2E Test Results✅ All tests passed • 198 passed • 3 skipped • 1257s
Tests ran across 4 shards in parallel. |
…n read The colorRules normalizer fell back to the raw stored color when a rule's token could not be resolved, so a color written directly to Mongo that is neither a hue token nor a legacy numeric token would pass through verbatim in the GET response, outside the documented ChartPaletteToken enum. The static color field already omits an unresolvable token. Drop a rule whose color cannot be resolved instead, so the response stays within the enum. Only reachable via a direct DB write, since the input schema validates rule colors. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Deep Review✅ No critical issues found. This is a tightly scoped, well-tested additive change to the v2 external dashboards API. The OpenAPI enum and 🟡 P2 -- recommended
🔵 P3 nitpicks (6)
Reviewers (8): correctness, api-contract, testing, maintainability, kieran-typescript, adversarial, security, project-standards. Testing gaps:
|
The external number-tile colorRules schema reused the full ColorConditionSchema, which accepts the contains, startsWith, endsWith, and regex operators that the number-tile editor never emits. A stored regex pattern is compiled and evaluated at render time, so accepting one over the API let an authenticated payload run an arbitrary pattern in a same-team viewer's browser. Add NumberTileColorConditionSchema (numeric and equality operators only) in common-utils and validate the external schema against it, so the API surface matches what the editor can author. The MCP dashboard tool can reuse the same schema. Normalize an empty colorRules result to undefined on read so the field is omitted rather than returned as an empty array, matching the static color field. Regenerate the OpenAPI spec: NumberTileColorCondition gains an operator discriminator and the unused string-match and regex schemas are dropped. Extend the integration coverage: all seven allowed operators round-trip, unsupported operators and invalid per-rule tokens are rejected, colorRules on a raw SQL number tile is stripped, and color plus colorRules round-trip through PUT. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Pushed 9e37785 addressing the review feedback:
Integration suite: 116 passing, including the new operator-coverage, rejection, raw SQL strip, and PUT round-trip tests. Hardening the render-time regex evaluation itself (so a future table-tile editor that exposes those operators is safe) is a separate follow-up; no current authoring path reaches it now that the API matches the editor. |
Number tiles let you set a static color and ordered conditional color rules in the editor, but the v2 external dashboards API carried neither field, so dashboards authored through
POST /api/v2/dashboardscould not set them. A raw SQL number tile that set a color in the UI also lost it on a GET then PUT round-trip, because the external conversion never emittedcolor.This adds number-tile color to the external API so the authoring surfaces match.
Closes #2359 (that issue predates the conditional rules and only mentioned the static color; this covers both).
Builds on #2265 (static color) and #2386 (conditional rules).
What
color(a palette token) andcolorRules(ordered conditional rules, last match wins, max 10).color.colorRulesis intentionally left off the raw SQL variant: the editor shows the rules section for raw SQL number tiles, but its save path drops them, so persisted raw SQL configs never carry rules and the API should not invent capability the UI lacks.ChartPaletteTokenenum and aColorConditionschema, referenced from the number config.openapi.jsonis regenerated.Why the palette-token handling looks the way it does
Colors persist as palette tokens, not hex, so they reflow across light and dark themes. The canonical tokens were renamed to hue names (
chart-blue,chart-red, and so on) recently, and the older numeric tokens (chart-1throughchart-10) can still sit in stored dashboards. So:resolveChartPaletteTokenhelper, matching the app's fetch-time normalizer. Older dashboards keep returning a valid token and keep rendering.I reused the existing
ChartPaletteTokenSchemaandColorConditionSchemafromcommon-utilsrather than re-declaring them in the external schema (the file already imports leaf enums and the OnClick schemas the same way). That keeps the external surface from drifting from what the editor persists.Test plan
yarn workspace @hyperdx/api tsc --noEmityarn workspace @hyperdx/api lintyarn workspace @hyperdx/api lint:openapimake dev-int FILE=external-api/__tests__/dashboards.test.ts(111 passed)colorpluscolorRulescovering every operator family, and raw SQLcolor.betweenwithout a two-number tuple, a numeric operator with a string value, an invalid regex, and an over-length label.colorandcolorRuleson the number tile.What is not in this PR
hyperdx_save_dashboardparity for the same fields. That is the next PR in this series and reuses this conversion.ClickHouse/clickhouse-docs#6298).