You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

8.8 KiB

13 a7-parity 补码成果 Demo E2E(浏览器级冒烟)

Type: task Status: resolved(2026-09-08)

Question

参照 dict-alignment「Demo E2E」模式(.scratch/dict-alignment/demo/index.html + demo_smoke.py,20260907 修改版为底),对票 07–11 落地的 a7-parity 补码成果做浏览器级 e2e 验证:

  1. 新建 .scratch/a7-parity/demo/index.html 单文件 demo(沿用 dict-alignment demo 的样式/登录(uid 直登)/toast/弹窗/api helper 底座),按域分 tab 覆盖:
    • A7-1/A7-2(票 07):用户统计出参三时间戳、批量分配角色(增量语义)、移交预览/执行/快照、角色 stats/copy 停用草稿/enable 两道校验/disable 内置保护、资源 enable/disable/references/禁删三段(61020/61021)。
    • 方案推送规则(票 08):8 端点版本化状态机 + 4 步骤 push_config + 发布校验(64029 同名发布中唯一 / 64030 创建方式值域与查重引用)+ 默认顶替同适用范围分组。
    • 项目查重规则(票 09):8 端点 + 适用范围三档(64031 非全部档设默认拒绝)+ referenceCount 引用计数联测(推送规则引用→count 变化)。
    • 项目规则 + LeadPool(票 10):GET /current 聚合回显 + 5 分区保存(64036 校验)、LeadPool memberUserIds 部门成员回显、导入导出。
    • 字典种子(票 11):opp_stage 06/07 与 opportunity_status 种子可见性(读端点验证)。
  2. 新建 demo_smoke.py(Playwright chromium headless):pre_clean 幂等清理 + 分步断言 + console/page error 零容忍 + 网络层零 PUT/DELETE/路径变量断言 + API 正门清理 + 截图落 shots/ + 结果写 demo-smoke-result.json
  3. 运行至全 PASS;发现的真实缺陷记录(修复需另行确认范围)。

Answer

resolved(2026-09-08)。47/47 全 PASS(两轮幂等重跑均 ALL_PASS=True),console_errors=0 / page_errors=0,网络层 118 请求零 PUT/DELETE、零路径变量形态;crm-rule 全量测试绿、改动 Java 文件 BOM 0。未提交 git。

交付物(本目录)demo/index.html(单文件 demo,4 tab:用户与角色 / 方案推送规则 / 项目查重规则 / 项目规则·线索池,沿 dict-alignment demo 底座:uid 登录 / api helper / toast / 步骤面板 / 执行日志;TS 经 URL ?ts= 注入对齐脚本侧)+ demo_smoke.py(Playwright chromium headless 47 步)+ shots/00-09*.png(10 张)+ demo-smoke-result.json

覆盖矩阵(47 步)

  • 票 07(A7-1/A7-2,18 步):users/stats 三时间戳出参;users/page 新入参;移交联测(preview 四域 → 自移交 61019 → 执行 admin→BUDDY 全域清零 → 返还 BUDDY 净零+admin 保底 → stats.lastTransferTime 落值);角色(stats 四计数 / assign-roles-batch 增量分配 BUDDY / copy 停用草稿 _copy_ / enable 无授权 61021 / disable 内置保护 61012 / 角色还原+删除);权限点(saveOrUpdate BUTTON 必填 denyBehavior+apiUrl / references 引用清单 / 启停 roundtrip / 禁删两段:启用删 61009 仅停用可删 → 停用后删 61020 被角色引用,经「演示角色 RD 授权→停用 RD→停资源→删」确定性链路触达)。
  • 票 08(推送规则,9 步):嵌套索引属性路径绑定(pushConfig.basic.pushNodeName 等)建草稿→详情回显一致;D-01 修复验证(无步骤④发布成功);发布+versions;64029 同名发布中唯一;64030 创建方式值域;copy 新编码 V1.0 草稿;disable+64027 仅草稿可删。
  • 票 09(查重规则,7 步):D1 发布+referenceCount 出参;64031 属地缺适用对象 / 仅全部商机可设默认两路;引用计数联测(推送规则 R5 草稿 dedupRuleId 引用 D1 → detail/versions referenceCount=1,草稿引用入账;清理后回落 0);草稿引用发布拦 64030;状态机 copy/删/停用/64033。
  • 票 10(项目规则+线索池,9 步):current 五区块聚合;stage-alias 分区保存+回显;64036 标底比例越界;池三类成员(负责人/协作人/部门成员用三个不同用户)回填一致;导出 xlsx ZIP 魔数;导入 BatchResult success=1/fail=0(openpyxl 造 12 列模板,部门取空闲部门第二顺位避让 64003)。
  • 票 11(字典种子,1 步):opp_stage 7 值含 06 技术交流/07 竞品打压;opportunity_status 4 值。
  • 收尾断言(3 步):网络层零旧契约形态;各演示数据 API 正门清理(pre_clean 幂等零残留)。

