Files
junhong_cmp_fiber/openspec/specs/enterprise-card-authorization/spec.md
huang c9fee7f2f6
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m42s
fix: 修复授权记录备注修改权限问题
- 实现备注权限检查逻辑(authorization_service.go)
- 添加备注权限验证存储层(authorization_store.go)
- 新增集成测试覆盖备注权限场景
- 归档 fix-authorization-remark-permission 变更
- 同步 enterprise-card-authorization spec 规范
2026-01-29 14:29:11 +08:00

7.7 KiB
Raw Blame History

MODIFIED Requirements

Requirement: 企业单卡授权管理

系统 SHALL 支持将 IoT 卡授权给企业使用,授权不转移所有权,仅授予使用权限。

授权规则

  • 代理只能授权自己的卡owner_type="agent" 且 owner_id=自己的 shop_id给自己的企业
  • 平台可以授权任意卡,但如果是代理的卡,只能授权给该代理的企业
  • 支持批量授权最多1000张卡
  • 已绑定设备的卡不能通过单卡授权接口授权MUST 使用设备授权接口
  • 只能授权状态为 "已分销(2)" 的卡

授权记录存储

  • 使用 enterprise_card_authorization 表记录授权关系
  • 通过单卡授权创建的记录 device_auth_id 为 NULL
  • 不使用 asset_allocation_record 表(该表用于分配,非授权)

权限控制

  • 企业用户只能查看被授权的卡
  • 授权后卡的 shop_id 保持不变(所有权不转移)
  • 回收授权后企业立即失去访问权限

Scenario: 代理授权自己的卡给自己的企业

  • WHEN 代理shop_id=10将自己的未绑定设备的卡授权给企业enterprise_id=5, owner_shop_id=10
  • THEN 系统创建授权记录device_auth_id=NULL企业可以查看和管理该卡

Scenario: 平台授权任意卡给企业

  • WHEN 平台管理员将未绑定设备的卡授权给企业
  • THEN 系统创建授权记录device_auth_id=NULL企业获得该卡的访问权限

Scenario: 代理无法授权其他代理的卡

  • WHEN 代理shop_id=10尝试授权其他代理的卡owner_id=20给企业
  • THEN 系统拒绝操作,返回权限错误

Scenario: 已绑定设备的卡不能通过单卡授权

  • WHEN 用户尝试通过单卡授权接口授权已绑定到设备的卡
  • THEN 系统拒绝操作,返回错误码 CodeCannotAuthorizeBoundCard提示"该卡已绑定设备,请使用设备授权功能"

Scenario: 只能授权已分销状态的卡

  • WHEN 用户尝试授权非"已分销"状态的卡
  • THEN 系统拒绝操作,提示只能授权"已分销"状态的卡

Requirement: 企业卡授权数据模型

系统 SHALL 定义 EnterpriseCardAuthorization 实体,记录企业卡授权关系。

实体字段

  • id: 主键BIGINT
  • enterprise_id: 被授权企业IDBIGINT关联 enterprises 表)
  • card_id: IoT卡IDBIGINT关联 iot_cards 表)
  • authorizer_id: 授权人账号IDBIGINT关联 accounts 表)
  • authorizer_type: 授权人类型SMALLINT2=平台用户 3=代理账号)
  • authorized_at: 授权时间TIMESTAMP
  • revoked_at: 回收时间TIMESTAMP可空
  • revoked_by: 回收人账号IDBIGINT可空
  • remark: 备注VARCHAR(500)
  • device_auth_id: 关联的设备授权IDBIGINT可空
    • NULL = 通过单卡授权创建
    • 有值 = 通过设备授权创建
  • created_at: 创建时间TIMESTAMP
  • updated_at: 更新时间TIMESTAMP

新增索引

  • idx_eca_device_auth ON tb_enterprise_card_authorization(device_auth_id)

Scenario: 创建单卡授权记录

  • WHEN 通过单卡授权接口授权卡给企业时
  • THEN 系统创建 EnterpriseCardAuthorization 记录device_auth_id 为 NULL

Scenario: 创建设备关联卡授权记录

  • WHEN 通过设备授权创建卡授权记录时
  • THEN 系统创建 EnterpriseCardAuthorization 记录device_auth_id 指向对应的设备授权ID

