Files
junhong_cmp_fiber/openspec/specs/enterprise-card-authorization/spec.md
huang ce0783f96e
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m30s
feat: 实现设备管理和设备导入功能,修复测试问题
主要变更:
- 实现设备管理模块(创建、查询、列表、更新状态、删除)
- 实现设备批量导入功能(CSV 解析、ICCID 绑定、异步任务处理)
- 添加设备-SIM 卡绑定约束(部分唯一索引防止并发问题)
- 修复 fee_rate 数据库字段类型(numeric -> bigint)
- 修复测试数据隔离问题(基于增量断言)
- 修复集成测试中间件顺序问题
- 清理无用测试文件(PersonalCustomer、Email 相关)
- 归档 enterprise-card-authorization 变更
2026-01-26 18:05:12 +08:00

5.9 KiB
Raw Blame History

enterprise-card-authorization Specification

Purpose

TBD - created by archiving change enterprise-card-authorization. Update Purpose after archive.

Requirements

Requirement: 企业单卡授权管理

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

授权规则

  • 代理只能授权自己的卡owner_type="agent" 且 owner_id=自己的 shop_id给自己的企业
  • 平台可以授权任意卡,但如果是代理的卡,只能授权给该代理的企业
  • 只能授权单张卡,不支持批量选择
  • 已绑定设备的卡不能授权(设备卡应整体授权,而非单卡)
  • 只能授权状态为 "已分销(2)" 的卡

授权记录存储

  • 使用 enterprise_card_authorization 表记录授权关系
  • 不使用 asset_allocation_record 表(该表用于分配,非授权)

权限控制

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

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

  • WHEN 代理shop_id=10将自己的卡owner_type="agent", owner_id=10授权给企业enterprise_id=5, owner_shop_id=10
  • THEN 系统创建授权记录,企业可以查看和管理该卡,卡的 shop_id 保持为 10

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

  • WHEN 平台管理员将卡授权给企业
  • THEN 系统创建授权记录,不检查卡的所有者,企业获得该卡的访问权限

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

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

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

  • WHEN 用户尝试授权已绑定到设备的卡
  • THEN 系统拒绝操作,提示该卡已绑定设备,请使用设备授权功能

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

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

Requirement: 企业卡授权数据模型

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

实体字段

  • id: 主键BIGINT
  • enterprise_id: 被授权企业IDBIGINT关联 enterprises 表)
  • card_id: IoT卡IDBIGINT关联 iot_cards 表)
  • authorizer_id: 授权人账号IDBIGINT关联 accounts 表)
  • authorizer_type: 授权人类型VARCHAR(20)"platform" | "agent"
  • authorized_at: 授权时间TIMESTAMP
  • revoked_at: 回收时间TIMESTAMP可空
  • revoked_by: 回收人账号IDBIGINT可空
  • created_at: 创建时间TIMESTAMP
  • updated_at: 更新时间TIMESTAMP

Scenario: 创建授权记录

  • WHEN 授权卡给企业时
  • THEN 系统创建 EnterpriseCardAuthorization 记录authorized_at 设置为当前时间revoked_at 为 NULL

Scenario: 回收授权

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

Requirement: 批量授权接口

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

接口设计

  • 路径:POST /api/admin/enterprises/{enterpriseId}/authorize-cards
  • 请求体包含卡ID列表
  • 响应:成功/失败的卡列表及原因

处理流程

  1. 验证每张卡的授权权限
  2. 检查卡状态是否为"已分销"
  3. 检查卡是否已绑定设备
  4. 检查是否已授权给其他企业
  5. 创建授权记录
  6. 返回处理结果

Scenario: 批量授权成功

  • WHEN 代理批量授权 5 张符合条件的卡给企业
  • THEN 系统创建 5 条授权记录,返回全部成功

Scenario: 批量授权部分成功

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

Requirement: 企业查看授权卡信息

系统 SHALL 允许企业查看被授权卡的特定信息,同时隐藏商业敏感信息。

可见信息

  • 卡基本信息ICCID、卡类型、运营商、批次号
  • 使用信息:激活状态、实名状态、网络状态、流量使用
  • 套餐信息:当前套餐、有效期
  • 授权信息:授权人、授权时间

不可见信息

  • 成本价cost_price
  • 分销价distribute_price
  • 供应商supplier
  • 所有者信息owner_type、owner_id

Scenario: 企业查看授权卡详情

  • WHEN 企业用户查看被授权的卡详情
  • THEN 系统返回卡信息,但 cost_price、distribute_price、supplier 字段为空或不返回

Scenario: 企业无法查看未授权的卡

  • WHEN 企业用户尝试查看未被授权的卡
  • THEN 系统返回 404 错误,提示卡不存在或无权限查看

Requirement: 授权回收功能

系统 SHALL 支持回收企业的卡授权,回收后企业立即失去访问权限。

回收规则

  • 代理可以回收自己授权的卡
  • 平台可以回收任何授权
  • 回收操作不可逆(需重新授权才能恢复访问)

回收效果

  • 更新 revoked_at 和 revoked_by 字段
  • 企业立即无法查看该卡
  • 保留授权历史记录

Scenario: 代理回收自己的授权

  • WHEN 代理回收之前授权给企业的卡
  • THEN 系统更新授权记录的回收字段,企业立即无法访问该卡

Scenario: 平台回收任意授权

  • WHEN 平台管理员回收任意企业的卡授权
  • THEN 系统更新授权记录,不检查原授权人,企业失去访问权限

Scenario: 回收后企业无法访问

  • WHEN 授权被回收后,企业用户尝试查看该卡
  • THEN 系统返回 404 错误,如同该卡从未被授权过