-
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