刘光辉
13 小时以前 34981c30a78e8bbd7791131059a9210f9928b62c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# 审计层 0(在线表单事件)表单注册表 —— Task C1
#
# 这份配置同时回答两个问题:**哪些应用前台请求要审计,以及已知业务表如何补充审计元数据**。
# 它取代了 lims 侧 BizFormRegistry 里那张 18 条的硬编码静态 Map——原先每接一个新表单都要改
# lims 代码、重新打包、重启服务;现在各业务模块自助在这里登记,audit 服务不动代码。
#
# 为什么单独一个配置文件(而不是并进服务自身的配置):这份表由**业务模块**维护、改动频繁,
# 而 jnpf-biz-common.yaml 是服务自身的日志等配置。混在一起,业务改一行表名就有把服务配置改坏的机会。
# (2026-08-11 前对照的是 jnpf-audit.yaml,该文件随 audit 搬入 biz-common 已删除。)
#
# ── 怎么加一张表 ───────────────────────────────────────────────────────────────
# 1. 认的是**主表名**(不是 modelId)。modelId 是无意义的雪花数字、且同一张主表常有多个表单视图
#    (列表页/详情页/移动端各一个 modelId),按表登记只需一条。modelId → 主表名由 audit 服务
#    反查 base_visual_release.F_TABLES_DATA(typeId=1 那张)并缓存,无需在此登记。
# 2. **清单是 YAML 列表(`- table: xxx`),不是 map**。这不是风格偏好:Spring Boot Binder 对
#    map 属性做的是**合并**,而不是整体替换——当年走 Nacos 热推送时,删掉一行**不会**生效,
#    那张表会一直被审计到下次重启为止(C1 实测踩到并已修)。补丁 #8 起配置只在服务启动/重启时
#    整体绑定一次,已无热推送场景,但列表格式仍保留:增删语义清晰,行为不随加载机制变化。
# 3. 除 table 外都可选,缺了只是记得糙一点,**不会让事件丢失**:
#      biz-module      落 audit_events.biz_module,用户视角的「在什么应用上操作的」
#      biz-type        落 biz_type,业务分类,与旧 lims_biz_log 的 BizLogType 同位
#      biz-code-field  从表单数据里取业务单号的字段名,落 biz_code;没有业务单号就别配
#      masked-fields   脱敏字段:只记「已变更」不记值
# 4. 改完这份文件后需要让 jnpf-audit 重新读取配置才生效(补丁 #8 起不再有 Nacos 热推送):
#    宿主 java -jar 栈(start-all.sh)直接重启 jnpf-audit 即可;容器栈(docker compose)需要
#    重建该服务镜像,或用 volume 挂载覆盖 /config/shared 后重启容器(开发 override 已挂载,
#    改完直接重启容器生效)。即便如此,相对 lims 旧硬编码依然是数量级的提效——那张表改一行
#    过去要改代码、重新打包、重启服务,现在只是改配置文件 + 重启。
# 5. ⚠️ **要停掉全部层 0 审计,写 `enabled: false` 或 `forms: []`,不要把 forms 这个键整个删掉。**
#    键还在(哪怕是空列表)binder 才会调 setter 让清单整体替换;键被删掉时 binder 根本不调 setter,
#    服务里会留着上一版的清单继续审计——同 L062 一个家族的坑,只是另一半形态。
#
# ── 已知边界(不是 bug,但会影响你怎么读产出)─────────────────────────────────
# · **脱敏列判定不了「是否变更」**:层 0 的变更前值来自上一条事件的快照,而快照里脱敏列存的是
#   `***`。拿它跟真值比必然不等,会把「没改过」报成「改过」——所以层 0 对脱敏列**一律不产出
#   diff**,只在 extra.maskedUndecidable 里列出这些列名。
#   ⚠️ 2026-08-11 起这是**无覆盖手段的已知缺口**:原先此处写「要判定脱敏字段是否真的变了,用层 1
#   (before-image 取自 SELECT 原值)」,而层 1 已整套移除(自交付起从未启用,source_layer=1 零行)。
#   现在没有任何层次能回答「脱敏字段是否真的变了」,只能知道「这次操作动过这张表」。
# · **快速连续修改会丢 diff**:同一行在秒级内被连改多次时,前 1-2 条事件会因并发消费窗口
#   取不到 baseline,记 extra.baselineSource=missing(可见降级,非静默丢失,快照链不断)。
#   量化见 tasks/audit-l0-concurrency-probe.sh。
# · **字段中文标签取自事件 listLog**:只有「本次实际发生变化」的字段才在 listLog 里带标签;
#   同值保存等情况下该字段不在 listLog 中,diff 的 fieldName 会回落成字段名本身。
#
# ── ⚠️ 范围怎么定的(2026-07-27 上线-2 修订)────────────────────────────────────
# 原先这里写着「在做完 B6-后续 ⑥(~50-65 ms 未归因开销)之前不要批量放开」。
# **这条前提已撤下**——它是按「放开 18 张表 + 未知量级」推的,而共享库真实用量实测推翻了它:
#   lims_qingyandan 共 70 行、lims_jianyan_xiang 126 条、lims_biz_log 72 行 / 2 个月。
# 每次表单保存多十几毫秒,在这个量级上没有意义。
#
# **登记的是主表名,一条覆盖该表的全部表单视图。** 实测(本机库 base_visual_release 148 条):
#   lims_qingyandan       ← 15 个表单视图(产品请验单/待取样记录/待接样记录/制作报告/原辅包请验单/
#                            自制溶液请验单/个人请验台账/已取样记录/已接样记录/报告台账/报告审核/
#                            报告批准/样品分检弹窗/样品组合分检弹窗/细胞库·菌种库请验单)
#   lims_sxt_quyang_jihua ← 1 个(水系统取样计划)
# 共享库真实用量里的 7 个在用 modelId 全部落在这两张表内,故**两条即可**,不需要按 modelId 逐条登记。
#
# ⚠️ **已知缺口:层 0 不处理子表**(spec §3.3 勘误)。「制作报告」的 F_TABLES_DATA 里
# 主表 lims_qingyandan(typeId=1) + **子表 lims_jianyan_xiang(typeId=0)**——子表数据的改动
# 不会产生 diff,静默丢失。
# ⚠️ 2026-08-11 起这也是**无覆盖手段的已知缺口**:原先此处写「要覆盖子表改动得靠层 1
# (它在 SQL 层看得到 lims_jianyan_xiang 的写)」,而层 1 已整套移除。
# 现在子表改动只能靠业务侧加层 2 @AuditLog 埋点覆盖,没有自动兜底。
#
# ⚠️ **biz_type 由静态配置决定,与旧实现的动态判定有形状差**。旧 listener 对同一个 modelId
# 会按动作给出不同 biz_type(如 813788483029051525 既产 QINGYANDAN 也产 QUYANG,
# 814206006757174789 既产 QINGYANDAN 也产 JIEYANG,实测共 6 行);新注册表按表配,
# 这些一律落 QINGYANDAN。新审计模块要区分取样/接样,按 action_code 而不是 biz_type。
#
# 下面把 lims 旧硬编码的 18 张表原样备在注释里,需要时解注释即可,
# 不必再去翻已废弃的 BizFormRegistry 源码。
audit:
  layer0:
    # 层 0 总开关。关掉则整个 listener 直接 return(连注册表都不查)。
    enabled: true
    # 仅记录 /app_<应用编码> 前台请求;/app_backend_<应用编码> 与无应用前缀的总控台不记录。
    frontend-only: true
    # 当前审计范围只包含 LIMS 应用前台。比较时忽略大小写。
    allowed-app-codes: [ LIMS ]
    # 应用前台访问的在线表单全部纳入审计;下面 forms 仍用于提供更准确的模块、分类和业务单号。
    include-unregistered-forms: true
    # READ 默认关闭。开启后列表查询和详情查看各按一次请求记录一条,不保存查询条件与返回数据。
    record-read: false
    forms: