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.
 
 
 
 
 

17 KiB

A5 项目管理 demo 缺陷清单(票 16 · 黑盒 e2e 审计)

  • 分级:P0 主流程阻断/数据错误 · P1 功能错误/口径违背 · P2 体验/展示/功能弱化 · P3 建议。
  • 复现环境:demo index.html?api=http://localhost:8080,uid 99021002(销售总监)/ 99021003(普通销售),种子客户 99021001 + 方案卡 99021008。
  • 证据缩写:probe*.json = audit 目录下探针结果;截图 = screenshots/

16R 修复状态(2026-09-11):D-01 已修(看板 badge/冲突入口仅进行中)、D-02 已修(68010 负责人∨管理员∨销售总监,报备专员细分角色随权限系统接线收紧——拍板记 README Decisions)、D-03 部分修(赢单快照四字段随标记落列;输单复盘字段为 spec §8 后续字段 spin-out 不采集)。P2/P3 维持记档待用户验收翻案。复测结论见票 17。 票 17 复测(2026-09-11 · 全新会话复测员):回归冒烟 35/35 PASS;P1 三条复验全部通过(D-01/D-02/D-03=FIXED,未误伤);P2/P3 共 24 项现状抽查全部维持记档(未恶化、未误伤主流程);完整主链回归(建项→报备→推进→3→5连跳→回退→推回5→赢单锁死)11/11 PASS。产物:retest-p1.py / retest-p23.py / retest-mainchain.py + retest-p1/p23/mainchain-result.json + screenshots/r17-*.png + retest-result.json。 票 17 复测观察项(非回归,记档供产品复核):赢单态(stage5/status=1/bid=1)执行「关闭」仍 code=0——ensureCloseable 只拦已关闭/已结项,为票 05-08 原有行为(git 溯源 16R 未触碰该守卫),4-3-11「三终态锁全拒」的记载对赢单态过宽;赢单态 回退 68003 / 推进 68003 / 重复标记 68009 / 报备审核 68008 均正常拒,关闭后进入已关闭终态锁亦正常。

P0

无。主流程(建档→冲突解除双写→逐级推进→3→5 连跳→多步回退→赢单闭环/输单结项→关闭记因→三终态锁)全部走通,未发现数据错误。

P1

D-01 看板「冲突待处理」计数与 stage0 卡冲突入口不排除已关闭项目(死入口 + 计数虚高)

  • 页面:看板(A5-1-1 看板视图)
  • 复现:① uid=99021002 登录;② 新建项目后直接「关闭…」(stage0/status=2);③ 回看板。
  • 期望:已关闭项目不属「冲突待处理」,卡片不应再提供冲突解除入口(详情动作区对终态已正确隐藏)。
  • 实际:badge 与 stage0 列计数把已关闭项目照数计入(截图中 badge=5,其中 4 个已关闭);已关闭卡仍渲染「冲突解除」按钮;点击后服务端 68003 拒绝,属死入口。
  • 证据:GET /project/board stage0 卡 projectStatus=2, conflictActionAvailable=true(4 例);对已关闭项目 POST /project/filing/review{"code":68003,"message":"项目已关闭/已结项(终态锁),不可冲突解除…"};screenshots/14-board-director.png。
  • 注:spec §4 字面写 badge「=stage0 项目数」,但终态口径(§3 三终态锁)优先,且死入口无争议。待复核点仅「计数是否含驳回停留项目」。
  • 复测(票 17):通过(FIXED)——新建项目关闭后 badge 计入再回落(2→3→2);已关闭卡仍显示但无「冲突解除」按钮;API 侧已关闭卡 conflictActionAvailable=false,conflictPendingCount=stage0 进行中数(2)与卡片口径一致;对已关闭项目冲突解除服务端仍 68003 拒(终态锁未松动)。证据 retest-p1-result.json D-01.0~1.6、screenshots/r17-d01-board-after-close.png。

