This is an automated email from the ASF dual-hosted git repository.

wu-sheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-horizon-ui.git


The following commit(s) were added to refs/heads/main by this push:
     new 97950a6  fix: per-layer alarm filter — queryAlarms condition.layer is 
singular
97950a6 is described below

commit 97950a600ceaece1d8056c4084d8551c1010d17d
Author: Wu Sheng <[email protected]>
AuthorDate: Wed May 20 09:20:03 2026 +0800

    fix: per-layer alarm filter — queryAlarms condition.layer is singular
    
    OAP's AlarmQueryCondition exposes the layer filter as `layer: String`
    (verified in alarm.graphqls and AlarmQueryCondition.java line 60:
    `private String layer`) — a single value, because an alarm record is
    persisted with exactly one layer.
    
    We were sending `condition.layers = [q.layer]` (plural, array). OAP
    ignores the unknown `layers` field and returns alarms across every
    layer, so the per-layer alarm page showed the global set instead of
    its own layer's — the filter silently no-op'd.
    
    Send `condition.layer = q.layer` instead.
---
 apps/bff/src/http/query/alarms.ts | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/apps/bff/src/http/query/alarms.ts 
b/apps/bff/src/http/query/alarms.ts
index 590dfb9..ce913f1 100644
--- a/apps/bff/src/http/query/alarms.ts
+++ b/apps/bff/src/http/query/alarms.ts
@@ -318,7 +318,8 @@ const alarmsQuerySchema = z.object({
   keyword: z.string().optional(),
   pageNum: z.coerce.number().int().min(1).default(1),
   pageSize: 
z.coerce.number().int().min(1).max(LIST_PAGE_SIZE_CAP).default(LIST_PAGE_SIZE_CAP),
-  /** New-mode only. Maps to `condition.layers: [layer]`. */
+  /** New-mode only. Maps to `condition.layer` (a single String on the
+   *  OAP side — an alarm record is persisted with one layer). */
   layer: z.string().optional(),
   /** New-mode only. Combined with `instance` / `endpoint` to build a
    *  single `Entity` filter. When absent, no entity narrowing. */
@@ -421,16 +422,22 @@ export function registerAlarmsQueryRoutes(app: 
FastifyInstance, deps: AlarmsQuer
     let msgsRaw: AlarmMessage[];
     try {
       if (caps.queryAlarms) {
-        /* New-mode condition. `entities` + `layers` ride server-side;
+        /* New-mode condition. `entities` + `layer` ride server-side;
          * `scope` is intentionally ignored here because it's a
-         * legacy-only coarse filter and `entities` + `layers` cover
-         * its use-cases more precisely. */
+         * legacy-only coarse filter and `entities` + `layer` cover
+         * its use-cases more precisely. NOTE: the OAP field is
+         * `layer: String` (singular scalar), NOT `layers: [String]`.
+         * An alarm record is persisted with exactly one layer, so the
+         * filter is a single value. Sending `layers` silently no-ops —
+         * OAP ignores the unknown field and returns every layer's
+         * alarms, which looked like "the per-layer filter doesn't
+         * work". */
         const condition: Record<string, unknown> = {
           duration: { start, end, step: 'SECOND' },
           paging: { pageNum: q.pageNum, pageSize: q.pageSize },
         };
         if (q.keyword) condition.keyword = q.keyword;
-        if (q.layer) condition.layers = [q.layer];
+        if (q.layer) condition.layer = q.layer;
         const entity = buildEntity(q);
         if (entity) condition.entities = [entity];
         const raw = await graphqlPost<QueryAlarmsRaw>(opts, 
QUERY_ALARMS_QUERY, { condition });

Reply via email to