刘光辉
昨天 bb638871a7fb692d80f1b7a758f991dc0879002c
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package jnpf.bizcommon.audit.service.sign;
 
/**
 * {@link AuditSignMetaData#parse} 的纯 JVM 断言——覆盖真实生产样本 + 降级路径。
 *
 * <p>骨架与 {@link AuditSignFieldProbe} 同族(mvn -o + javac + 直调 main)。
 * 四条真实样本取自 {@code lims_sign.meta_data}(2026-08-01 只读查询,字段顺序、值均原样保留,
 * 未做任何简化——line-by-line 与库里实际存的 JSON 一致,见 task-6-report.md 的行为验证章节)。
 *
 * <p>runner:{@code tasks/audit-sign-field-checks.sh}
 */
public final class AuditSignMetaDataProbe {
 
    private static int pass;
    private static int fail;
 
    /** f_id=853033878464640709,复核动作,is_review_button=true。 */
    private static final String SAMPLE_REVIEW_1 =
            "{\"is_review_button\":true,\"biz_button\":\"复核\",\"biz_data\":[{\"id\":\"852927614623561029\","
            + "\"flowId\":\"\",\"bian_hao\":\"1\",\"beizhu\":\"111\",\"tijiao_ren\":\"349057407209541\","
            + "\"fuhe_ren\":\"817410893825462789\",\"biz_sign\":\"853023946319214277\","
            + "\"fuhe_sign\":\"852927419957524037\"}],\"biz_form_id\":\"852852941198079301\","
            + "\"biz_module\":\"\",\"biz_title\":\"\",\"is_biz_form\":true}";
 
    /** f_id=853030727456011973,同一张单子的第二次复核提交,形态与上一条一致。 */
    private static final String SAMPLE_REVIEW_2 =
            "{\"is_review_button\":true,\"biz_button\":\"复核\",\"biz_data\":[{\"id\":\"852927614623561029\","
            + "\"flowId\":\"\",\"bian_hao\":\"1\",\"beizhu\":\"111\",\"tijiao_ren\":\"349057407209541\","
            + "\"fuhe_ren\":\"817410893825462789\",\"biz_sign\":\"853023946319214277\","
            + "\"fuhe_sign\":\"852927419957524037\"}],\"biz_form_id\":\"852852941198079301\","
            + "\"biz_module\":\"\",\"biz_title\":\"\",\"is_biz_form\":true}";
 
    /** f_id=853027186830096069,批量按钮、非复核,biz_data 是列表行快照(多个 *_jnpfId 影子字段)。 */
    private static final String SAMPLE_BATCH_BUTTON =
            "{\"is_review_button\":false,\"biz_button\":\"批量按钮\",\"biz_data\":[{\"bian_hao_jnpfId\":\"1\","
            + "\"flowTaskId\":\"852927614623561029\",\"tijiao_ren_jnpfId\":\"349057407209541\","
            + "\"beizhu_jnpfId\":\"111\",\"biz_sign_jnpfId\":null,\"biz_sign\":null,\"bian_hao\":\"1\","
            + "\"f_flow_task_id\":\"852927614623561029\",\"tijiao_ren\":\"管理员/admin\","
            + "\"fuhe_ren\":\"wuyong/wuyong\",\"fuhe_ren_jnpfId\":\"817410893825462789\",\"fuhe_sign\":null,"
            + "\"fuhe_sign_jnpfId\":null,\"f_version\":2,\"beizhu\":\"111\",\"f_id\":\"852927614623561029\","
            + "\"id\":\"852927614623561029\",\"_id\":null,\"f_flow_id\":null,\"flowId\":null}],"
            + "\"biz_form_id\":\"852852941198079301\",\"biz_module\":\"\",\"biz_title\":\"\","
            + "\"is_biz_form\":false}";
 
    /** f_id=853026858244126405,列表按钮、非复核——与批量按钮样本仅 biz_button 不同,其余同构。 */
    private static final String SAMPLE_LIST_BUTTON =
            "{\"is_review_button\":false,\"biz_button\":\"列表按钮\",\"biz_data\":[{\"bian_hao_jnpfId\":\"1\","
            + "\"flowTaskId\":\"852927614623561029\",\"tijiao_ren_jnpfId\":\"349057407209541\","
            + "\"beizhu_jnpfId\":\"111\",\"biz_sign_jnpfId\":null,\"biz_sign\":null,\"bian_hao\":\"1\","
            + "\"f_flow_task_id\":\"852927614623561029\",\"tijiao_ren\":\"管理员/admin\","
            + "\"fuhe_ren\":\"wuyong/wuyong\",\"fuhe_ren_jnpfId\":\"817410893825462789\",\"fuhe_sign\":null,"
            + "\"fuhe_sign_jnpfId\":null,\"f_version\":2,\"beizhu\":\"111\",\"f_id\":\"852927614623561029\","
            + "\"id\":\"852927614623561029\",\"_id\":null,\"f_flow_id\":null,\"flowId\":null}],"
            + "\"biz_form_id\":\"852852941198079301\",\"biz_module\":\"\",\"biz_title\":\"\","
            + "\"is_biz_form\":false}";
 