D-02 状态机动作服务端无角色权限校验(除回退外全线裸奔)

  • 页面:详情动作区(原型 A5-1-1-1 冲突处理 / A5-1-1-2 方案设计确认 / A5-1-1-5 赢单输单)
  • 复现:uid=99021003(普通销售,非负责人非报备专员)登录 → 打开他人项目 → 直接调用/点击: ① stage0 项目「冲突解除」提交通过 → 成功,项目 0→1(screenshots/27、28;ui-result4 U41/U41b); ② POST /project/stage/advance → 成功推进; ③ POST /project/close → 成功关闭他人项目; ④ POST /project/bid-result/mark → 成功标记他人项目赢单。
  • 期望(原型权限表):冲突处理仅报备专员+管理员;「确认通过」(推进)仅限项目负责人/销售管理员;标记赢单/输单仅限项目负责人及销售管理员。
  • 实际:仅阶段回退有服务端权限(68005),其余动作任意登录用户可对任意项目执行。
  • 证据:probe2 A2/A4/A8(code=0)、ui-result3/ui-result4。
  • 备注:demo 单机演示下危害有限,但这是服务端口径违背而非前端简化(README 只声明回退权限在服务端强制)。
  • 复测(票 17):通过(FIXED)——普通销售(99021003)对他人项目 冲突解除/推进/关闭/标记赢输 四动作全被 68010 拒(stage0 与 stage5 各验一遍,权限先于状态校验);负责人(99021002)对自己项目 冲突解除/推进/关闭/标记赢单全部成功未误伤;销售对自己(负责人)项目亦可操作,口径=负责人∨管理员∨销售总监。证据 retest-p1-result.json D-02.0~2.8。

D-03 标记赢单/输单不采集快照,开标页签数据永远为空且无写入通道

  • 页面:详情「开标」页签 + stage5 动作(原型 A5-1-1-5 赢单/输单)
  • 复现:stage5 项目点「标记赢单」→ 仅一个 confirm(无表单);成功后打开「开标」页签。
  • 期望(原型弹窗必填):赢单=中标时间/中标金额/中标单位/中标方式/合同扫描件;输单=输单原因/竞品品牌/竞品中标单位/我方报价/竞品报价/失败分析。spec §2.3 亦将「开标 bid_result + 赢/输快照字段」列为本期范围(主表扩展列已建:bidAwardAmount/bidAwardMethod/bidOpenTime/bidOpenPlace/bidTime 等)。
  • 实际:标记只写 bid_result;快照列永无写入端点;开标页签赢单/输单后所有字段仍为「-」(screenshots/12-bidopen-win.png、18);bid-open DTO 快照字段全 null。
  • 证据:probe1 detail keys 含快照字段但值恒 null;ui-result U17。
  • 复测(票 17):通过(FIXED,按 16R 拍板口径)——标记赢单弹窗带快照四字段(开标时间/地点/中标方式/中标金额),提交后开标页签回显四值+中标时间(bid_time 服务端盖章),API bid-open 快照列已落值;输单路径免输单复盘字段直接提交进 stage6 结项(spin-out 维持)。中标单位/合同扫描件仍不采集(16R 拍板「可落库部分」范围)。证据 retest-p1-result.json D-03.1~3.6、screenshots/r17-d03-*.png。

P2

D-04 回退弹窗缺「回退原因类型 + 详细说明」(原型两字段均必填、原因类型按目标阶段字典联动)

  • 复现:stage≥2 进行中项目 → 「回退…」。
  • 实际:弹窗仅「回退到」一个下拉;动态留痕无回退原因。原型 A5-1-2-2 回退弹窗:*回退至阶段 + *详细说明 + 与目标阶段联动的原因类型字典(转回商机/冲突处理/方案设计/商务报价/招投标准备各有专属选项)。
  • 证据:screenshots/09-rollback-dialog.png;ui_audit U14。
  • 复测(票 17):维持记档(KEPT)——回退弹窗仍仅「回退到」单下拉,无原因类型/详细说明字段。证据 retest-p23-result.json、screenshots/r17-d04-rollback-dialog.png。

D-05 「回退…」按钮对普通销售可见(原型:仅管理员和销售总监可见可操作)

  • 复现:uid=99021003 打开他人进行中 stage≥2 项目 → 动作区可见「回退…」,点击弹窗正常打开,提交才被 68005 拒。
  • 期望:按钮按原型应不可见(README 自认「可见但服务端拒绝」,与原型「可见可操作仅限」不符)。
  • 证据:screenshots/25、26;ui-result U39、ui-result4 U40。
  • 复测(票 17):维持记档(KEPT)——普通销售打开他人 stage3 项目「回退…」按钮仍可见(服务端 68005 拒不变)。证据 screenshots/r17-d05-sales-sees-rollback.png。

D-06 demo 前端请求竞态:旧响应晚到覆盖新结果(scope/筛选快速切换、登录后首屏)

  • 复现:A 账号(列表 17 条)登录后立即点「我的项目」→ 短窗口内列表显示 manage 数据;快速连点 manage/mine 后终态可能与所选 scope 不一致。
  • 实际:loadBoard/loadList 无请求去重/AbortController/序号守卫,先发后至即覆盖。API 层 scope 过滤本身正确(sales mine total=0)。
  • 证据:ui_audit 首跑 U37 FAIL(mine 显示总监的「A5UI-输单」行);ui_audit2 R1/R2。
  • 复测(票 17):维持记档(KEPT)——index.html 仍无请求去重/AbortController/序号守卫(源码检查,竞态窗口未扩大)。

