Files
zkxw/docs/testing/2026-10-15-storage-market-report.md
T
2026-10-17 11:46:53 +08:00

15 KiB
Raw Blame History

存储服务与市场移动端完整性测试报告

测试日期:2026-10-15 至 2026-10-16(Asia/Shanghai);测试对象为本地工作区,不代表生产环境已部署。

结论

本轮按照“基线测试 → 复现缺陷 → 制定最小修复方案 → 回归 → 交叉审查 → 真实接口/页面复测”执行。下表列出的已确认缺陷已修复。业务修改限定在指定七个 Web 模块、市场移动页面及对应后端;没有修改 OA、生产、质检等其他模块的业务规则,也没有调整全局权限守卫。

财务真实链路已补验:从数据库查得既有会计账号“张敏”,经正常账号密码登录,完成预签约意向金和正式缴费的页面退回、重新提交、确认及重复操作保护。验收仍存在明确边界:微信真机、网络故障下的原生 web-view、实际对象存储下载和高并发压力未做完整验收。不能将本报告解释为这些场景已经通过,或保证系统不存在任何尚未发现的缺陷。

范围与环境

端 范围 实际实现/入口
Web 采集协议单 /market/cell-storage/protocol-audit,协议专用表单/详情/运输组件
Web 预签约订单 /market/cell-storage/presign-order
Web 缴费信息、催缴信息 /market/cell-storage/payment-info、payment-chase
Web 客户服务管理 /market/cell-storage/sample-info
Web 运费信息、缴费财务确认 /market/cell-storage/sample-freight、payment-confirm
移动 市场专员、地区经理各五模块 presign、protocol、payment、payment-chase、freight

Web 当前菜单名称为“市场 → 存储服务”。小程序工程实际为 mobile-h5;市场入口通过 web-view 打开 mobile-oa-h5。仓库没有名为 miniprogram 的目录。

  • 后端:本地端口 8000;最终回归前用原启动命令和原环境重启,加载修复。
  • Web:端口 3006;市场 H5:端口 5178、base /oa-h5/。
  • 真实登录:首轮使用 admin;财务补测从数据库按有效角色/职位授权查询,选择会计账号“张敏”,经 Web 账号密码表单正常登录。没有修改账号密码、角色或菜单权限;凭据和 Token 不写入报告或仓库。后续需其他权限账号时优先直接查询数据库中的既有用户。
  • 浏览器:Chrome + Playwright;Web 1440×1000,移动 390×844。
  • 权限测试:SQLite 隔离用户、角色、自定义范围及多角色并集。财务状态测试调用真实 CRUD。
  • 测试数据:专用 QA_STORAGE_20261015_… 标记,未修改已有客户/协议/缴费记录。

第一轮缺陷、改造方案与复测

编号 级别 复现/影响 实施方案 回归证据
QA-01 P1 同租户受限用户可越权读取、修改 Web 运费;关联样本可影响无权批次 在批次和样本所属协议应用既有角色数据范围;校验旧关联批次;样本快照由服务器派生 运费权限、并集、伪造快照及跨批次用例通过
QA-02 P1 预签约列表有范围限制,详情/编辑/转正式/转账等单条入口缺失同等保护 十个入口增加对应订单或转账列表模型的数据范围检查 本人、无权、多角色并集三组回归通过
QA-03 P1 直接调用协议审核入口可绕过协议数据范围 审核前复用协议可访问性校验 越权审核拒绝且不调用写服务
QA-04 P1 新建记录创建部门为空,纯部门范围用户可能创建后无法查看 运费、协议、预签约及派生操作从数据库当前用户取得创建部门 服务器部门参数回归通过;不信任客户端部门
QA-05 P2 Web 预签约传 2026-10-15 等非法日期进入 CHAR(8),报数据库 503 Schema 校验 YYYYMMDD 长度与真实日期 修复前 10 失败,修复后日期 18 项通过;真实接口返回 422
QA-06 P2 非有限运费 NaN/Infinity 可导致异常或绕过普通金额检查 Decimal 有限性校验,负数继续拒绝 单元及真实接口错误码 400 验证通过
QA-07 P2 V2 协议已有样本缴费和首期时间,列表缴费方式仍显示“—” 仅协议列表开启 V2 模式汇总;支持混合模式、分改趸 五项新回归及真实接口“趸交”标签通过
QA-08 P2 预签约/正式协议清空可选字段后恢复原值 将清空意图编码为空串/null,避免 JSON 省略 undefined 行为回归通过;真实预签约备注清空保存后重新读取为空
QA-09 P2 删除全部协议或转账附件后保存,旧附件恢复 不再用旧 URL 覆盖空附件列表,明确发送空值 正式/预签约转账、主单附件回归通过
QA-10 P2 上传期间删除前面的附件,上传完成或失败时改错数组项 四处上传回填按临时 ID 查找,处理已移除项 成功与失败竞态回归通过
QA-11 P2 附件上传未结束就保存或提交财务,凭证可能遗漏 保存和提交前检查上传状态 上传中拒绝提交回归通过
QA-12 P1 编辑详情失败仍可保存空表单;预签约字典/详情加载期间输入可被覆盖 初始化全程加载/禁用与就绪校验;失败提示重开,禁止提交 协议详情失败、预签约初始化五项新增回归通过
QA-13 P2 协议运输组件读取不存在的 formData.id;编辑后新增沿用旧 editingId 传真实 editingId,新增初始化清空旧上下文 运输 ID 与新增隔离行为回归通过
QA-14 P2 移动协议切地区保留旧经理/医院,慢响应覆盖新地区 切换时清旧候选、取消旧请求并验证请求身份 新行为测试、两角色真实地区切换通过
QA-15 P2 移动预签约清空地区后 loading 卡住,旧响应回填旧选项 清空加载状态、取消请求、忽略旧响应 新行为测试、两角色真实地区切换通过

