## Context 当前后台接口中,设备导入任务相关接口在 Handler 层做了“仅平台用户/超级管理员可访问”的用户类型校验(基于 `middleware.GetUserTypeFromContext` + `constants.UserTypeSuperAdmin/UserTypePlatform`)。 IoT 卡导入任务相关接口(提交导入、任务列表、任务详情)未做同等校验,导致权限边界与设备导入不一致。 本变更目标是将 IoT 卡导入任务相关接口的访问权限收敛为与设备导入一致:仅超级管理员与平台用户可访问。 ## Goals / Non-Goals **Goals:** - 对以下 3 个接口增加用户类型校验:仅允许超级管理员与平台用户访问。 - 返回行为与现有模式一致:非允许用户类型直接返回 403(`errors.CodeForbidden`),错误消息使用中文。 - OpenAPI 路由描述与实际权限一致。 - 补齐/新增集成测试,覆盖非平台用户访问应被拒绝。 **Non-Goals:** - 不调整导入任务的数据模型与存储逻辑。 - 不引入新的 RBAC 权限点或权限表配置(保持“用户类型硬校验”的现有风格)。 - 不改动其他 IoT 卡管理接口的权限策略。 ## Decisions 1) **在 Handler 层做用户类型校验(与设备导入对齐)** - 方案:在 `internal/handler/admin/iot_card_import.go` 的 `Import` / `List` / `GetByID` 入口处增加与 `internal/handler/admin/device_import.go` 同风格的校验。 - 理由: - 与现有“设备导入”实现一致,减少认知负担。 - 校验发生在参数解析与业务调用前,能最早拒绝无权限请求。 - 备选方案: - 路由层中间件:更集中,但需要在路由注册处引入新中间件组合,且当前设备导入并未采用该方式。 - Service 层校验:更“业务化”,但会改变当前导入模块的职责边界(设备导入限制目前在 Handler 层)。 2) **错误码与错误消息遵循现有约定** - 方案:使用 `errors.New(errors.CodeForbidden, "仅平台用户可...")` 风格,保持与设备导入一致。 - 理由:该模块已有同类错误消息,避免引入新的错误码或文案风格。 3) **同步更新路由描述(OpenAPI)** - 方案:在 `internal/routes/iot_card.go` 对相关接口补充 `Description: "仅平台用户可操作。"`(与设备导入相同语义)。 - 理由:避免文档与实际行为不一致,减少前后端联调成本。 ## Risks / Trade-offs - **[风险] 规格与实现不一致** → **缓解**:在本变更的 specs(delta spec)中明确将权限收敛为平台用户/超管,并在实现阶段对齐。 - **[风险] 测试缺口导致回归** → **缓解**:新增集成测试覆盖非平台用户访问 403,并尽量复用现有测试基建(集成测试 env)。 ## Migration Plan - 该变更为权限收敛,无数据迁移。 - 发布后影响:非平台用户/超管将无法调用 IoT 卡导入与导入任务查询接口。 - 回滚策略:如业务需要恢复原可见性,可回滚本变更提交(或通过后续变更重新放开)。 ## Open Questions - 是否需要将错误消息文案统一为同一句(如“仅平台用户可操作”),还是分别保留更具体的文案(导入/列表/详情)?(实现阶段可按现有 device_import 文案对齐)