Files
lislgosms/docs/unreported-signature-diagnosis-20260921.md
T

49 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-09-21 预生产未报备签名漏统计只读诊断
核验时间:2026-09-21 15:0915:12(北京时间)。授权仅排查,不修复、不部署、不改变线上数据。
## 当前证据
- 预生产 8.160.169.106,运行提交 `001d5f2cbdbd19e56c4de914bd3b94a04c3b19c5`cmpp-api active;实际工作目录 `/opt/cmpp-platform/api`。本地 main 同提交,现有 origin/main 跟踪差异 0/0,未 fetch;暂存区为空,其他会话修改保留。
- 真实 PostgreSQL `cmpp_platform``server_encoding=SQL_ASCII`。查询全部在 READ ONLY 事务内,statement_timeout 1215 秒,结束回滚。
- 今天【宜都市万商市场投资有限公司】共有64条业务短信,企业为“启瑞企业”,应用为“启瑞物业-From老平台”,入队时间北京时间12:12:21.23814:19:39.114。全部 signatureId 为空,status=failederrorCode=SIGNATURE,错误说明“短信内容未识别到已审核通过的签名”。未查询或输出收件号码及完整正文。
- 当前企业应用有效签名库精确同名记录为0。存在的是另一个名称【宜都市万商商业运营有限公司】,审核/报备均 approved,不能替代用户询问的签名。
- 正文从规范黑括号开始,前缀字节为 `e38090`。线上运行产物 `api/dist/signature-retirement/signature-retirement.service.js:520` 使用 `SUBSTRING(message.content FROM '^【[^【】]+】')`;该表达式对全部64条返回NULL。
- 只读对照表达式 `^【.+?】` 对同一64条均提取出完整目标签名。对照仅证明现有表达式漏识别,不代表替代表达式已满足异常/嵌套括号等全部验收规则。
## 根因及范围
当前数据库按 SQL_ASCII 处理字符串,现有排除字符集合 `[^【】]` 按字节处理中文括号及正文,误排除共享字节的汉字;提取结果为空后被 `signature_name IS NOT NULL` 条件剔除。因此该签名按业务规则应进入统计,实际因统计提取缺陷漏掉,非日期或已登记签名排除。
需求依据:first-version-development-requirements.md 未报备签名规则;测试依据:system-functional-test-cases.md 的 TC-SIGNATURE-RETIREMENT-022/023/028/029。同一表达式同时存在于实时查询 `api/src/signature-retirement/signature-retirement.service.ts` 与日报聚合 `api/src/signature-analytics/analytics-aggregate.ts`,修复须同时覆盖。历史冻结报表不应未经授权重算。
15:1115:12扩大只读对照:今天signatureId为空1327条,原表达式识别629条,对照识别1318条;进一步限定真实企业/应用关联、有效签名库无同名记录,得到655条/61个签名与应用组合的潜在遗漏。此为对照候选量,未逐一核验异常正文,不能冒称全部应补计或历史总影响。
## 后续最小修复建议与边界
在保持规范开头签名、企业应用归属和有效签名库判定不变的前提下,修复实时及日报提取对 SQL_ASCII 的兼容;在真实 SQL_ASCII 与 UTF8 隔离数据库验证汉字、非规范开头、嵌套括号、已有签名、分页及数量。无需将迁移数据库编码作为本次最小修复。
本轮未调用HTTP登录后接口、未做浏览器页面验收;数据库和线上运行表达式已直接复现原因。无业务代码修改、提交、推送、部署、发短信、重投或配置变更,仅新增本记录及进度条目。初次前缀字符截取因SQL_ASCII字节截断产生UTF8转换错误,改为完整字节十六进制核验;扩大统计初次SQL列名歧义,限定x.name后通过,失败事务均未写入数据。
## 后续授权修复与本地验收(2026-09-21)
用户在诊断后明确授权“修复、提交代码”,不包含推送、部署或历史重算;上文仅排查边界保留为前一阶段记录。
最小修复:新增共用 `leadingSignatureSql`,实时查询和日报聚合统一采用 `^【(?:(?!【|】).)+】`。负向前瞻检查完整开闭括号,不再用中文排除字符集合;非捕获分组保证提取结果包含外侧括号。保留非空内容、开头定位、拒绝嵌套括号,以及原租户/应用/有效签名匹配、signatureId、日期、排序和分页逻辑。无数据库迁移、编码变更、接口字段或权限修改;现有需求不变,无需新增业务设计。
验证结果:
- PostgreSQL 16.14 两种编码各自新建本机隔离库,使用提交内的113项迁移(排除其他会话未提交的mobile-rule迁移)。`tools/testing/verify-unreported-signature-encoding.mjs` 在UTF8、SQL_ASCII均通过:26种直接提取输入,64条目标案例,日期起止边界、其他企业/应用同名、有效/待审核/已删除签名、已有signatureId、空应用、非规范及嵌套括号。
- 真实后端服务生成并持久化昨日日报,两日均得到13个预期聚合组;真实Nest控制器HTTP返回与数据库一致,验证每页10条的两页、三类搜索、空结果、参数化输入及非法日期/页码。测试仅注册所需控制器及服务,不注册整套应用全局认证/授权,不能冒称登录权限或浏览器已验收。没有启动发送/通知调度、Gateway、Redis或MinIO,实际Submit记录为0。
- 隔离库验证冻结日期已有报表不重算:源消息改变后普通生成跳过,补建覆盖被拒绝,历史计数仍为1。
- API全量87套/990项通过,覆盖率语句68.05%、分支53.73%、函数69%、行70.77%,达到现有门禁;新公共函数覆盖100%。API生产TypeScript构建、五个本轮代码文件ESLint(零错误零警告)、Prettier通过。
- 15:33:24北京时间在预生产READ ONLY事务中对同一64条再次对照:旧提取0、新提取64,结束回滚。仅查询表达式对照,不是部署或页面修复。
原始失败保留:首先使用的旧PostgreSQL16运行目录缺dict_snowballinitdb失败,改用现有完整pgsql运行目录后成功;初次HTTP分页验收传入不支持的pageSize=2,返回400。夹具改为13组、每页10条,并在两种编码新空库重新迁移和完整复验通过,未放宽业务规则。原失败库/日志保留。
证据目录:`.local-data/unreported-signature-20260921/`,包括 `real-utf8-verified.log``real-ascii-verified.log`、两份 `migrate-*-verified.log``api-coverage.log``build.log``lint.log``format.log``preprod-readonly-comparison.log`。复跑需API构建、全迁移的本机新空库,设置 `SIGNATURE_TEST_DATABASE_URL`(库名须以cmpp_qa_signature_encoding_开头),执行上述脚本;脚本拒绝远端/非隔离库及已有租户库,不自动清空数据。
本轮交付为本地代码、回归脚本、需求兼容说明、测试用例及实施记录;本地提交号以Git结果为准。未推送、未部署,预生产页面仍运行旧统计逻辑,冻结报表未修正。无前端/Gateway变更,未重跑前端、Go或线上登录页面验收。
提交前补充精确版本复验:从暂存区导出独立候选,仅共享已安装依赖,未带入其他会话未提交代码/测试。候选API全量86套/922项通过,覆盖率68.05/53.73/69.02/70.77达门禁,生产构建通过;候选编译产物在两种编码的另外两个全新库完整复跑上述真实PG/日报/HTTP脚本均通过。前文87套/990项为工作区验证,包含他轮未提交测试,不能用作本次精确提交测试数。最终证据为 `candidate-api-coverage.log``candidate-build.log``real-utf8-candidate.log``real-ascii-candidate.log` 及对应迁移日志。专用本机PG集群已停止,数据和日志保留。暂存脚本初次读取较大进度文档达到Node默认输出缓冲限制,检查已暂存范围后提高本地缓冲并续接,没有覆盖其他会话内容。