Explorar el Código

test(s8): enforce watch dedup keys and honor dept cluster config

YY968XX hace 5 meses
padre
commit
034f31df65

+ 3 - 1
Web/src/views/aidop/s8/monitoring/S8MonitoringOverviewPage.vue

@@ -32,6 +32,7 @@
 
 
 			<template #sidebar>
 			<template #sidebar>
 				<aside class="s8-monitor__sidebar glass-panel">
 				<aside class="s8-monitor__sidebar glass-panel">
+					<template v-if="pageConfig.hasDeptCluster.value">
 					<div class="section-title">
 					<div class="section-title">
 						<div class="section-title__bar" />
 						<div class="section-title__bar" />
 						<h2 class="section-title__text">S9 部门效率分析</h2>
 						<h2 class="section-title__text">S9 部门效率分析</h2>
@@ -72,6 +73,7 @@
 							</div>
 							</div>
 						</article>
 						</article>
 					</div>
 					</div>
+					</template>
 
 
 					<div class="s8-monitor__efficiency">
 					<div class="s8-monitor__efficiency">
 						<div class="s8-monitor__efficiency-head">
 						<div class="s8-monitor__efficiency-head">
@@ -228,7 +230,7 @@ const CATEGORY_DEFS_FALLBACK: ReadonlyArray<{ key: string; title: string; icon:
 
 
 // ─── G-09 一期 Part D:page-config driver 接入 ─────────────────────────
 // ─── G-09 一期 Part D:page-config driver 接入 ─────────────────────────
 // driver 派生 stageMeta(保留 valueMode 由 fallback 同 code 映射);categoryCards 用 effectiveCategoryDefs;
 // driver 派生 stageMeta(保留 valueMode 由 fallback 同 code 映射);categoryCards 用 effectiveCategoryDefs;
-// dept 由 API 动态返回,driver 仅暴露 hasDeptCluster 开关(预留,本期保持原行为:始终渲染部门簇)。
+// dept 由 API 动态返回;模板已通过 pageConfig.hasDeptCluster 控制部门簇可见性(fallback 时默认 true,行为兼容历史)。
 const pageConfig = useS8PageConfigDriver({ pageCode: 'OVERVIEW', pageCodePrefix: 'OVERVIEW' });
 const pageConfig = useS8PageConfigDriver({ pageCode: 'OVERVIEW', pageCodePrefix: 'OVERVIEW' });
 
 
 const stageMeta = computed<StageMeta[]>(() => {
 const stageMeta = computed<StageMeta[]>(() => {

+ 16 - 14
Web/tests/e2e/s8/g01-watch-mapping.spec.ts

@@ -89,21 +89,23 @@ test('S8-G01-MAPPING 多轮 run-once + 去重映射闭环', async ({ authedPage
     const ex = await getException(authedPage, hit.matchedExceptionId);
     const ex = await getException(authedPage, hit.matchedExceptionId);
     expect(ex, `matchedExceptionId=${hit.matchedExceptionId} 详情不可达`).toBeTruthy();
     expect(ex, `matchedExceptionId=${hit.matchedExceptionId} 详情不可达`).toBeTruthy();
     expect(PENDING).toContain(String(ex.status));
     expect(PENDING).toContain(String(ex.status));
-    // 双键一致:DTO 可能未暴露 sourceRuleId / relatedObjectCode(注释字段),
-    // 缺字段时只记录"DTO 未暴露",不视为失败;存在则严格相等。
-    const exRule =
-      ex.sourceRuleId ?? ex.SourceRuleId ?? ex.sourceRuleID ?? ex.ruleId ?? null;
-    const exObj =
-      ex.relatedObjectCode ?? ex.RelatedObjectCode ?? ex.relatedObject ?? ex.objectCode ?? null;
-    if (exRule != null && exRule !== '') {
-      expect(String(exRule), 'sourceRuleId 不一致').toBe(String(hit.sourceRuleId ?? ''));
-    }
-    if (exObj != null && exObj !== '') {
-      expect(String(exObj), 'relatedObjectCode 不一致').toBe(String(hit.relatedObjectCode ?? ''));
-    }
-    const dtoFlag = exRule == null && exObj == null ? '[DTO 未暴露双键]' : '';
+    // 双键强制一致:5656a88d 起 ExceptionDetailDto 必须暴露 sourceRuleId / relatedObjectCode。
+    expect(
+      ex.sourceRuleId,
+      `ex#${ex.id} DTO 未暴露 sourceRuleId(参见 5656a88d)`,
+    ).not.toBeUndefined();
+    expect(
+      ex.relatedObjectCode,
+      `ex#${ex.id} DTO 未暴露 relatedObjectCode(参见 5656a88d)`,
+    ).not.toBeUndefined();
+    expect(String(ex.sourceRuleId ?? ''), 'sourceRuleId 不一致').toBe(
+      String(hit.sourceRuleId ?? ''),
+    );
+    expect(String(ex.relatedObjectCode ?? ''), 'relatedObjectCode 不一致').toBe(
+      String(hit.relatedObjectCode ?? ''),
+    );
     mappingNotes.push(
     mappingNotes.push(
-      `hit{rule=${hit.sourceRuleId},obj=${hit.relatedObjectCode}} → ex#${ex.id}(${ex.status}, code=${ex.code ?? ex.exceptionCode})${dtoFlag}`,
+      `hit{rule=${hit.sourceRuleId},obj=${hit.relatedObjectCode}} → ex#${ex.id}(${ex.status}, code=${ex.code ?? ex.exceptionCode})`,
     );
     );
   }
   }
   test.info().annotations.push({ type: 'mapping', description: mappingNotes.join(' || ') });
   test.info().annotations.push({ type: 'mapping', description: mappingNotes.join(' || ') });