D-07 终态(已关闭/已结项)项目仍可新增跟进/附件

  • 复现:对已结项项目 POST /project/follow/add → code=0。
  • 期望:原型已关闭/结项页「所有页签只读,任何人不可编辑」。
  • 证据:probe2 B8。
  • 复测(票 17):维持记档(KEPT)——对已关闭项目 follow/add 仍 code=0,行为与记档一致,主流程未受影响。

D-08 列表列与原型列定义差异大(缺 8 列、3 列为新增、2 列改名)

  • 缺:NO./地区/销售经理/客户信息(名称-联系人-脱敏手机)/来源商机/品牌/中标时间/操作(查看)。
  • 新增:状态/报备/赢输(原型列表无,信息有价值);改名:当前节点→阶段、当前负责人→负责人。
  • 证据:screenshots/16、17;ui-result U26/U27。
  • 复测(票 17):维持记档(KEPT)——列表仍为 demo 9 列(缺原型 8 列、3 列新增、2 列改名口径未变)。

D-09 详情头部缺原型页首区字段

  • 缺:项目编号、甲方单位、客户联系人、来源商机名称(DTO 有 sourceOppId 但不展示)、项目类型;无阶段 stepper(原型横向阶段导航高亮当前节点)。
  • 证据:ui-result U07;screenshots/04、07。
  • 复测(票 17):维持记档(KEPT)——详情头部仍缺 项目编号/甲方单位/客户联系人/来源商机/项目类型,无阶段 stepper。

D-10 顶部统计卡缺失(原型+spec §4「顶部统计卡 7 阶段计数 + 冲突待处理入口」)

  • 实际:看板/列表顶部仅「冲突待处理」一张卡,无全部项目与各阶段计数卡(点击筛选联动亦无)。
  • 证据:ui-result U24;screenshots/14。
  • 复测(票 17):维持记档(KEPT)——看板顶部仍仅「冲突待处理」1 张统计卡,无 7 阶段计数卡。

D-11 看板卡字段不全

  • 缺原型卡的:最近跟进时间、中标时间、超期状态;负责人无部门前缀(原型「广东10部 陈亚」)。
  • 证据:ui-result U23;screenshots/14。
  • 复测(票 17):维持记档(KEPT)——看板卡仍缺 最近跟进时间/中标时间/超期状态,负责人无部门前缀。

D-12 写跟进弹窗字段缺失、跟进列表缺列

  • 弹窗缺:跟进方式字典必填(demo 自由文本选填)、客户名称/联系人/电话、跟进结果标签、计划下次跟进时间、附件上传。
  • 列表缺:跟进人、跟进人部门列。
  • 证据:ui-result U34[follow]、U35;screenshots/19。
  • 复测(票 17):维持记档(KEPT)——写跟进表单仍仅 内容/时间/方式(自由文本) 三项,列表仍缺 跟进人/部门列。

D-13 客户页签字段缺失、枚举未译名

  • 缺:客户联系人/联系电话/客户等级(原型关联客户页签);customerType 直接显示 ENTERPRISE
  • 证据:ui-result U36;screenshots/19 前后页。
  • 复测(票 17):维持记档(KEPT)——客户页签仍缺 联系人/电话/等级,customerType 仍显示原始枚举 ENTERPRISE。

D-14 分屏视图(左列右详)未实现

  • 原型 A5-1-1/A5-1-2-1 均有分屏视图(左侧卡片列表+右侧详情联动,页内高频操作);demo 仅 看板/列表/详情 三 tab,点行跳转式详情。
  • 证据:demo index.html nav.tabs。
  • 复测(票 17):维持记档(KEPT)——导航仍仅 看板/列表/详情 三 tab,分屏视图未实现。

D-15 关闭信息展示原始枚举

  • 头部「关闭」行显示 MANUAL 2026-09-11 …,未译为「主动关闭」等中文名(closeType 枚举无名称映射字段)。
  • 证据:ui-result U19。
  • 复测(票 17):维持记档(KEPT)——已关闭项目头部关闭行仍显示原始枚举「MANUAL」未译名。证据 screenshots/r17-d15-closed-raw-enum.png。