    public static void main(String[] args) {
        realReviewSamplesParseCorrectly();
        realNonReviewSamplesParseCorrectly();
        nullAndBlankReturnEmpty();
        malformedJsonNeverThrows();
        missingKeysDegradeGracefully();
        blankBizButtonTreatedAsAbsent();
        System.out.println("=== meta_data 动作语义断言:" + pass + " 通过 / " + fail + " 失败 ===");
        if (fail > 0) {
            System.exit(1);
        }
    }
 
    /** M1 真实复核样本:biz_button="复核"、is_review_button=true、rawBizData 非空。 */
    private static void realReviewSamplesParseCorrectly() {
        for (String json : new String[] {SAMPLE_REVIEW_1, SAMPLE_REVIEW_2}) {
            AuditSignMetaData md = AuditSignMetaData.parse(json);
            check("M1 复核样本 biz_button=复核", "复核".equals(md.bizButton()), "实际 " + md.bizButton());
            check("M1 复核样本 isReviewButton=true", md.isReviewButton(), "实际 " + md.isReviewButton());
            check("M1 复核样本 rawBizData 非空", md.rawBizData() != null, "实际 null");
        }
    }
 
    /** M2 真实非复核样本(批量按钮/列表按钮):is_review_button=false,按钮名各自透传。 */
    private static void realNonReviewSamplesParseCorrectly() {
        AuditSignMetaData batch = AuditSignMetaData.parse(SAMPLE_BATCH_BUTTON);
        check("M2 批量按钮样本 biz_button=批量按钮", "批量按钮".equals(batch.bizButton()), "实际 " + batch.bizButton());
        check("M2 批量按钮样本 isReviewButton=false", !batch.isReviewButton(), "实际 " + batch.isReviewButton());
 
        AuditSignMetaData list = AuditSignMetaData.parse(SAMPLE_LIST_BUTTON);
        check("M2 列表按钮样本 biz_button=列表按钮", "列表按钮".equals(list.bizButton()), "实际 " + list.bizButton());
        check("M2 列表按钮样本 isReviewButton=false", !list.isReviewButton(), "实际 " + list.isReviewButton());
    }
 
    /** M3 null / 空串 / 纯空白:一律返回 EMPTY,三个 getter 都是「拿不到」的零值。 */
    private static void nullAndBlankReturnEmpty() {
        for (String json : new String[] {null, "", "   "}) {
            AuditSignMetaData md = AuditSignMetaData.parse(json);
            check("M3 null/空串/空白 → EMPTY", md == AuditSignMetaData.EMPTY, "json=[" + json + "] 实际未返回 EMPTY 实例");
            check("M3 EMPTY.bizButton()==null", md.bizButton() == null, "实际 " + md.bizButton());
            check("M3 EMPTY.isReviewButton()==false", !md.isReviewButton(), "实际 " + md.isReviewButton());
            check("M3 EMPTY.rawBizData()==null", md.rawBizData() == null, "实际 " + md.rawBizData());
        }
    }
 
    /** M4 非 JSON 字符串:解析失败必须降级为 EMPTY,绝不能抛异常炸穿调用方(brief 硬约束)。 */
    private static void malformedJsonNeverThrows() {
        String[] garbage = {"{not json", "not even braces", "{\"a\":}", "[]", "null", "123"};
        for (String json : garbage) {
            try {
                AuditSignMetaData md = AuditSignMetaData.parse(json);
                check("M4 非法 JSON 不抛异常,返回非空对象 [" + json + "]", md != null, "实际 null");
            } catch (Throwable t) {
                fail++;
                System.out.println("  ❌ M4 非法 JSON 抛出异常 [" + json + "] —— " + t);
            }
        }
    }
 
    /** M5 合法 JSON 但没有 biz_button/is_review_button 键:降级为拿不到,不是抛异常也不是瞎猜。 */
    private static void missingKeysDegradeGracefully() {
        AuditSignMetaData md = AuditSignMetaData.parse("{\"foo\":\"bar\"}");
        check("M5 缺键时 bizButton()==null", md.bizButton() == null, "实际 " + md.bizButton());
        check("M5 缺键时 isReviewButton()==false", !md.isReviewButton(), "实际 " + md.isReviewButton());
    }
 
    /** M6 biz_button 为空串:视同「拿不到」返回 null,而不是把空串当成一个有效按钮名往下传。 */
    private static void blankBizButtonTreatedAsAbsent() {
        AuditSignMetaData md = AuditSignMetaData.parse("{\"biz_button\":\"\",\"is_review_button\":false}");
        check("M6 biz_button 空串 → bizButton()==null", md.bizButton() == null, "实际 [" + md.bizButton() + "]");
    }
 
    private static void check(String name, boolean ok, String detail) {
        if (ok) {
            pass++;
            System.out.println("  ✅ " + name);
        } else {
            fail++;
            System.out.println("  ❌ " + name + " —— " + detail);
        }
    }
}