Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/webapp/app/components/alerts/QueryAlertTranscript.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export type QueryWatchPrefill = {
mode?: QueryAlertMode;
measure?: string;
operator?: ">" | "<";
value?: number;
windowSec?: number;
};

export function queryWatchPrefill(
Expand Down Expand Up @@ -105,6 +107,8 @@ export function QueryAlertTranscript({
mode: prefill.mode,
measure: prefill.measure,
operator: prefill.operator,
value: prefill.value,
windowSec: prefill.windowSec,
...analyzed,
}
: undefined;
Expand Down
2 changes: 2 additions & 0 deletions apps/webapp/app/components/alerts/queryAlertLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export type QueryAlertPrefill = {
mode?: QueryAlertMode;
measure?: string;
operator?: ">" | "<";
value?: number;
windowSec?: number;
};

export function queryAlertNameKey(mode: QueryAlertMode, measure?: string) {
Expand Down
14 changes: 12 additions & 2 deletions apps/webapp/app/components/alerts/useQueryAlertDraft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,23 @@ export function useQueryAlertDraft(
const measure = mode === "match" ? undefined : signal.measure;

const [operator, setOperator] = useState<">" | "<">(prefill.operator ?? ">");
const [valueText, setValueText] = useState("");
const [valueText, setValueText] = useState(
prefill.value !== undefined ? String(prefill.value) : ""
);
const value = valueText.trim() === "" ? undefined : Number(valueText);
const valueValid = mode !== "threshold" || (value !== undefined && Number.isFinite(value));

const bounds = queryWindowBounds(analysis.limits);
const defaultWindow = defaultQueryWindowMinutes(prefill.period, analysis.limits);
const [windowText, setWindowText] = useState(() => String(defaultWindow));
const prefillWindowMinutes =
prefill.windowSec !== undefined ? Math.round(prefill.windowSec / 60) : undefined;
Comment on lines +67 to +68

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Query watch windows shorten unexpectedly

For a query patch requesting 630 seconds, prefillWindowMinutes becomes 10 instead of 11. The created alert watches a shorter interval than requested.

Learn more

Query watch alerts store their windows in whole minutes. The patch contract accepts any number of seconds, and applyDraftPatch rounds curated alert windows up. Rounding to the nearest minute here shortens intervals with a remainder under 30 seconds. The resulting window is used by queryAlertRequestBody when the alert is created.

Example: With a 601-second patch window and a 600-second minimum cadence, this code prefills 10 minutes and creates a 600-second alert rather than covering all 601 seconds.

Recommended fix: Use Math.ceil(prefill.windowSec / 60) before checking the analysis bounds, matching applyDraftPatch and avoiding a shorter requested interval.

Suggested change
const prefillWindowMinutes =
prefill.windowSec !== undefined ? Math.round(prefill.windowSec / 60) : undefined;
const prefillWindowMinutes =
prefill.windowSec !== undefined ? Math.ceil(prefill.windowSec / 60) : undefined;

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

const initialWindow =
prefillWindowMinutes !== undefined &&
prefillWindowMinutes >= bounds.min &&
prefillWindowMinutes <= bounds.max
? prefillWindowMinutes
: defaultWindow;
const [windowText, setWindowText] = useState(() => String(initialWindow));
const windowMinutes = mode === "match" ? defaultWindow : Number(windowText);
const windowValid =
mode === "match" ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
alertDraftPatchSchema,
applyDraftPatch,
errorGroupToResolve,
queryWatchFromPatch,
type AlertDraftPatch,
} from "./draftPatch";
import { draftResultLines } from "./useCreationAgentSend";
Expand Down Expand Up @@ -265,6 +266,23 @@ describe("below-threshold operator", () => {
const patch = { area: "query", query: "SELECT 1", condition: { operator: "<" } };
expect(alertDraftPatchSchema.safeParse(patch).success).toBe(true);
});

it("forwards condition value and windowSec in queryWatchFromPatch", () => {
const patch = {
area: "query",
query: "SELECT count() FROM runs",
querySignalChoice: { mode: "threshold" as const, measure: "count" },
condition: { operator: ">" as const, value: 42, windowSec: 1800 },
};
expect(queryWatchFromPatch(patch)).toEqual({
query: "SELECT count() FROM runs",
mode: "threshold",
measure: "count",
operator: ">",
value: 42,
windowSec: 1800,
});
});
});

describe("unknown-key rejection", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ export function queryWatchFromPatch(patch: AlertDraftPatch): QueryWatchPrefill |
mode: patch.querySignalChoice?.mode,
measure: patch.querySignalChoice?.measure,
operator: patch.condition?.operator,
value: patch.condition?.value,
windowSec: patch.condition?.windowSec,
Comment on lines +70 to +71

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Query watch fix missing release note

This user-facing query watch fix has no .server-changes entry. Customers will not see the fix in server release notes.

Learn more

The repository's server changes guidance requires a release note for a user-facing server-only bug fix. This change restores query watch condition and window prefills for customers, but the PR adds no release note.

Example: A customer whose query alert previously lost its threshold now sees it prefilled, but the release summary does not mention the fix.

Recommended fix: Add a .server-changes/ Markdown file with area: webapp, type: fix, and a one-sentence user-facing description of the restored query watch prefills.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

};
}

Expand Down