## Summary
This PR implements alerting on Raw SQL-based line/bar charts.
- This is only available for line/bar charts with this change. Number charts will be added in a future PR.
- The threshold is compared to the _last_ numeric column in each result.
- The interval parameter must be used. This is required for line charts to function, and is used for zero-fill and other functionality within the alerts task. This limitation will be removed for Number chart alerts when those are implemented.
- Start and and end date should be used, but are not required because there are some potential use-cases where they may not be desirable.
### Screenshots or video
https://github.com/user-attachments/assets/e2d0cd6c-b040-4490-89af-6a51a7380647
Logs from Check-Alerts evaluating a raw-sql alert
<img width="1241" height="908" alt="Screenshot 2026-04-09 at 3 01 14 PM" src="https://github.com/user-attachments/assets/dbed4e5f-bf27-4179-b8e0-897cc19f3d3a" />
### How to test locally or on Vercel
This must be tested locally, as alerts are not enabled in the preview environment.
<details>
<summary>Query for the "anomaly detection" example</summary>
```sql
WITH buckets AS (
SELECT
$__timeInterval(Timestamp) AS ts,
count() AS bucket_count
FROM $__sourceTable
WHERE TimestampTime >= fromUnixTimestamp64Milli({startDateMilliseconds:Int64}) - toIntervalSecond($__interval_s * 30) -- Fetch 30 intervals back
AND TimestampTime < fromUnixTimestamp64Milli({endDateMilliseconds:Int64})
AND SeverityText = 'error'
GROUP BY ts
ORDER BY ts
WITH FILL STEP toIntervalSecond($__interval_s)
),
anomaly_detection as (
SELECT
ts,
bucket_count,
avg(bucket_count) OVER (ORDER BY ts ROWS BETWEEN 30 PRECEDING AND 1 PRECEDING) as previous_30_avg, -- avg of previous 30 intervals
stddevPop(bucket_count) OVER (ORDER BY ts ROWS BETWEEN 30 PRECEDING AND 1 PRECEDING) as previous_30_stddev, -- standard deviation of previous 30 intervals
greatest(bucket_count - (previous_30_avg + 2 * previous_30_stddev), 0) as excess_over_2std -- compare bucket to avg + 2 stddev. clamp at 0.
FROM buckets
)
SELECT ts, excess_over_2std
FROM anomaly_detection
WHERE ts >= fromUnixTimestamp64Milli({startDateMilliseconds:Int64}) AND ts < fromUnixTimestamp64Milli({endDateMilliseconds:Int64})
```
</details>
### References
- Linear Issue: HDX-1605
- Related PRs:
## Summary
This PR improves dashboard filters
1. Dashboard filters can now have an associated WHERE condition which filters the rows from which filter values will be queried.
2. Multiple values can now be selected for a single dashboard filter
### Screenshots or video
Multiple values can now be selected for a single filters:
<img width="544" height="77" alt="Screenshot 2026-03-23 at 12 31 02 PM" src="https://github.com/user-attachments/assets/2390a2d7-8514-4eb8-ac3c-db102a5df99b" />
Filters now have an optional condition, which filters the values which show up in the dropdown:
<img width="451" height="476" alt="Screenshot 2026-03-23 at 12 30 44 PM" src="https://github.com/user-attachments/assets/eed7f69e-466e-42fd-93f1-c27bfbc06204" />
<img width="265" height="94" alt="Screenshot 2026-03-23 at 12 30 54 PM" src="https://github.com/user-attachments/assets/2ba46e33-a44a-45ea-a6bf-fb71f5373e46" />
This also applies to Preset Dashboard Filters
<img width="726" height="908" alt="Screenshot 2026-03-23 at 12 33 34 PM" src="https://github.com/user-attachments/assets/df648feb-32e2-4f5e-80e5-409e0443b38e" />
### How to test locally or on Vercel
This can be partially tested in the preview environment, but testing the following requires running locally
1. Preset dashboard filters
2. External API support
### References
- Linear Issue: Closes HDX-3631 Closes HDX-2987
- Related PRs:
## Summary
This PR adds the Spectral linter for linting our OpenAPI spec, with rules preventing fields with missing examples or descriptions, which are often enforced in the Control Plane repo.
This PR also resolves lint errors that were already present.
### Screenshots or video
### How to test locally or on Vercel
Run `make ci-lint` to lint the openapi specs
### References
- Linear Issue: Closes HDX-3768
- Related PRs:
## Summary
This PR updates Raw SQL charts with support for dashboard filters, using the $__filters macro.
Lucene global filters require a Source to be included in the ChartConfig, for schema introspection and the `implicitColumnExpression` value. To support Lucene filters, this PR also updates the RawSqlChartConfig type to include optional `source`, `implicitColumnExpression`, and `from` properties. Only `source` is saved in the database. The external API has been updated to accept the `source` field for raw SQL charts as well.
Dashboard import/export has also been updated to support source mapping for raw sql charts with sources.
### Screenshots or video
Both the global filter and the drop-down filters are applied:
<img width="683" height="574" alt="Screenshot 2026-03-17 at 10 57 36 AM" src="https://github.com/user-attachments/assets/280ba0b5-55f7-4107-a55c-eeb1497ac7de" />
To render Lucene conditions, we require Source information (the `from` and `implicitColumnExpression` fields). When a source is not set, filters are therefore not applied:
<img width="782" height="618" alt="Screenshot 2026-03-17 at 10 54 41 AM" src="https://github.com/user-attachments/assets/3ad19ea7-12ee-4334-abe2-8985a0be952c" />
Similarly, if the `$__filters` macro is not used, then the filters are not applied
<img width="704" height="292" alt="Screenshot 2026-03-17 at 10 56 33 AM" src="https://github.com/user-attachments/assets/e1169e4a-2f64-4cd2-bc05-f699fecef8c1" />
Import:
<img width="993" height="669" alt="Screenshot 2026-03-17 at 3 35 16 PM" src="https://github.com/user-attachments/assets/6ebe20c0-19e2-4e90-95d0-8b02c2af0612" />
### How to test locally or on Vercel
This can be tested in the preview environment.
1. Create a saved dashboard and add some filters.
2. Create a raw sql tile, with or without the $__filters macro
3. Try selecting filters, deselecting filters, and applying global SQL and Lucene filters
4. Inspect the generated queries in the console.
### References
- Linear Issue: Closes HDX-3694
- Related PRs:
Closes#1715
## Summary
- Add scheduleStartAt and scheduleOffsetMinutes to alert schemas and API validation.
- Update alert evaluation scheduling to anchor windows by scheduleStartAt when set.
- Skip evaluations before scheduleStartAt.
- Keep current behavior unchanged when scheduling fields are unset.
- Add UI fields and API/OpenAPI/external API support for the new schedule options.
- Add alert scheduler tests for anchored windows and pre-start skip behavior.
## Notes
- This enables Splunk-style scheduled monitor migration where checks must run on isolated, periodic windows anchored to specific times.
- scheduleStartAt is the primary anchor; scheduleOffsetMinutes remains optional for backward-compatible alignment.
Co-authored-by: melsalcedo <128840984+melsalcedo@users.noreply.github.com>
Co-authored-by: Tom Alexander <3245235+teeohhem@users.noreply.github.com>
Closes HDX-3479
# Summary
This PR makes a number of improvements to new pie chart implementation (#1704)
1. Pie charts are now limited to 1 series. Previously, the pie chart summed the values of each series by group, and used the sum as the slice value. This is non-obvious and probably not what users expect. With a one-series limit, this problem is eliminated. Further, the logic for formatting the pie chart data from the clickhouse response is dramatically simpler.
2. Slices are now ordered by value decreasing, to avoid randomly changing slice order on refresh
3. Instead of being randomly generated, slice colors are now consistent with the theme colors and auto-detect log and trace severity levels, matching line/bar chart behavior
4. The external dashboards API now supports reading and writing pie charts. The transformation code has been updated so that there will be a type error if any new chart types are added in the future without updating the external API code.
5. The pie chart's tooltip now matches the style of the line chart tooltip, and is updated appropriately based on the app theme and light/dark mode.
6. The chart's number format is now applied to values in the pie chart tooltip
7. Slice labels are now correctly populated when a map is accessed in the Group By (eg. when grouping by `ResourceAttributes['app']`, the slice labels include the `app` value instead of being empty).
8. Also, added some unit tests for the pie chart data transformation, and moved it to ChartUtils with the other similar chart data transformation code.
1. `source` isn't actually required on an alert. It is non-nullable, but has a default value of `saved_search` if omitted.
2. `whereLanguage` is actually a required input.
HDX-3318
# Summary
This PR adds a `GET /sources` endpoint to the external API. This is intended to be a way for users to retrieve the list of available sources, so that they can use a correct source ID when creating or updating dashboards through the external API. Previously, the user had no easy way to view source IDs.
Create/Update/Delete source endpoints may be added in subsequent iterations.
There will be a related PR in control-plane to add this to the OpenAPI.
<img width="2126" height="1345" alt="Screenshot 2026-02-11 at 10 37 54 AM" src="https://github.com/user-attachments/assets/bd5ba25f-75df-495a-a25f-95b3a6a5cae2" />
```
curl --request GET \
--url http://localhost:8000/api/v2/sources \
--header 'authorization: Bearer <API Key>'
```
Fixes HDX-3325
* Use enums where possible
* Add descriptions where missing
* Simplify Alert request and types
* Fix a disceprency with alert request and response fields: `team` vs `teamId`, `dashboard` vs `dashboardId`, `savedSearch` vs `savedSearchId`
Closes HDX-3303
# Summary
This PR reworks the external dashboard APIs in the following ways
1. Previously, there was no way to create a renderable dashboard using the create or update routes, because the APIs saved dashboard data in a format incompatible with v2 of HyperDX. This PR introduces a transformation layer to transform external API request and response formats into the v2 dashboard format prior to saving.
2. This PR also corrects and improves the openapi documentation associated with the dashboard endpoints.
This PR introduces a number of **breaking changes** in the dashboard API, which is acceptable because the APIs are already (a) effectively non-functional for writing dashboard data and (b) not aligned at all with the previously published spec when reading dashboard data.
1. The `dataSource` field has been removed from each series and replaced with a `sourceId` field, which specifies the sourceId of the source which should be queried. The `dataSource` argument was inflexible and could only specify `events`, `rrweb`, or `metrics` - these are leftover from V1, and are not very compatible with the design of HyperDX V2.
2. Dashboard responses previously would have contained `config` fields, in the format of a V2 dashboard config. Results are now transformed and align with the spec, which contains config data in a `series` array.
3. Additional validation has been added to prevent creation of some invalid dashboards
# Summary
This PR updates the external Alerts API specs so that the specs match the actual behavior of the API.
I've also added a validator to an API which was missing any validation.