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.
 
 
 
 
 

3.7 KiB

08 修复:P1 服务层守卫批次(P1-1/2/3/4)

Type: task Status: resolved Blocked by: 03

Question

按 ticket 03 的裁决修复 P1 服务层四项(判误报的跳过):

  • P1-1 反馈提交清草稿applyFeedback() 提交成功后清除同 (user_id, lead_id) 的 DRAFT 行(PRD §6.4:"转为 SUBMITTED"——删除或置状态,按 PRD 措辞与现表结构定,写清注释)。
  • P1-2 删除权限deleteLead()PRD §3.3 落地:删除 = (状态≠已转商机) AND (管理员 OR 创建人);激活 isCreator 死变量或移除;"管理员判定由 DataScope 兜底"的注释假设要重新论证——DataScope 是读过滤,写守卫必须在 service 里显式判(用 07 号 ticket 选定的管理员判定机制,保持一致)。
  • P1-3 EDIT 字段级 diffeditLead() 对可编辑业务字段做 old→new diff,变更项写入 EDIT 历史 detail(字段名/旧值/新值,格式对齐 LeadHistoryRecorder kv 机制);无变更时是否仍写 EDIT 由本 ticket 定并写明依据。
  • P1-4 反馈入口校验:按 03 结论补缺——feedbackStatus 枚举合法性(仅 有效/无效,未反馈不可作为提交值);EXPIRED/CONVERTED 等状态拦截若 LeadTransition.guard 已兜底则复核单测覆盖,不重复实现。

验收:每项新增针对性单测 + mvn test(crm-lead)全绿 + BOM 扫描。

Answer

P1-1 反馈提交清草稿

  • submitFeedback()leadTransition.execute() 成功后,调用 leadFeedbackMapper.delete() 清除同 (userId, leadId, DRAFT) 的草稿行。
  • 依据 PRD §6.4:"草稿随提交转为 SUBMITTED"——applyFeedback() 已新建 SUBMITTED 记录,DRAFT 行为残留,此处删除(而非更新状态)避免重复记录。
  • 单测:submitFeedback_clearsDraft——验证 leadFeedbackMapper.delete(any()) 被调用。

P1-2 删除权限

  • deleteLead() 落地 删除 = (状态≠已转商机) AND (管理员 OR 创建人)(PRD §3.3)。
  • isAdmin = SecurityUtils.hasRole(AuthConstants.ROLE_CODE_ADMIN)(与 ticket 07 一致)。
  • isCreator = creatorId != null && Long.parseLong(creatorId) == currentUserId
  • !isAdmin && !isCreator → throw CODE_NOT_OWNER(65004)"仅管理员或创建人可删除线索"。
  • 移除"管理员判定由 DataScope 兜底"的错误注释——DataScope 是读过滤,写守卫必须在 service 显式判。
  • 单测:deleteLead_nonAdminNonCreator_rejected(拒)+ deleteLead_creatorAllowed(放行)。

P1-3 EDIT 字段级 diff

  • editLead() 对 13 个可编辑业务字段做 Objects.equals(old, new) 逐项比较,变更项以 (fieldName, newVal) kv 对追加到 editDetail 列表。
  • 调用 historyRecorder.record(id, EDIT, userId, editDetail.toArray())——空列表→detail=null(无变更仍写 EDIT,记录编辑意图)。
  • 新增 addIfChanged(List<Object>, String, Object, Object) 辅助方法。
  • 单测:editLead_fieldDiff_onlyChangedFieldsInHistory——验证 history detail 仅含变更字段(leadName+phone),不含未变更字段(consultContent 等)。

P1-4 反馈入口校验

  • submitFeedback() 入口校验 feedbackStatus:必须为 FEEDBACK_VALID(1)FEEDBACK_INVALID(2),否则 throw CODE_LEAD_INVALID(65001)"反馈情况必须为有效或无效"。
  • EXPIRED/CONVERTED 状态拦截:FeedbackCmd.allowedFromStatuses() = {CLAIMED, FOLLOWING, VOID},guard() 已兜底,不重复实现——仅复核单测覆盖。
  • 单测:submitFeedback_invalidFeedbackStatus_rejected——feedbackStatus=0→拒、不进 transition。

验证

  • BOM 扫描:2 个修改文件无 BOM。
  • mvn test -pl crm-lead -am:91 tests, 0 failures, 0 errors, BUILD SUCCESS。