Scenario: 回收授权

  • WHEN 回收企业的卡授权时
  • THEN 系统更新对应记录的 revoked_at 和 revoked_by 字段,不删除记录(保留历史)

Requirement: 批量授权接口

系统 SHALL 提供批量授权接口,支持一次授权多张卡给企业。

接口设计

  • 路径:POST /api/admin/enterprises/:id/allocate-cards
  • 请求体:
    {
      "iccids": ["8986001234567890", "8986001234567891"],
      "remark": "批量授权"
    }
    
  • 响应:成功/失败的卡列表及原因

处理流程

  1. 验证每张卡的授权权限
  2. 检查卡状态是否为"已分销"
  3. 检查卡是否已绑定设备,绑定设备的卡直接拒绝并返回错误
  4. 检查是否已授权给该企业
  5. 创建授权记录device_auth_id = NULL
  6. 返回处理结果

移除功能

  • DeviceBundle 预检和确认流程(已移除)
  • confirm_device_bundles 参数(已移除)
  • AllocatedDevices 响应字段(已移除)

Scenario: 批量授权成功

  • WHEN 代理批量授权 5 张未绑定设备的卡给企业
  • THEN 系统创建 5 条授权记录device_auth_id 均为 NULL返回全部成功

Scenario: 批量授权遇到设备卡

  • WHEN 代理批量授权 5 张卡,其中 2 张已绑定设备
  • THEN 系统创建 3 条授权记录,返回 3 张成功、2 张失败,失败原因为"该卡已绑定设备,请使用设备授权功能"

Scenario: 批量授权部分成功

  • WHEN 代理批量授权 5 张卡,其中 1 张已绑定设备、1 张非已分销状态
  • THEN 系统创建 3 条授权记录,返回 3 张成功、2 张失败及各自失败原因

ADDED Requirements

Requirement: 授权记录备注修改权限

系统 SHALL 对授权记录备注修改操作实施严格的权限控制,确保只有有权限的用户才能修改授权记录的备注信息。

权限规则

  • 超级管理员/平台用户:可以修改任意授权记录的备注
  • 代理账号仅可修改自己创建的授权记录的备注authorized_by 等于自己的账号 ID
  • 企业账号:禁止修改授权记录备注(即使是授权给自己企业的记录)

实施方式

  • Service 层 MUST 在 UpdateRecordRemark 方法中校验用户权限和创建者匹配
  • Store 层 MUST 在更新语句中增加 authorized_by 约束条件(对代理用户)
  • Handler 层 MUST 将权限失败场景返回统一错误码和中文错误消息

错误处理

  • 代理尝试修改他人创建的记录:返回错误码 CodePermissionDenied1003消息"无权修改该授权记录的备注"
  • 企业用户尝试修改:返回错误码 CodePermissionDenied1003消息"企业用户无权修改授权记录备注"
  • 记录不存在或不在可见范围:返回错误码 CodeRecordNotFound2001消息"授权记录不存在"

Scenario: 平台用户修改任意授权记录备注

  • WHEN 平台用户调用备注修改接口,指定任意授权记录 ID 和新备注内容
  • THEN 系统成功更新该授权记录的 remark 字段,返回成功响应

Scenario: 代理修改自己创建的授权记录备注

  • WHEN 代理账号account_id=100调用备注修改接口修改自己创建的授权记录authorized_by=100的备注
  • THEN 系统成功更新该授权记录的 remark 字段,返回成功响应

Scenario: 代理尝试修改他人创建的授权记录备注

  • WHEN 代理账号account_id=100调用备注修改接口尝试修改其他代理创建的授权记录authorized_by=200的备注
  • THEN 系统拒绝操作,返回错误码 1003,错误消息"无权修改该授权记录的备注",不执行任何更新

Scenario: 企业用户尝试修改授权记录备注

  • WHEN 企业账号调用备注修改接口,尝试修改授权给自己企业的授权记录的备注
  • THEN 系统拒绝操作,返回错误码 1003,错误消息"企业用户无权修改授权记录备注",不执行任何更新

Scenario: 代理修改不存在或不可见的授权记录备注

  • WHEN 代理账号调用备注修改接口,指定的授权记录 ID 不存在或不在其数据权限范围内
  • THEN 系统返回错误码 2001,错误消息"授权记录不存在",不执行任何更新