lsy-review-status-comment.sql 5.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. -- 乐收赢商户映射 —— review_status 本地词表写进列注释(Task 8 / 三-B,计划 §0.9-1)
  2. --
  3. -- ★★ 2026-09-23 执行记录:**已在本机所连的 payment_platform_java 上执行完毕**。
  4. -- 执行前注释是旧文案(不含 PENDING/REJECTED),执行后三个词齐全;列的 DDL 与数据分布均未变
  5. -- (默认值仍是 'APPROVED'::character varying / NOT NULL / VARCHAR(32))。读数见 logs/_lsy_comment_exec.py 的输出,
  6. -- (脚本只 print 到 stdout、不落盘;原写作 _lsy-comment-exec.txt,2026-09-23 订正)。只读复核见 logs/_lsy_comment_readonly.py。重跑安全:只说一遍 COMMENT,幂等。
  7. --
  8. -- 【原注,保留】执行由用户做。**只改注释,不动任何数据、不动表结构** ⇒ 可安全重复执行。
  9. --
  10. -- ── 为什么要有这个脚本 ────────────────────────────────────────────────
  11. -- V1.8 建表时把这一列写成 `review_status VARCHAR(32) NOT NULL DEFAULT 'APPROVED'`,
  12. -- 但当时**没有定义 B 阶段的词表**:列注释只说「B 阶段由进件写入口与上游审核通知回写」,
  13. -- 没有任何地方枚举过 B 阶段该写什么值。三-B 把这三个值定下来了(计划 §0.9-1 的裁定),
  14. -- 本脚本把词表落进**数据库自己的元数据**里 —— 让以后直接看库的人不必回去翻代码。
  15. --
  16. -- ★ **本脚本不改变任何行为**。真正的约束在 Java 侧:`LsyMerchantReviewStatus` 的三个常量,
  17. -- 有 `LsyMerchantReviewStatusTest` 钉着字面值。本脚本只是把同一份词表抄进注释。
  18. --
  19. -- ── ★ 这一列的真实危险:DEFAULT 'APPROVED' ─────────────────────────────
  20. -- `NOT NULL DEFAULT 'APPROVED'` 意味着**任何不显式给值的 INSERT 都会静默拿到 APPROVED**,
  21. -- 也就是「刚进件、还没审核」在管理端被读成「已通过」。
  22. -- 进件写入口(`LeshouyingOnboardingController.create` → `LsyMerchantService.createOnboardingRow`)
  23. -- **必须显式写 PENDING**,不得依赖列默认值;也不得复用 `LsyMerchantService.save` 的新增分支
  24. -- (那一路正是把 review_status 钉成 APPROVED 的地方,计划 §0.9-3)。
  25. -- 本条**不是**本脚本能保证的,这里写下来是因为「改注释的人」正是最该知道它的人。
  26. --
  27. -- ── 词表三个值的来源(每个词都不是新造的)────────────────────────────
  28. -- PENDING —— 本批次(三-B)**新引入**:进件写入口用它。
  29. -- APPROVED —— 沿用**同一份 DDL 的默认值**里的那个词(逐字 'APPROVED',不是新词)。
  30. -- REJECTED —— 沿用同模块 `pay_lsy_notify_log.process_status` **已在用的**那个词
  31. -- (该列注释逐字列着 RECEIVED/APPLIED/DUPLICATE/REJECTED/...,
  32. -- 且 `LsyNotifyService` 在验签失败分支上写的就是字面量 "REJECTED")。
  33. --
  34. -- ★ 这**不是** spec §6.4 禁的那种「归一化」。那条禁的是把上游**三套** reviewed_status
  35. -- 值域互相猜着合并;这里是给**本地**一列定词表,且只从上游 556 这一套推导。
  36. -- 上游值域 → 本地词表的映射**只此一处**,在 `LsyOnboardingReviewStatus`。
  37. COMMENT ON COLUMN pay_lsy_merchant.review_status IS
  38. '进件审核状态(本地词表,VARCHAR(32))。三种取值:'
  39. 'PENDING=待审核(三-B 新引入,进件写入口写入;新行**不得**落到本列默认值 APPROVED 上);'
  40. 'APPROVED=审核通过(沿用本列 DDL 默认值里的那个词);'
  41. 'REJECTED=审核驳回(沿用同模块 pay_lsy_notify_log.process_status 已在用的那个词)。'
  42. '字面值由 LsyMerchantReviewStatus 常量钉住;上游审核状态到本词表的映射只在 LsyOnboardingReviewStatus 一处,别的类不许各写一份。';
  43. -- ── 只读核对(执行后手工跑一遍)──────────────────────────────────────
  44. --
  45. -- 1) 注释是否落上(**逐字**比对上面那段,注意 psql 会把多行字符串拼成一行)
  46. -- SELECT col_description('pay_lsy_merchant'::regclass,
  47. -- (SELECT ordinal_position FROM information_schema.columns
  48. -- WHERE table_name = 'pay_lsy_merchant' AND column_name = 'review_status'));
  49. -- 期望:一段含 'PENDING'、'APPROVED'、'REJECTED' 三个词的文本。
  50. --
  51. -- 2) 列的默认值**仍然是 APPROVED**(本脚本**故意不改它**)
  52. -- SELECT column_default, is_nullable, character_maximum_length
  53. -- FROM information_schema.columns
  54. -- WHERE table_name = 'pay_lsy_merchant' AND column_name = 'review_status';
  55. -- 期望:`'APPROVED'::character varying | NO | 32`。
  56. -- ★ 若这里被改成了别的值,说明有人动过 DDL —— 那与 `LsyMerchantReviewStatus` 的
  57. -- APPROVED 常量、以及 V1.8 的存量行口径都不一致,需要先裁定再继续。
  58. --
  59. -- 3) 库里的值**是否只在词表内**(本脚本执行前后都可跑;只读)
  60. -- SELECT review_status, count(*) FROM pay_lsy_merchant GROUP BY review_status ORDER BY 1;
  61. -- 期望:出现的值都落在 {PENDING, APPROVED, REJECTED} 内。出现别的值 ⇒ 有写入口没走常量。