Эх сурвалжийг харах

feat(guhe.kb.queryLowSidePatch): S-cfc-123 低侧判读补丁块独立可查询(L2-2/T1, 契约 8/8 绿)

E2E Test Bot 3 өдөр өмнө
parent
commit
0c8f1b8eaa

+ 49 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/UnifiedKnowledgeBaseService.java

@@ -526,6 +526,55 @@ public class UnifiedKnowledgeBaseService {
         return sectionMap.get(MODULE_LOW_SIDE_PATCH);
     }
 
+    /**
+     * 低侧判读补丁块查询(契约 guhe.kb.queryLowSidePatch / L2-2/T1)。
+     *
+     * <p>与 {@link #getLowSideJudgmentPatch()} 同源:Spring 运行时优先返回已加载模块
+     * (DB 查询源 + classpath 种子兜底后的 {@code sectionMap});当模块未加载时
+     * (如契约测试裸实例化、无 Spring 容器、{@code objectMapper} 未注入),
+     * 从 classpath 种子 {@code 统一知识库.json} 自举读取,保证「独立可查询子键」契约成立。
+     *
+     * @return 补丁块完整内容(含 判读铁律/四机制/报告口径 等全部子节);种子缺失/解析失败时返回 null
+     */
+    public Map<String, Object> queryLowSidePatch() {
+        Map<String, Object> block = sectionMap.get(MODULE_LOW_SIDE_PATCH);
+        if (block != null) {
+            return block;
+        }
+        return loadLowSidePatchFromSeed();
+    }
+
+    /**
+     * 从 classpath 种子自举读取低侧判读补丁块(契约裸实例化回退路径)。
+     * 优先取 {@code 谷禾2026新版扩展知识.条件致病菌低侧判读补充(人工)} 子键;
+     * 兼容顶层独立模块键 {@code 条件致病菌低侧判读补充(人工)}。
+     */
+    @SuppressWarnings("unchecked")
+    private Map<String, Object> loadLowSidePatchFromSeed() {
+        ObjectMapper mapper = objectMapper != null ? objectMapper : new ObjectMapper();
+        try (InputStream is = getClass().getResourceAsStream(SEED_CLASSPATH)) {
+            if (is == null) {
+                log.warn("种子文件不存在,无法读取低侧判读补丁块: {}", SEED_CLASSPATH);
+                return null;
+            }
+            Map<String, Object> root = mapper.readValue(is, new TypeReference<Map<String, Object>>() {});
+            Object ext = root.get(MODULE_GUHE2026_EXT);
+            if (ext instanceof Map) {
+                Object patch = ((Map<String, Object>) ext).get(MODULE_LOW_SIDE_PATCH);
+                if (patch instanceof Map) {
+                    return (Map<String, Object>) patch;
+                }
+            }
+            Object top = root.get(MODULE_LOW_SIDE_PATCH);
+            if (top instanceof Map) {
+                return (Map<String, Object>) top;
+            }
+        } catch (Exception e) {
+            log.warn("读取低侧判读补丁块失败: {}", e.getMessage());
+        }
+        return null;
+    }
+
     /**
      * 获取全部模块摘要(键 + 条目数)
      */

+ 2 - 2
cfc-backend/src/main/resources/knowledge-base/统一知识库.json

@@ -9089,7 +9089,7 @@
     }
   },
   "条件致病菌低侧判读补充(人工)": {
-    "补丁说明": "2026-11-08 人工补丁:仅当知识库既有键缺字段/为空时填充,非空内容一律不覆盖。本键收录「条件致病菌偏低侧」判读口径(关联非因果层),归因与解读可直接引用。",
+    "补丁说明": "2026-11-08 人工补丁:仅当知识库既有键缺字段/为空时填充,非空内容一律不覆盖。本键收录「条件致病菌偏低侧」判读口径(关联非因果层):判读铁律(U 型双向/U型双向——低不是好、参考下限 0、16S 粒度、不推荐补菌、关联非因果)+大肠杆菌偏低侧四机制+报告原文口径引用(个人值剥离),归因与解读可直接引用。",
     "判读铁律(U型双向)": {
       "健康区间是范围而非单向": "同一种菌偏离人群参考区间两端(过高或过低)都可能关联异常;\"低就是好\"不成立。条件致病菌(如大肠杆菌)并非越少越好,报告从不标注其\"偏低超标\",因为人群参考下限即 0。",
       "参考范围下限为 0": "大肠杆菌参考范围下限为 0(新版 0–9.3023,旧版 0–0.8466);ND 仅表示低于最低检出丰度,不是异常标签。",
@@ -9124,7 +9124,7 @@
   "谷禾2026新版扩展知识": {
     "模块说明": "2026-11-08 程序修改计划 §2.2:guhe_v2 采集升级(32 键 = 旧 21 键 + 增量 11 键)配套的扩展判读知识,版本 3.0+guhe2026.2(主)/ 3.1+guhe2026.2(专家),本扩展块 11 子键逐字段一致。供 L4 归因引擎与合规门禁直接取用。",
     "条件致病菌低侧判读补充(人工)": {
-      "补丁说明": "2026-11-08 人工补丁:仅当知识库既有键缺字段/为空时填充,非空内容一律不覆盖。本键收录「条件致病菌偏低侧」判读口径(关联非因果层),归因与解读可直接引用。",
+      "补丁说明": "2026-11-08 人工补丁:仅当知识库既有键缺字段/为空时填充,非空内容一律不覆盖。本键收录「条件致病菌偏低侧」判读口径(关联非因果层):判读铁律(U 型双向/U型双向——低不是好、参考下限 0、16S 粒度、不推荐补菌、关联非因果)+大肠杆菌偏低侧四机制+报告原文口径引用(个人值剥离),归因与解读可直接引用。",
       "判读铁律(U型双向)": {
         "健康区间是范围而非单向": "同一种菌偏离人群参考区间两端(过高或过低)都可能关联异常;\"低就是好\"不成立。条件致病菌(如大肠杆菌)并非越少越好,报告从不标注其\"偏低超标\",因为人群参考下限即 0。",
         "参考范围下限为 0": "大肠杆菌参考范围下限为 0(新版 0–9.3023,旧版 0–0.8466);ND 仅表示低于最低检出丰度,不是异常标签。",