另外修正实际引用页面的 18 条类型错误,包括无效导入、金额参数类型和自动完成返回值;未修改闲置的开票/退款 Tab 等范围外代码。

V2 模式汇总通过显式开关限定在协议列表,质检、样本接收等调用保持原有默认行为。权限继续采用所有角色的并集;未把财务权限修改为超级管理员自动绕过。

自动化结果

检查 结果 说明
后端主回归 679/679 39 个去重文件;新增 81 项
客服补充回归 38/38 快捷登记、证书/保险样本级关联、质检信息、办理状态
移动市场 312/312 原 307 项,加 5 项地区联动/竞态回归
Web 单元/行为 85/85 原 54 项,加 31 项表单/附件/初始化回归
Web 既有专用脚本 2/2 缴费预设、缴费详情弹窗布局
小程序市场入口脚本 通过 两角色共十入口、web-view URL/返回路径
独立交叉审查 通过 后端相关集合另跑 263 项;属于重复验证,不再累计
git diff --check 通过 无补丁空白错误
市场 H5 生产构建 通过 既有大包提示
Web 生产构建 通过 默认 2 GB 堆 OOM;提高到 8 GB 后构建成功,存在既有 Sass/大包提示

主回归与客服补充合计 717 个后端用例;加移动、Web 合计 1,114 个用例通过。独立审查和重复回归不重复累计。

关键回归文件:

  • backend/tests/test_web_freight_permissions.py
  • backend/tests/test_web_presign_permissions.py
  • backend/tests/test_presign_order_date_validation.py
  • backend/tests/test_protocol_v2_payment_mode_summary.py
  • backend/tests/test_payment_finance_status_regression.py
  • web-admin/scripts/test-cell-storage-form-regressions.ts
  • mobile-oa-h5/src/market/protocol-region-cascade.test.js
  • mobile-oa-h5/src/market/presign/presign-region-cascade.test.js

新增测试先观察原实现失败再修复。财务四项是补充覆盖,原状态逻辑本身通过:预签约/样本缴费分别验证确认、退回成功,及重复操作不能覆盖状态。权限测试使用真实隔离数据库查询,写服务用 spy 验证越权时未调用;不将其声称为实际 MySQL 完整写链路。

真实页面与业务链路

检查项 结果与边界
七个 Web 列表 均加载成功;检查脚本错误、HTTP 错误和页面整体横向溢出
七类 Web 弹窗 协议新增、预签约新增、缴费明细、催缴关联协议、客服查看、运费编辑、财务确认弹窗均打开
十个移动入口 两角色五模块均可进入;空数据和有数据状态均有覆盖
移动四个新增表单 两角色×协议/预签约;必填校验通过
地区联动 四地区×四表单 16 轮,另 8 轮有经理→无经理;24 轮均符合实际 API
预签约链路 新增、编辑、双角色详情、转账提交/撤回/编辑、转正式;重复转正式拒绝
协议/缴费链路 转正式后增加样本及缴费计划;双角色查看/修改转账、提交、撤回;重复提交拒绝
催缴 逾期测试期次出现;查看缴费关联正确
运费 创建、修改、双角色读取;金额边界拒绝
客服 短信、微生物回访、履约登记后重新查询,三组字段均持久化
表单实际保存 浏览器新增预签约,再分别编辑预签约、正式协议清空备注,API 重新读取确认为空;正式协议最后复测无页面/API错误
最终真实 API 专项 24/24 检查通过,包括 V2 标签、日期、金额、状态保护、十入口
无效请求 10/10 拒绝检查:未登录、非法分页、不存在记录;无数据泄露

移动地区选择器没有“清空”操作入口;清空地区的竞态仅有行为测试覆盖,没有计为真实点击通过。首轮 admin 被严格财务权限拒绝;补测已用既有会计账号完成真实成功流程,所有财务写操作只针对本轮新建的 QA 记录。

