Files
junhong_cmp_fiber/openspec/changes/archive/2026-08-18-agent-refund-shop-visibility/design.md
break c8052df8eb
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m30s
补充退款列表应当让本店铺的人看见
2026-08-18 11:44:30 +08:00

2.0 KiB

Context

退款列表和详情当前共用按创建人过滤的数据访问方法。详情读取还被退款审批、退回和重新提交等写操作用于加载退款申请,因此直接把该方法改为按店铺过滤,会扩大既有写操作的对象范围。

Goals / Non-Goals

Goals:

  • 让代理仅在退款列表和详情读取时按当前登录账号的直接所属店铺查看退款。
  • 保持下级代理店铺不可见,并保持退款写操作的既有创建人权限边界。

Non-Goals:

  • 不改变平台和超级管理员的可见范围。
  • 不改变代理创建退款、审批、退回、拒绝或重新提交的授权规则。
  • 不补齐历史退款中缺失的店铺归属数据。

Decisions

  • 读取路径以认证上下文中的直接 ShopID 与退款申请的 ShopID 精确匹配,不使用包含下级店铺的 SubordinateShopIDs。这是账号所属店铺的稳定事实,且能直接满足排除下级代理的要求。
  • 为列表与详情读取使用店铺可见范围;写操作继续通过创建人范围加载退款申请。读取与写入分别显式选择权限范围,避免共享查询方法导致查看权限扩展为操作权限。
  • 代理上下文没有有效 ShopID 时施加恒假条件,不回退至未过滤查询。备选方案是返回参数错误;选择空结果/不存在以与现有未授权对象查询行为一致,并避免暴露数据存在性。

Risks / Trade-offs

  • [历史退款的 shop_id 为空] → 该类记录不会对代理可见,仍由平台和超级管理员查询;不在本次改动中推断或回填归属。
  • [读取与写入使用不同权限方法] → 在方法名称和调用处明确区分读取可见性与操作授权,并在实现后逐一检查退款服务中全部按 ID 加载的调用者。

Migration Plan

  1. 发布应用代码;无需数据迁移。
  2. 使用同店铺不同账号、下级店铺和未绑定店铺账号分别验证列表及详情。
  3. 如需回滚,恢复代理退款读取的创建人过滤;数据库数据不受影响。