• Data Governance Dev's avatar
    feat(web3): date 规则 value 自动 patch 成 datetime 对象再调 check · 135fef49
    Data Governance Dev authored
    问题(commit 5ffa4cc4 之后又暴露):
    
    用户重跑 test3,attendance_in_time(rule_id=31)仍判不合规。
    诊断:pymysql/oracledb/dmPython 把 DATETIME 字段自动转成 Python datetime 对象,
    但用户规则代码里的 strptime 用了 '%Y-%m-%d'(只接受纯日期),
    而 str(datetime_obj) 是 'YYYY-MM-DD HH:MM:SS'(空格分隔的日期+时间),
    格式不匹配 → ValueError → except 吞 → False。
    
    修法:在 run_rule 调 check 前先做一次宽泛解析,把任意类型的 val 归一化成
    datetime.datetime 对象。用户写规则直接 value.date() / .year / .strftime() 用,
    不再关心 val 的原始类型(驱动转的 datetime 对象 / str / bytes / None)。
    
    1. backend/core/rule_runner.py
       - 新增 _DATE_PARSE_FORMATS:10 种常见格式(MySQL DATETIME 默认 / ISO8601 /
         紧凑 / 斜杠分隔 等)
       - 新增 _patch_date_value(val):datetime/date/str/bytes → datetime.datetime,
         解析失败返 None
       - run_rule 的 date 分支先 patch:成功 → _exec_user_function(code, dt);
         失败 → 抛 RuleRunError('无法解析为日期:...') 让 issues 暴露原因
    
    2. backend/core/ai_rule.py
       - _DATE_USER_TEMPLATE_INITIAL / _DATE_USER_TEMPLATE_FIX 完全改写:
         「value 已经是 datetime.datetime 对象(后端已自动宽泛解析)」
         去掉所有 datetime.datetime.strptime 教学,改用 value.date() / .year 等
    
    3. src/components/RuleModal.vue
       - codePlaceholder(date) 改 'def check(value) -> bool:\n    return value.date() < datetime.date.today()'
       - date 类型 form-hint 改 'value 已是 datetime 对象;不要再 strptime'
         (红字警示)
    
    4. tests/test_rule_runner.py
       - 删 1 条过时的 strptime 风格用例 test_strptime_format_check
       - TestDate 加 8 条用例:patch 后传 datetime / datetime 对象直接传 /
         MySQL 默认格式 / ISO8601 / 紧凑 / 斜杠 / bytes / 解析失败抛 RuleRunError /
         None 抛 RuleRunError / 老 strptime 风格代码在 patch 下返 False(迁移信号)
       - 新 TestPatchDateValue 类 11 条用例:锁 _patch_date_value 的 12 种类型行为
    
    5. tests/test_rule_types_e2e.py
       - test_queries_run_dispatches_by_rule_type 里 birthday 规则的 code
         改成新风格 'value.date() <= datetime.date.today()'
    
    对老规则的影响(migration gap):
    - DB 里的旧 strptime 风格代码(rule_id=28 / 31)继续返 False —— 行为不变,
      用户需去 UI 改成新风格。按 CLAUDE.md「本工具只做查询」不动 DB。
    - 新生成的或手写正确代码直接用 value.date() 等,跟 patch 行为兼容。
    
    60 条测试全过(+9 新增)。
    135fef49
RuleModal.vue 11.9 KB