财务权限账号补测(2026-10-16)

使用既有“会计”角色用户“张敏”正常登录本地 Web。数据库权限解析覆盖直接角色和职位继承角色;没有变更权限配置。专用数据标记为 QA_FINANCE_20261016_1792081469569。

验证 结果
意向金实际页面退回、重新提交、确认 通过;状态依次为 jfqrz → dfj → jfqrz → yjf
正式缴费实际页面退回、重新提交、确认 通过;状态同上
两类转账在退回后再次退回/确认、确认后再次确认/退回 8 次非法操作均返回业务码 400;原金额及财务备注未被覆盖
待确认与已确认列表 已确认记录从待确认移除,出现在已确认列表;财务备注正确
金额与欠款汇总 意向金确认 12 元;正式缴费确认 30 元,100 元期次剩余 70 元;重复操作没有重复计款
MySQL 持久化 两类转账均为 yjf,更新人为所用会计用户,财务备注保存正确
浏览器错误 4 次实际页面财务动作通过,页面脚本错误 0 条

本次补测 24 次 API 检查和 4 次页面财务提交全部通过(不并入前文 1,114 个隔离/行为用例计数),未发现需要新增代码修复的问题。9 条本次有效测试行按精确 ID/标记软删除,5 个相关列表回查为 0;测试会话已登出,本机临时凭据已移除。原始验证摘要附在证据 JSON 的 financeFollowup 字段。

构建、历史问题与验收限制

  1. 真实财务权限(已补验):admin 的超级管理员标记不能替代严格菜单授权,403 规则保留。已从数据库找到具有显式权限的既有会计账号“张敏”,完成以下真实页面/API/MySQL 验证,此项不再是待验收限制。
  2. Web 全量类型检查:默认堆内存不足;8 GB 重跑完成,错误由 415 条降至 397 条,已修改文件无错误。剩余来自未修改模块及闲置旧组件,未按“全仓通过”报告。
  3. 字段一致性脚本:执行结果 0 errors、5 warnings,退出码 1。警告来自未修改的 consumable/reagent/material/qc_material/sop_document 的 orderNum 或旧前端路径,未扩大范围修复。
  4. 历史部门字段:未擅自回填已有 create_dept_id='' 数据;其在纯部门数据范围下可能不可见。若要修复历史记录,需要基于创建人部门核对后单独制定数据迁移。
  5. 知识图谱:已执行 backend/frontend 更新脚本。后端节点过多,工具跳过 HTML;前端 JSON 节点缩减触发保护,旧 JSON 保留,报告/HTML 已生成。未强制覆盖可能含人工补充的节点。脚本没有 mobile-oa-h5 目标。
  6. 环境瞬断:跨午夜时后端日志记录远程 MySQL 拒绝连接,导致列表刷新一度 503。连接恢复后重测原页面及协议保存通过,未修改网络或数据库配置。
  7. 未覆盖的外部环境:微信真机/正式域名、真实附件上传下载的全面验证、并发压力及生产数据库部署不在本轮已通过清单内。

测试数据清理

本次创建的 16 条有效测试行(含自动生成的客户、关联子表与测试运输字典项)已按精确 ID/标记软删除,未物理删除。六个业务列表按测试标记回查均返回 0 条。保留正常审计日志和业务编号流水,不回退序号。财务补测另创建并清理 9 条有效行,见财务补测小节。

复测命令

后端主回归(先去重 glob,避免重复计数):

cd backend
venv/bin/python - <<'PY'
from glob import glob
import subprocess
patterns = [
    'tests/test_*protocol*.py', 'tests/test_*payment*.py',
    'tests/test_*presign*.py', 'tests/test_*freight*.py',
    'tests/test_*customer_service*.py',
    'tests/test_market_mobile_permissions.py',
    'tests/test_market_field_scope.py',
]
files = sorted({f for p in patterns for f in glob(p)})
raise SystemExit(subprocess.call(['venv/bin/python', '-m', 'pytest', '-q', '--tb=short', *files]))
PY
venv/bin/python -m pytest -q tests/test_sample_info_quick_register.py tests/test_sample_cert_insurance_sample_level.py tests/test_sample_storage_cert_qc.py tests/test_sample_info_handle.py tests/test_sample_info_progress.py
cd web-admin
pnpm exec tsx --test scripts/test-cell-storage-form-regressions.ts
NODE_OPTIONS=--max-old-space-size=8192 pnpm exec vue-tsc --noEmit

cd ../mobile-oa-h5
node --test src/market/*.test.js src/market/presign/*.test.js
pnpm build

cd ..
node mobile-h5/utils/market-h5.test.js

修复计划见 docs/superpowers/plans/2026-10-15-storage-market-completeness.md。测试证据摘要另存同目录 JSON;原始本机日志及截图在 /tmp/zkxw-storage-qa/,含页面业务数据的截图未收入仓库。