|
|
@@ -0,0 +1,95 @@
|
|
|
+# 浠艾福平台程序修改计划 · C 档探测与 T4 实现报告
|
|
|
+
|
|
|
+> **任务**: DOC-2026-11-08-guhe-v2-T4(P0 · L4-3 低位补菌红线)
|
|
|
+> **tdd_key**: `guhe.lowSide.noSupplement`
|
|
|
+> **日期**: 2026-11-09
|
|
|
+> **分支**: `cfclub`(主线直改,未新开分支)
|
|
|
+> **关联**: 计划文档 `plans/2026-11-08-浠艾福平台程序修改计划.md` §三 T4 / §四 C 档;基准《浠艾福-报告归因方案-总体设计修改方案-v1.1.md》§5.2
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 一、结论速览
|
|
|
+
|
|
|
+T4(L4-3 偏低不推荐补菌红线)已实现并验证通过:
|
|
|
+
|
|
|
+- **规则码**: `no_low_side_supplement`(`AttributionLowSideRules.RULE_NO_LOW_SIDE_SUPPLEMENT`)
|
|
|
+- **核心禁令**: 无成熟证据支持「缺大肠杆菌→补大肠杆菌」;⛔ 禁「报告缺 X → 买含 X 菌株产品」桥接,叠加 §5.2 16S 粒度声明
|
|
|
+- **实现位置**: 既有 G-1 低侧红线组内新增规则(不新建规则表、不新增 DB 迁移——纯规则)
|
|
|
+- **挂载点**: `AttributionComplianceGate.scan(text, boolean)`(L5 出文档前),并经 `enforceLowSide()` 的 L4 前置扫描联动
|
|
|
+- **测试**: `AttributionComplianceGateTest` 17/17 通过(含 6 个新增 T4 case);`AttributionPipelineMockTest` 2/2 通过
|
|
|
+- **编译**: `mvn compile -q` 通过(cfc-backend)
|
|
|
+
|
|
|
+> 本次提交文件中的 `AttributionComplianceGate.java` 与 `AttributionLowSideRules.java` 为**共享工作文件**,其内容同时承载了并行会话的 T6(G-2 16S 粒度拦截)代码——本地绿色状态即二者的合并快照,详见「六、已知事项」。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 二、C 档探测结论(计划 §四,4 项)
|
|
|
+
|
|
|
+探测方式:对 `cfc-backend` 现有代码直接取证(无 index,未走 codegraph)。
|
|
|
+
|
|
|
+| # | 待确认项 | 平台现状(代码证据) | 判定 |
|
|
|
+|---|---|---|---|
|
|
|
+| C1 | Adapter 实现形态 | `PdfParseService`(`service/PdfParseService.java`)统一 PDF 解析,产出 `ParsedReportPayload` / `ParsedReportResult`(均含 `reportFormat` 字段);`HealthReport` 实体带 `reportFormat` 持久化。**无统一多格式 Adapter 接口**,格式信息以字段形式贯通。 | **「新增 guhe_v2 分支」**而非「重写路由」——在既有解析流中按 `reportFormat` 判别新增分支 |
|
|
|
+| C2 | KB 服务加载方式 | `UnifiedKnowledgeBaseService`:查询源为 DB 表 `knowledge_base_section`(`KnowledgeBaseSectionMapper`),classpath 种子 JSON 仅作兜底导入(表为空/建表失败时降级内存模式)。 | **服务接口新增**——升级走 `knowledge_base_section` 数据 + 种子兜底,非纯文件直读升级 |
|
|
|
+| C3 | L4 引擎存在性 | 归因判读为纯 Java 规则引擎(`IndicatorInterpretEngine`、`NormCompareEngine`、`AttributionLowSideRules` 常量模式组),非专家 prompt 驱动。 | **「补规则」**而非「新建规则表」——在既有纯 Java 规则引擎内新增常量模式 + 门禁执行器 |
|
|
|
+| C4 | 合规门禁挂载点 | `AttributionComplianceGate`(`@Component`)已挂载于 `AttributionAnalysisServiceImpl.analyze()`:L4 出结论前 `enforceLowSide()` + L5 出文档前 `scan()`,结果经 `AttributionReportBuilder.sections.complianceGate` 暴露。 | **已有门禁框架**——T4 红线作为既有 G-1 门禁内新增规则复用现有挂载点 |
|
|
|
+
|
|
|
+C 档结论对 T4 实现无阻塞:四者均为「已有框架内增量」,与 T4 纯规则定位一致。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 三、实现详情
|
|
|
+
|
|
|
+### 3.1 规则定义(`constant/AttributionLowSideRules.java`)
|
|
|
+
|
|
|
+- `RULE_NO_LOW_SIDE_SUPPLEMENT = "no_low_side_supplement"`
|
|
|
+- `S16S_GRANULARITY_NOTE`:§5.2 16S 粒度声明——「16S 测序只到属/种粒度,测不到菌株;报告缺 X 与含 X 菌株的商品之间无桥,禁止生成菌株级商品推荐」。措辞已刻意避免自匹配其「补/买」类动词+细菌结构。
|
|
|
+- `NO_SUPPLEMENT_HINT`:命中时给下游的建议改写(改用措辞白名单表述、补类动作后置、先查血/复测再医生定)。
|
|
|
+- `FORBIDDEN_SUPPLEMENT_PATTERNS`:动词(补/补充/服用/口服/摄入/吃/喝/喂/进食/加菌/买/购买/选购/下单/采购)+ ≤6 非句读字符 + 细菌名(属级:双歧/乳杆菌/拟杆菌/肠球菌/梭菌…;菌株级:菌粉/菌株/Bifidobacterium/E._coli…)。覆盖「买含 X 菌株产品」桥接。
|
|
|
+- `NEGATION_WINDOW`:命中片段前 10 字内出现否定词(不/禁/无/未/别/勿/慎/避免/无需/不应/不建议)→ 视为安全表述(「不推荐补菌」「禁补 X」「无需补」不误报)。
|
|
|
+- 访问器 `supplementPatterns()` + 判定 `hitsLowSideSupplement()`(带否定词窗口过滤)。
|
|
|
+
|
|
|
+### 3.2 门禁执行(`service/attribution/AttributionComplianceGate.java`)
|
|
|
+
|
|
|
+- `scan(String text)` → 新增 `scan(String text, boolean strainGranularity)` 重载;`scan(text)` 委托 `scan(text, false)`。
|
|
|
+- `scan(text, boolean)` 在既有 G-1 扫描后追加 `matchLowSideSupplement(text)`(T4),并在非菌株级粒度下追加 `matchStrainRecommendation(text)`(T6 G-2,共享文件)。
|
|
|
+- 私有 `matchLowSideSupplement()` 调 `matchAllFiltered(text, supplementPatterns(), RULE_NO_LOW_SIDE_SUPPLEMENT, …)`——带否定词窗口的违规收集。
|
|
|
+- `enforceLowSide()` 中扫描调用升级为 `scan(r.getMeaning(), r.isStrainGranularity())`(联动粒度感知)。
|
|
|
+- javadoc 同步补充 T4 红线与 §5.2 粒度声明。
|
|
|
+
|
|
|
+### 3.3 报告暴露(`service/attribution/AttributionReportBuilder.java`)
|
|
|
+
|
|
|
+- `sections.complianceGate` 新增 `s16sGranularityNote`(= `S16S_GRANULARITY_NOTE`)。
|
|
|
+- G-1 红线组消息补充「偏低不推荐补菌(无成熟证据『缺大肠杆菌→补大肠杆菌』)」要点。
|
|
|
+
|
|
|
+### 3.4 兼容性核对
|
|
|
+
|
|
|
+- 不误报:`益生菌按说明使用`、`不与抗生素同服`、`儿童剂量由医生定`、`报告提示…有关`、判读含义「…先医后补」(裸「菌」非模式目标)、否定词窗内「不推荐补菌/禁补/无需补」。
|
|
|
+- 不阻断流程:违规收集为 E4 弱提示(violation),不抛异常、不改结论。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 四、测试
|
|
|
+
|
|
|
+| 测试类 | 结果 | 说明 |
|
|
|
+|---|---|---|
|
|
|
+| `AttributionComplianceGateTest` | **17/17 通过** | 含 6 个新增 T4 case(命中补菌/否定窗放行/规则码/模式非空/命中判定/桥接报告) |
|
|
|
+| `AttributionPipelineMockTest` | **2/2 通过** | 管线 B1 端到端(RL01/RL02/G-1 红线 + status=READY) |
|
|
|
+
|
|
|
+> 并行会话的 `ConditionalPathogenLowSideRuleTest.java`(untracked,非本任务)存在编译错误(static 方法引用实例字段 `interpretEngine`),已通过 `-Dmaven.compiler.testExcludes=**/ConditionalPathogenLowSideRuleTest.java` 在测试编译时排除该文件,不影响本任务测试结果。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 五、构建与验证
|
|
|
+
|
|
|
+- `mvn compile -q`(cfc-backend):**通过**(期间一次 Lombok `UserService` 报错为并行会话编辑竞态,重跑通过)。
|
|
|
+- DB 迁移:**无**(任务为纯规则,无结构变更)。
|
|
|
+- `cfc-web`:本任务**零改动**(其工作区仅一个并行会话的 untracked python 脚本),未引入 web 侧回归。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 六、已知事项
|
|
|
+
|
|
|
+1. **共享工作文件**:`AttributionComplianceGate.java` / `AttributionLowSideRules.java` 同时含并行会话 T6(G-2 16S 粒度拦截)代码;本提交为二者合并的本地绿色快照,T6 的 `GROUP_CODE_2/GROUP_TITLE_2/RULE_NO_STRAIN_RECOMMENDATION/strainRecommendationPatterns/hitsStrainNumber` 与 `matchStrainRecommendation/isStrainGranularity` 随本提交一并入库。T6 会话后续对该二文件的提交可能显示为空(其增量已含于本提交)。
|
|
|
+2. **分支推进**:本地 `cfclub` 已与 `origin/cfclub` 对齐(`be391106e`);本提交后为本地领先 1,`git push origin cfclub` 应可快进。
|
|
|
+3. **C 档**:四项探测结论(C1 新增分支 / C2 服务接口 / C3 补规则 / C4 已有门禁)已记录于「二、C 档探测结论」,供计划 §四 转 A 档。
|