-- S8-LEGACY-RUNTIME-RETIREMENT-1 · TASK D：停用全部 Legacy 取数模式的监控规则。
--
-- 产品裁决：STANDARD_DATASET 成为**唯一允许运行**的 Rule DataAccessMode。
-- Legacy 规则不再具备运行资格 —— 但它们是历史数据，必须留下。
--
-- ┌── 本脚本只做一件事：enabled = 0 ────────────────────────────────────────────
-- │ 明确**不做**（做了就是数据损坏，不是迁移）：
-- │   · 不 DELETE 任何规则行
-- │   · 不改 data_access_mode（NULL 保持 NULL —— 见下方"判定口径"）
-- │   · 不填 dataset_code（没有真实 Provider 的 dataset_code 是伪造）
-- │   · 不改 expression / data_source_id / params_json
-- │   · 不动历史 ado_s8_detection_log / ado_s8_exception
-- └────────────────────────────────────────────────────────────────────────────
--
-- 判定口径必须与代码 S8DataAccessMode.Resolve 完全一致：
--     NULL / 空白 / 'LEGACY_SQL'(大小写不敏感)  → LEGACY_SQL → 无运行资格
--     'STANDARD_DATASET'                        → 有运行资格
-- 因此这里用「NOT (mode = 'STANDARD_DATASET')」的**补集**写法而非枚举 Legacy 值：
-- 万一库里存在既非 Legacy 也非 Standard 的脏值（如 'SQL'），补集写法会连它一起停掉，
-- 与 S8RuleCreationPolicy.IsRuntimeEligible 对脏值返回 false 的语义对齐；
-- 若枚举 Legacy 值，脏值行会被漏掉而继续保持 enabled=1。
--
-- NULL 处理：`data_access_mode <> 'STANDARD_DATASET'` 对 NULL 求值为 UNKNOWN（不成立），
-- 会漏掉全部 132 条历史行，故必须显式写 `IS NULL OR ...`。这是本脚本最容易写错的一处。
--
-- 与代码防御的关系（两者都要，不是二选一）：
--   本脚本 = 清理现存状态；代码三层防御 = 保证将来即使有人手工置 enabled=1 也不会执行。
--
-- 幂等：带 enabled = 1 前置条件，重复执行影响行数为 0。
-- 验收：执行后 Legacy 规则总数不变，其中 enabled=1 的条数应为 0。

UPDATE ado_s8_watch_rule
   SET enabled = 0,
       updated_at = NOW()
 WHERE enabled = 1
   AND (
         data_access_mode IS NULL
      OR TRIM(data_access_mode) = ''
      OR UPPER(TRIM(data_access_mode)) <> 'STANDARD_DATASET'
   );
