mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
fix: allow any numeric value for alert thresholds (#1869)
## Summary - Removes restrictive numeric constraints from alert threshold Zod schemas across all packages (common-utils, api, app), allowing any number (negative, zero, float) as a valid threshold - Removes `min` constraints from threshold `NumberInput` components in the saved search alert form and dashboard tile alert form - Updates the enhanced errors test to reflect that negative thresholds are no longer a validation error Closes HDX-3186 ## Test plan - [x] `yarn ci:unit` passes in `packages/app` (1031 tests passing) - [x] `yarn ci:unit` passes in `packages/common-utils` (624 passing, 8 pre-existing failures in queryParser unrelated to this change) - [ ] Verify saved search alerts accept threshold values of 0, negative numbers, and floats - [ ] Verify dashboard tile alerts accept threshold values of 0, negative numbers, and floats - [ ] Verify external API v2 alerts accept threshold values of 0, negative numbers, and floats Made with [Cursor](https://cursor.com)
This commit is contained in:
parent
84b0315f73
commit
1bae972e95
6 changed files with 13 additions and 10 deletions
7
.changeset/any-numeric-threshold.md
Normal file
7
.changeset/any-numeric-threshold.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
"@hyperdx/common-utils": patch
|
||||
"@hyperdx/api": patch
|
||||
"@hyperdx/app": patch
|
||||
---
|
||||
|
||||
fix: allow any numeric value for alert thresholds
|
||||
|
|
@ -155,7 +155,7 @@ describe('enhancedErrors', () => {
|
|||
source: 'tile',
|
||||
tileId: '507f1f77bcf86cd799439011',
|
||||
dashboardId: '507f1f77bcf86cd799439011',
|
||||
threshold: -5, // Invalid: negative threshold
|
||||
threshold: -5,
|
||||
interval: '99m', // Invalid: not a valid interval
|
||||
thresholdType: 'above',
|
||||
channel: {
|
||||
|
|
@ -166,7 +166,7 @@ describe('enhancedErrors', () => {
|
|||
|
||||
expect(response.status).toBe(400);
|
||||
expect(response.body.message).toEqual(
|
||||
"Body validation failed: interval: Invalid enum value. Expected '1m' | '5m' | '15m' | '30m' | '1h' | '6h' | '12h' | '1d', received '99m'; threshold: Number must be greater than or equal to 0; Params validation failed: id: Invalid input",
|
||||
"Body validation failed: interval: Invalid enum value. Expected '1m' | '5m' | '15m' | '30m' | '1h' | '6h' | '12h' | '1d', received '99m'; Params validation failed: id: Invalid input",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -412,7 +412,7 @@ export const alertSchema = z
|
|||
interval: z.enum(['1m', '5m', '15m', '30m', '1h', '6h', '12h', '1d']),
|
||||
scheduleOffsetMinutes: z.number().int().min(0).max(1439).optional(),
|
||||
scheduleStartAt: scheduleStartAtSchema,
|
||||
threshold: z.number().min(0),
|
||||
threshold: z.number(),
|
||||
thresholdType: z.nativeEnum(AlertThresholdType),
|
||||
source: z.nativeEnum(AlertSource).default(AlertSource.SAVED_SEARCH),
|
||||
name: z.string().min(1).max(512).nullish(),
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ import { optionsToSelectData } from './utils';
|
|||
const SavedSearchAlertFormSchema = z
|
||||
.object({
|
||||
interval: AlertIntervalSchema,
|
||||
threshold: z.number().int().min(1),
|
||||
threshold: z.number(),
|
||||
scheduleOffsetMinutes: z.number().int().min(0).default(0),
|
||||
scheduleStartAt: scheduleStartAtSchema,
|
||||
thresholdType: z.nativeEnum(AlertThresholdType),
|
||||
|
|
@ -170,7 +170,6 @@ const AlertForm = ({
|
|||
control={control}
|
||||
/>
|
||||
<NumberInput
|
||||
min={1}
|
||||
size="xs"
|
||||
w={80}
|
||||
control={control}
|
||||
|
|
|
|||
|
|
@ -163,8 +163,6 @@ const isQueryReady = (queriedConfig: ChartConfigWithDateRange | undefined) => {
|
|||
);
|
||||
};
|
||||
|
||||
const MINIMUM_THRESHOLD_VALUE = 0.0000000001; // to make alert input > 0
|
||||
|
||||
type SeriesItem = NonNullable<
|
||||
SavedChartConfigWithSelectArray['select']
|
||||
>[number];
|
||||
|
|
@ -1381,7 +1379,6 @@ export default function EditTimeChartForm({
|
|||
control={control}
|
||||
/>
|
||||
<NumberInput
|
||||
min={MINIMUM_THRESHOLD_VALUE}
|
||||
size="xs"
|
||||
w={80}
|
||||
control={control}
|
||||
|
|
|
|||
|
|
@ -396,7 +396,7 @@ export const AlertBaseObjectSchema = z.object({
|
|||
.max(MAX_SCHEDULE_OFFSET_MINUTES)
|
||||
.optional(),
|
||||
scheduleStartAt: scheduleStartAtSchema,
|
||||
threshold: z.number().int().min(1),
|
||||
threshold: z.number(),
|
||||
thresholdType: z.nativeEnum(AlertThresholdType),
|
||||
channel: zAlertChannel,
|
||||
state: z.nativeEnum(AlertState).optional(),
|
||||
|
|
@ -420,7 +420,7 @@ const AlertBaseValidatedSchema = AlertBaseObjectSchema.superRefine(
|
|||
);
|
||||
|
||||
export const ChartAlertBaseSchema = AlertBaseObjectSchema.extend({
|
||||
threshold: z.number().positive(),
|
||||
threshold: z.number(),
|
||||
});
|
||||
|
||||
const ChartAlertBaseValidatedSchema = ChartAlertBaseSchema.superRefine(
|
||||
|
|
|
|||
Loading…
Reference in a new issue