D-16 暂停/恢复、终止项目、编辑项目、移交负责人 均未实现

  • 原型右上角操作与对应弹窗(暂停原因/预计恢复时间/终止三选项/编辑表单/移交新负责人+原因)全缺;spec 端点清单亦未定义(📝),其中「移交负责人」在 spec §5 有移交 Port 间接依据 → 待复核是否本期范围。
  • 证据:demo 动作区全量按钮清单(U08/U11/U12)。
  • 复测(票 17):维持记档(KEPT)——详情动作区仍无 暂停/恢复/终止/编辑/移交 按钮(spec 口径未变)。

P3

D-17 建档表单形态与原型向导差异

  • 无 3 步向导(填写信息→冲突检测→创建;检测为 spin-out)、客户/方案卡为裸 id 手输(原型目录级联选择,spec 提及 CustomerCatalogPort 目录选)、无销售经理/项目类型字段、品牌/金额/地区必填性放宽(spec §5.1 只定客户+卡必填,不判缺陷,仅记录)。
  • 复测(票 17):维持记档(KEPT)——建档仍为单步弹窗、客户/方案卡裸 id 手输、无销售经理/项目类型字段。证据 screenshots/r17-d17-create-dialog.png。

D-18 同一方案卡可被多项目重复绑定(待复核)

  • 复现:同客户同卡连续建两个项目均成功(code=0)。卡为引用语义(DB:卡 owner_type=1 归商机,项目仅存 scheme_card_id,无抢占/数据损坏)。「一项目一客户一卡」是否要求卡与项目互斥,spec 未明 → 待产品确认。
  • 复测(票 17):维持记档(KEPT)——同卡两项目建项均 code=0,引用语义未变(待产品确认口径不变)。

D-19 A5-1-4 项目统计页整体缺失

  • demo 无统计入口;spec 端点清单亦未定义统计端点(按 spec 裁剪),建议后补。
  • 复测(票 17):维持记档(KEPT)——仍无 A5-1-4 统计入口。

D-20 board/list 数值类型不一致

  • conflictPendingCount、列 count、卡片/行 id 均为字符串,前端以宽松比较兼容;建议统一数值/保持一致。
  • 复测(票 17):维持记档(KEPT)——board/list 计数与 id 仍为字符串类型(前端宽松兼容未变)。

D-21 回退失败后弹窗保持打开

  • 68005 被拒后 dlgRollback 不自动关闭(open=true),仅 toast 反馈,阻塞页面点击需手动取消。
  • 证据:ui-result4 U40b。
  • 复测(票 17):维持记档(KEPT)——68005 被拒后回退弹窗仍保持打开(open=true),需手动取消。证据 screenshots/r17-d21-rollback-stays-open.png。

D-22 跟进时间默认值取浏览器 UTC 时间

  • README 已声明的演示性简化(toISOString),演示时可手改。非缺陷,记录备查。
  • 复测(票 17):维持记档(KEPT)——跟进时间默认值仍取浏览器 UTC(flTime == UTC now,非本地 UTC+8)。

D-23 错误信息泄露实现细节

  • followTime=垃圾时间 → 40001 message 返回 Spring 类型转换链(含 @io.swagger.v3.oas.annotations.media.Schema 等内部类名),建议转为业务文案。
  • 复测(票 17):维持记档(KEPT)——followTime=垃圾时间 仍 40001 并返回 Spring 类型转换链实现细节(类名泄露未收敛)。

D-24 推进/标记等写动作无二次确认

  • 原型各阶段推进均有确认弹窗;demo 仅标记赢输有 confirm,推进直接执行(误触即推进,可回退兜底)。
  • 复测(票 17):维持记档(KEPT)——推进仍无二次确认弹窗直接执行(误触可回退兜底不变)。

D-25 分页无页码/跳至;列表无排序

  • 原型页码+跳至+列排序;demo 仅上一页/下一页。
  • 复测(票 17):维持记档(KEPT)——分页仍仅 上一页/下一页 + 当前页码,无页码列表/跳至;列表无排序。

D-26 操作日志未拆分旧值/新值/敏感信息查看

  • 原型操作日志含操作对象/字段、旧值、新值、查看明细;demo 动态为事件级投影(spec 口径 crm-log 投影,记录为增强方向)。
  • 复测(票 17):维持记档(KEPT)——动态条目仍为事件级投影(action/actionName/fromStage/toStage/opDesc/opTime/operatorName/id),无旧值/新值拆分。

待复核汇总:D-01(badge 是否含驳回停留项目)、D-16(移交负责人是否本期范围)、D-18(卡互斥语义)。