Files
junhong_cmp_fiber/openspec/changes/fix-device-sim-binding-issues/tasks.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

77 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 实现任务清单
## 1. 数据库迁移
- [x] 1.1 创建迁移文件 `migrations/000019_fix_device_sim_binding_constraints.up.sql`
- 使用 `CREATE INDEX CONCURRENTLY` 添加 `idx_active_device_slot` 部分唯一索引
-`tb_device_import_task` 表添加 `warning_count``warning_items` 字段
- [x] 1.2 创建回滚文件 `migrations/000019_fix_device_sim_binding_constraints.down.sql`
- [x] 1.3 执行迁移并验证索引创建成功
## 2. 模型层修改
- [x] 2.1 创建 `internal/model/device_sim_binding.go` 文件
-`internal/model/package.go` 移动 `DeviceSimBinding` 结构体和 `TableName()` 方法
- 确保所有 import 和 tag 正确
- [x] 2.2 从 `internal/model/package.go` 中删除 `DeviceSimBinding` 相关代码
- [x] 2.3 修改 `internal/model/device_import_task.go`
- 添加 `WarningCount int` 字段
- 添加 `WarningItems ImportResultItems` 字段JSONB 类型)
- [x] 2.4 运行 `go build ./...` 确保编译通过
## 3. Store 层修改
- [x] 3.1 修改 `internal/store/postgres/device_sim_binding_store.go`
- 添加 `isUniqueViolation(err error) bool` 辅助函数
- 修改 `Create` 方法,检测唯一约束冲突并返回友好的业务错误
- 根据违反的约束名(`idx_active_device_slot``idx_device_sim_bindings_active_card`)返回不同的错误信息
- [x] 3.2 添加 `github.com/jackc/pgx/v5/pgconn` 依赖(如果尚未存在)
## 4. Service 层修改
- [x] 4.1 修改 `internal/service/device/binding.go`
- `BindCard` 方法已有应用层检查,无需修改
- Store 层的错误处理已足够Service 层只需透传错误
## 5. 设备导入任务修改
- [x] 5.1 修改 `internal/task/device_import.go` 中的 `deviceImportResult` 结构体
- 添加 `warningCount int` 字段
- 添加 `warningItems model.ImportResultItems` 字段
- [x] 5.2 修改 `processBatch` 函数添加归属权校验
- 在 ICCID 验证循环中添加 `card.ShopID != nil` 检查
- 如果卡已分配给店铺,记录原因 `ICCID+"已分配给店铺,不能绑定到平台库存设备"`
- [x] 5.3 修改 `processBatch` 函数添加部分成功处理逻辑
-`len(validCardIDs) > 0 && len(cardIssues) > 0` 时,设备创建后记录到 `warningItems`
- 增加 `warningCount`
- [x] 5.4 修改 `HandleDeviceImport` 函数
- 更新调用 `h.importTaskStore.UpdateResult` 传入 `warning_count``warning_items`
- [x] 5.5 修改 `internal/store/postgres/device_import_task_store.go`
- 更新 `UpdateResult` 方法签名,添加 `warningCount``warningItems` 参数
- 更新 SQL 语句保存新字段
## 6. 测试
- [x] 6.1 编写 `internal/store/postgres/device_sim_binding_store_test.go` 并发绑定测试
- 测试同一张卡并发绑定到不同设备
- 测试同一设备插槽并发绑定不同卡
- 验证返回正确的错误信息
- [x] 6.2 编写 `internal/task/device_import_test.go` 归属权校验测试
- 测试绑定平台库存卡成功
- 测试绑定已分配店铺的卡失败
- 测试部分成功场景,验证 warning_items 记录正确
- [x] 6.3 运行现有测试确保无回归 `go test ./...`
-tests/unit 和 tests/integration 中存在既有问题(与本次实现无关)
- 本次实现相关测试全部通过internal/store/postgres、internal/task
## 7. 验证与文档
- [x] 7.1 使用 PostgreSQL MCP 验证数据库约束生效
- 手动测试插入重复 (device_id, slot_position, bind_status=1) 记录被拒绝
- 手动测试插入重复 (iot_card_id, bind_status=1) 记录被拒绝
- [x] 7.2 验证 API 响应结构
- 确认设备导入任务结果包含 `warning_count``warning_items` 字段
- 更新了 DTO 和 Service 层映射
- [x] 7.3 更新相关文档(如有必要)
- 本次实现无需额外文档更新