Files
junhong_cmp_fiber/tests/hurl/reports/findings-package-resource-full-flow-2026-03-30.md
huang 2ef8b8a705
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
fix: 修复分页字段/角色DTO/套餐详情/批量分配Bug,新增C端测试登录接口和Hurl价格验证测试
- 修复B-2:27个分页DTO字段名统一(list→items, page_size→size,删除total_pages)
- 修复B-1:角色接口统一返回DTO(id小写,消除GORM大写字段名)
- 修复C-1:套餐详情接口(GET /packages/:id)补充代理佣金字段
- 修复C-2:批量分配已存在记录由500改为静默跳过
- 修复C-3:创建系列授权响应在事务提交后构建,packages数组不再为空
- 新增C端开发测试登录接口(POST /api/c/v1/auth/dev-login,仅logging.development=true时生效)
- 新增Hurl测试:card-price-verification-flow.hurl(导入卡→分配→C端价格验证)
- 新增测试Excel数据文件和dev.env测试变量
2026-03-31 09:54:08 +08:00

6.6 KiB
Raw Blame History

🔍 Hurl 测试发现报告

  • 测试文件flows/package-resource-full-flow.hurl
  • 生成时间2026-03-30
  • 最后更新2026-03-30修复 B-1/B-2/C-1/C-2/C-3 后更新)
  • 总请求数37
  • 通过36
  • 失败1C-4新发现 bug断言保留
  • 发现总计A类: 2, B类: 2, C类: 4

A 类(测试自身错误)— 已自动修正

A-1: 角色名冲突导致创建失败409

  • 位置:第 2 步 POST /api/admin/roles
  • 原因:角色名使用固定值 "hurl测试代理角色",重复运行时触发唯一约束冲突
  • 修正:角色名改为 "hurl测试角色-{{newUuid}}"

A-2: 店铺创建时初始账号用户名冲突409

  • 位置:第 5/7 步 POST /api/admin/shops
  • 原因init_username 使用 env 文件中的固定值,重复运行时触发 CodeUsernameExists (1013)
  • 修正:改为幂等策略 — HTTP * 接受创建结果 + 通过账号查询获取 shop_id
  • 备注env 文件中的 agent1_username / agent2_username 有唯一约束,首次运行后不可变更。如需重新创建,需先清理旧数据。

B 类(代码一致性问题)— 已修复

B-1: 角色接口返回原始 GORM 模型而非 DTO

  • 位置POST /api/admin/roles → 响应体
  • DTO 定义RoleResponsejson:"id"(小写)、json:"role_name"json:"created_at"
  • Handler 实际(修复前):直接返回 model.Role,字段为 "ID"(大写 GORM 默认)、"CreatedAt"
  • 影响:前端按 API 文档对接会取不到 id 字段
  • 决策:添加 model→DTO 转换保持一致性
  • 修复internal/service/role/service.goCreate/Get/Update 返回 *dto.RoleResponse,新增 toResponse() 辅助函数
  • 验证hurl 测试断言 $.data.id(小写)通过

B-2: 所有分页接口的实际格式与 DTO 定义不一致

  • 位置:所有列表接口(GET /packages, GET /shops, GET /shop-series-grants 等)
  • DTO 定义(修复前)json:"list" / json:"page_size" / json:"total_pages"
  • Handler 实际response.SuccessWithPagination() 返回 {items, total, page, size}
  • 影响:前端按 DTO 文档对接分页字段名不匹配
  • 决策DTO 定义改为匹配 SuccessWithPagination 格式
  • 修复27 个 DTO 文件 json tag 统一(list→items, page_size→size),删除 TotalPages 字段及 12 个 service/handler 中的计算逻辑
  • 验证hurl 测试断言 $.data.items / $.data.size 通过

C 类(接口行为 Bug

C-1: 套餐详情接口缺少 one_time_commission_amount 字段 — 已修复

  • 位置GET /api/admin/packages/:id(代理视角)
  • 预期PackageResponse DTO 定义了 one_time_commission_amount 字段
  • 实际(修复前):列表接口返回该字段,详情接口不返回
  • 决策Detail handler 增加佣金信息增强逻辑
  • 修复internal/service/package/service.goGet() 方法增加代理用户佣金信息增强,调用 fillCommissionInfoList 保持一致
  • 验证hurl 断言 $.data.one_time_commission_amount == 3000(一级代理)和 == 2000(二级代理)均通过

C-2: 批量分配对已有授权的店铺返回 500 — 已修复

  • 位置POST /api/admin/shop-package-batch-allocations
  • 预期:对已有分配记录应跳过或返回业务错误码,而非 500
  • 实际(修复前):唯一约束冲突触发 {code: 2001, msg: "内部服务器错误"}
  • 决策:添加已存在记录的前置检查
  • 修复internal/service/shop_package_batch_allocation/service.goBatchAllocate() 方法在创建前用 GetByShopAndPackageForSystem 检查记录是否已存在,已存在则跳过
  • 验证hurl 测试批量分配请求不再返回 500

C-3: 创建授权接口响应不包含 packages 数组 — 已修复

  • 位置POST /api/admin/shop-series-grants
  • 预期:创建响应应包含完整 packages 列表
  • 实际(修复前)packages 为空数组(事务内查询,新数据未提交不可见)
  • 根因buildGrantResponse 在事务内部调用,使用 s.db 而非事务 tx 查询 packages
  • 决策:创建授权后返回完整响应
  • 修复internal/service/shop_series_grant/service.goCreate() 方法将 buildGrantResponse 调用移到事务提交后
  • 验证hurl 测试 GET 详情确认 packages 存在

C-4: 创建授权不校验目标店铺是否存在 — 🐛 未修复(新发现)

  • 位置POST /api/admin/shop-series-grants

  • 预期shop_id 对应的店铺不存在时应返回 404

  • 实际shop_id=9999999(不存在的店铺)也能成功创建授权记录,返回 200

  • 影响

    • 产生无效的授权数据(关联到不存在的店铺)
    • 数据一致性风险:后续查询/操作该授权时可能出现不可预期的行为
  • 测试断言:保留 HTTP 404(预期失败,直到代码修复)

  • 建议Create() 方法中添加店铺存在性校验:

    _, err := s.shopStore.GetByID(ctx, req.ShopID)
    if err != nil {
        return nil, errors.New(errors.CodeNotFound, "目标店铺不存在")
    }
    
  • 决策: 修复吧


非 Bug 项(已确认的正常业务逻辑)

强充金额锁定机制

  • 位置PUT /api/admin/shop-series-grants/:id
  • 行为:当 force_recharge_locked=truegrant 级别无法修改 force_recharge_amount,金额由套餐系列配置控制
  • 判定:正常业务逻辑,非 Bug
  • 断言:已按实际行为编写(force_recharge_amount == 5000

有下级分配时不可修改成本价

  • 位置PUT /api/admin/shop-series-grants/:id/packages
  • 行为:存在下级分配记录时返回 {code: 1005, msg: "存在下级分配记录,请先回收后再修改成本价"}
  • 判定:正常业务保护机制,非 Bug
  • 断言改为只读验证GET 详情),不再尝试修改

修复历史

日期 操作 涉及文件
2026-03-30 初始报告生成
2026-03-30 修复 B-1 internal/service/role/service.go
2026-03-30 修复 B-2 27 个 DTO + 12 个 service/handler
2026-03-30 修复 C-1 internal/service/package/service.go
2026-03-30 修复 C-2 internal/service/shop_package_batch_allocation/service.go
2026-03-30 修复 C-3 internal/service/shop_series_grant/service.go
2026-03-30 新增 C-4 未修复,断言保留