发现并当场修复的真实缺陷(D-01)

  • D-01(crm-rule,OpportunityPushRuleServiceImpl.validateForPublish:步骤①已配但步骤④未配(projectCreation=null)的合法发布场景 NPE → HTTP 500 code=50001。if (StrUtil.isNotBlank(creation.getCreateMode()) 脱空判。修复=补 creation != null 守卫(1 行)+ 回归测试 publishWithoutProjectCreationSucceeds;浏览器级复验发布成功 status=2。crm-rule 全量测试绿(MVN_EXIT=0)。

顺带核证非缺陷 2 项

  • PoolMemberStore 三类成员去重优先级(负责人>协作人>部门成员)把 member=collaborator 同人提交吞并——演示数据自撞,按票 10 设计语义工作。
  • 资源删除三段顺序(①子节点 ②仅停用可删 ③被角色引用 61020)决定了「启用中被引用资源删除」报 61009 而非 61020——e2e 链路按语义顺序构造后两段均验证。

记录在案的文档缺陷(F-01,已修正 2026-09-08):文档仓《保存/发布推送规则》《保存/发布查重规则》4 份 .bru 把 pushConfig/wizardConfig 标为「string(json) 整体 JSON 表单字段」并给整体 JSON 示例——实现无 String→POJO 转换器,照文档示例执行会 400;实际契约=嵌套索引属性路径。已按 bruno-sync「结构听源码」修正 4 文件(body 示例/参数表/请求示例三处 + 绑定形态说明行),并用修正后示例原文对活服执行实证:code=0 草稿建删闭环(PUSH_RULE_13 / DUP_RULE_07)。补丁脚本留存 patch_docs_f01.py;文档仓改动未提交 git。

运行环境mvn -pl crm-app -am clean package -DskipTests(改 Java 后须重打 fat jar,先停 8080 java 进程)→ $env:SPRING_PROFILES_ACTIVE='verify'; $env:CRM_MINIO_AK='admin'; $env:CRM_MINIO_SK='Itc@123456'; java -jar crm-app\target\crm-app-1.0.0-SNAPSHOT.jarpython demo_smoke.py(系统 Python 3.13 + Playwright/openpyxl)。留存物:probe_a7e2e.py(前置探测)、patch_demo*.py(demo 修补脚本)。

v2 布局修订(2026-09-08,用户验收反馈):用户指出 tab 划分过粗、且 dict-alignment 原有字典四页丢失(原始诉求即「demo 用 dict demo 的修改」)。重排为 12 tab

  • A7 八页细分(原 4 个粗 tab 拆开):用户管理 / 角色管理 / 权限点管理 / 方案推送规则 / 项目查重规则 / 项目规则 / 线索池 / 字典种子验证——每页独立 out 容器 + 执行日志;
  • dict-alignment 字典四页原样回归移植:分组管理 / 字典项管理(含二级项父项下拉、设默认联动)/ 两级树 / 引用计数联测(customer_type ref_count 全链路,与 dict demo 逐功能等价);导航加分隔符分组。
  • 冒烟同步改写:run_step 按 data-tab 切页 + 分容器断言,47→49 步(+字典分组/字典项列表预加载移植回归断言×2),两轮幂等重跑 ALL_PASS=True、console/page error 双零、122 请求零旧契约形态。
  • v2 期间修 demo 自身 bug 一处:outBox/logLine 助手误把 #id 选择器串传给 getElementById$ 助手收裸 id)→ 4 个助手改用 document.getElementById(box);该 bug 曾致用户/角色/权限点等页首个步骤全部渲染失败。

v3 字典页对齐原型 v2 契约(2026-09-08):dict-alignment 票 08/09 落地后(列表只查一级 + /saveOrUpdate children 复合保存),本 demo 字典四页同款移植对齐:

  • 字典项管理:列表只渲染一级行,二级子项随 /page 行内嵌 children 返回(含停用),点行首箭头展开为独立子行(编辑/停用/删除,复用既有单端点);「删最后一个子项」走子行删除(children 空载荷=单项保存,不触发全量替换——契约边角在弹窗内拦截提示)。
  • 复合弹窗:children 列表行编辑(带 id 更新/不带 id 新建且键值=名称/缺失删行置灰);键值字段动态启停(复合新增禁用、后端取字典名称;单项与编辑维持 63001 必填);isDefault 一级/子项均可勾(同载荷仅一行 true);删除旧「父项下拉」与 linkDefaultAfterSave 反查联动(后端 applyDefaultFlag 直达)。新增后端守卫「二级项不可换组 63008」。
  • 冒烟重跑:49/49 ALL_PASS、console/page error 双零、122 请求零旧契约形态(verify profile + MinIO fat jar 活服);截图 shots/v2-ditem.png。