diff --git a/openspec/changes/asset-realname-policy/tasks.md b/openspec/changes/asset-realname-policy/tasks.md index a767660..61d4285 100644 --- a/openspec/changes/asset-realname-policy/tasks.md +++ b/openspec/changes/asset-realname-policy/tasks.md @@ -1,81 +1,81 @@ ## 1. 基础设施(常量 + 迁移 + Model) -- [ ] 1.1 在 `pkg/constants/` 中定义 `RealnamePolicy` 枚举常量(none / before_order / after_order)及新增错误码 `CodeRealnameNotAvailable`(`pkg/errors/codes.go`) -- [ ] 1.2 创建数据库迁移文件,为 `tb_iot_card` 新增 `realname_policy VARCHAR(20) NOT NULL DEFAULT 'none'` -- [ ] 1.3 创建数据库迁移文件,为 `tb_device` 新增 `realname_policy VARCHAR(20) NOT NULL DEFAULT 'none'` -- [ ] 1.4 创建数据库迁移文件,为 `tb_iot_card_import_task` 新增 `realname_policy VARCHAR(20) NOT NULL DEFAULT 'none'` -- [ ] 1.5 创建数据库迁移文件,为 `tb_device_import_task` 新增 `realname_policy VARCHAR(20) NOT NULL DEFAULT 'none'` -- [ ] 1.6 在 `internal/model/iot_card.go` 的 `IotCard` 结构体新增 `RealnamePolicy` 字段(含 gorm 标签和中文注释) -- [ ] 1.7 在 `internal/model/device.go` 的 `Device` 结构体新增 `RealnamePolicy` 字段(含 gorm 标签和中文注释) -- [ ] 1.8 在 `internal/model/iot_card_import_task.go` 的 `IotCardImportTask` 结构体新增 `RealnamePolicy` 字段 -- [ ] 1.9 在 `internal/model/device_import_task.go` 的 `DeviceImportTask` 结构体新增 `RealnamePolicy` 字段 -- [ ] 1.10 执行迁移并验证四张表字段已正确添加 +- [x] 1.1 在 `pkg/constants/` 中定义 `RealnamePolicy` 枚举常量(none / before_order / after_order)及新增错误码 `CodeRealnameNotAvailable`(`pkg/errors/codes.go`) +- [x] 1.2 创建数据库迁移文件,为 `tb_iot_card` 新增 `realname_policy VARCHAR(20) NOT NULL DEFAULT 'none'` +- [x] 1.3 创建数据库迁移文件,为 `tb_device` 新增 `realname_policy VARCHAR(20) NOT NULL DEFAULT 'none'` +- [x] 1.4 创建数据库迁移文件,为 `tb_iot_card_import_task` 新增 `realname_policy VARCHAR(20) NOT NULL DEFAULT 'none'` +- [x] 1.5 创建数据库迁移文件,为 `tb_device_import_task` 新增 `realname_policy VARCHAR(20) NOT NULL DEFAULT 'none'` +- [x] 1.6 在 `internal/model/iot_card.go` 的 `IotCard` 结构体新增 `RealnamePolicy` 字段(含 gorm 标签和中文注释) +- [x] 1.7 在 `internal/model/device.go` 的 `Device` 结构体新增 `RealnamePolicy` 字段(含 gorm 标签和中文注释) +- [x] 1.8 在 `internal/model/iot_card_import_task.go` 的 `IotCardImportTask` 结构体新增 `RealnamePolicy` 字段 +- [x] 1.9 在 `internal/model/device_import_task.go` 的 `DeviceImportTask` 结构体新增 `RealnamePolicy` 字段 +- [x] 1.10 执行迁移并验证四张表字段已正确添加 ## 2. 公共策略判断逻辑(Service 层) -- [ ] 2.1 在合适的公共 Service 或工具包中实现 `GetEffectiveRealnamePolicy(card *model.IotCard, device *model.Device) string`:设备卡取 device.RealnamePolicy,单卡取 card.RealnamePolicy -- [ ] 2.2 实现检查 `after_order` 生效条件的方法:查询该资产当前 generation 内是否存在有效充值(status=2)或已支付订单(payment_status=2),返回 bool +- [x] 2.1 在合适的公共 Service 或工具包中实现 `GetEffectiveRealnamePolicy(card *model.IotCard, device *model.Device) string`:设备卡取 device.RealnamePolicy,单卡取 card.RealnamePolicy +- [x] 2.2 实现检查 `after_order` 生效条件的方法:查询该资产当前 generation 内是否存在有效充值(status=2)或已支付订单(payment_status=2),返回 bool ## 3. IoT 卡导入模块改造 -- [ ] 3.1 在 `ImportIotCardRequest` DTO 中新增 `realname_policy` 字段(含 validate、description 标签) -- [ ] 3.2 更新 `iot_card_import` Service 的 CreateImportTask 方法:将请求中的 `realname_policy` 保存到 `IotCardImportTask.realname_policy` -- [ ] 3.3 更新 IoT 卡导入 Worker 处理逻辑:创建 `IotCard` 记录时从任务的 `realname_policy` 写入卡的 `realname_policy` -- [ ] 3.4 在 `ImportTaskResponse`(IoT 卡)中新增 `realname_policy` 字段(含 description 标签) +- [x] 3.1 在 `ImportIotCardRequest` DTO 中新增 `realname_policy` 字段(含 validate、description 标签) +- [x] 3.2 更新 `iot_card_import` Service 的 CreateImportTask 方法:将请求中的 `realname_policy` 保存到 `IotCardImportTask.realname_policy` +- [x] 3.3 更新 IoT 卡导入 Worker 处理逻辑:创建 `IotCard` 记录时从任务的 `realname_policy` 写入卡的 `realname_policy` +- [x] 3.4 在 `ImportTaskResponse`(IoT 卡)中新增 `realname_policy` 字段(含 description 标签) ## 4. 设备导入模块改造 -- [ ] 4.1 在 `ImportDeviceRequest` DTO 中新增 `realname_policy` 字段(含 validate、description 标签) -- [ ] 4.2 更新 `device_import` Service 的 CreateImportTask 方法:将请求中的 `realname_policy` 保存到 `DeviceImportTask.realname_policy` -- [ ] 4.3 更新设备导入 Worker 处理逻辑:创建 `Device` 记录时从任务的 `realname_policy` 写入设备的 `realname_policy` -- [ ] 4.4 在 `DeviceImportTaskResponse` 中新增 `realname_policy` 字段(含 description 标签) +- [x] 4.1 在 `ImportDeviceRequest` DTO 中新增 `realname_policy` 字段(含 validate、description 标签) +- [x] 4.2 更新 `device_import` Service 的 CreateImportTask 方法:将请求中的 `realname_policy` 保存到 `DeviceImportTask.realname_policy` +- [x] 4.3 更新设备导入 Worker 处理逻辑:创建 `Device` 记录时从任务的 `realname_policy` 写入设备的 `realname_policy` +- [x] 4.4 在 `DeviceImportTaskResponse` 中新增 `realname_policy` 字段(含 description 标签) ## 5. 后台管理查询接口 DTO 添加字段 -- [ ] 5.1 在 `StandaloneIotCardResponse`(`iot_card_dto.go`)中新增 `realname_policy` 字段,更新 Store/Service 中的 DTO 填充逻辑 -- [ ] 5.2 在 `DeviceResponse`(`device_dto.go`)中新增 `realname_policy` 字段,更新填充逻辑 -- [ ] 5.3 在 `AssetResolveResponse`(`asset_dto.go`)中新增 `realname_policy` 字段,更新 `asset` Service 的 Resolve 方法填充逻辑 -- [ ] 5.4 在 `AssetRealtimeStatusResponse`(`asset_dto.go`)中新增 `realname_policy` 字段,更新填充逻辑 -- [ ] 5.5 在 `DeviceCardBindingResponse`(`device_dto.go`)中新增 `realname_policy` 字段,更新填充逻辑 -- [ ] 5.6 在 `BoundCardInfo`(`asset_dto.go`,后台管理端公共子结构)中新增 `realname_policy` 字段,更新填充逻辑 +- [x] 5.1 在 `StandaloneIotCardResponse`(`iot_card_dto.go`)中新增 `realname_policy` 字段,更新 Store/Service 中的 DTO 填充逻辑 +- [x] 5.2 在 `DeviceResponse`(`device_dto.go`)中新增 `realname_policy` 字段,更新填充逻辑 +- [x] 5.3 在 `AssetResolveResponse`(`asset_dto.go`)中新增 `realname_policy` 字段,更新 `asset` Service 的 Resolve 方法填充逻辑 +- [x] 5.4 在 `AssetRealtimeStatusResponse`(`asset_dto.go`)中新增 `realname_policy` 字段,更新填充逻辑 +- [x] 5.5 在 `DeviceCardBindingResponse`(`device_dto.go`)中新增 `realname_policy` 字段,更新填充逻辑 +- [x] 5.6 在 `BoundCardInfo`(`asset_dto.go`,后台管理端公共子结构)中新增 `realname_policy` 字段,更新填充逻辑 ## 6. C 端查询接口 DTO 添加字段 -- [ ] 6.1 在 `AssetInfoResponse`(`client_asset_dto.go`)中新增 `realname_policy` 字段,更新 `client_asset` Service 的填充逻辑 -- [ ] 6.2 在 C 端 `BoundCardInfo`(`client_asset_dto.go` 内嵌子结构)中新增 `realname_policy` 字段,更新填充逻辑 -- [ ] 6.3 在 `DeviceCardItem`(`client_realname_device_dto.go`)中新增 `realname_policy` 字段,更新 `GetDeviceCards` 接口填充逻辑 +- [x] 6.1 在 `AssetInfoResponse`(`client_asset_dto.go`)中新增 `realname_policy` 字段,更新 `client_asset` Service 的填充逻辑 +- [x] 6.2 在 C 端 `BoundCardInfo`(`client_asset_dto.go` 内嵌子结构)中新增 `realname_policy` 字段,更新填充逻辑 +- [x] 6.3 在 `DeviceCardItem`(`client_realname_device_dto.go`)中新增 `realname_policy` 字段,更新 `GetDeviceCards` 接口填充逻辑 ## 7. C 端充值接口拦截(C3/C4) -- [ ] 7.1 在 `client_wallet` Service 的充值预检方法(C3 对应逻辑)中,在归属校验后插入实名策略检查:before_order + 未实名 → 返回 CodeNeedRealname -- [ ] 7.2 在 `client_wallet` Service 的充值下单方法(C4 对应逻辑)中,在归属校验后、OpenID 查询前插入实名策略检查:before_order + 未实名 → 返回 CodeNeedRealname +- [x] 7.1 在 `client_wallet` Service 的充值预检方法(C3 对应逻辑)中,在归属校验后插入实名策略检查:before_order + 未实名 → 返回 CodeNeedRealname +- [x] 7.2 在 `client_wallet` Service 的充值下单方法(C4 对应逻辑)中,在归属校验后、OpenID 查询前插入实名策略检查:before_order + 未实名 → 返回 CodeNeedRealname ## 8. C 端购买套餐/订单接口拦截(D1/D4) -- [ ] 8.1 删除 `client_order` Service 中的 `REALNAME-03` 注释代码 -- [ ] 8.2 在 `client_order` Service 的 CreateOrder 方法(D1)中,套餐校验之后、OpenID 查询之前插入实名策略检查 -- [ ] 8.3 在 `client_order` Service 的 PayOrder 方法(D4)中,在执行支付前插入实名策略检查 +- [x] 8.1 删除 `client_order` Service 中的 `REALNAME-03` 注释代码 +- [x] 8.2 在 `client_order` Service 的 CreateOrder 方法(D1)中,套餐校验之后、OpenID 查询之前插入实名策略检查 +- [x] 8.3 在 `client_order` Service 的 PayOrder 方法(D4)中,在执行支付前插入实名策略检查 ## 9. C 端实名链接接口改造(E1) -- [ ] 9.1 在 `client_realname` Service 的 GetRealnameLink 方法中,目标卡定位后,`real_name_status=1` 检查前,插入策略检查:after_order + 无有效充值/订单 → 返回 CodeRealnameNotAvailable +- [x] 9.1 在 `client_realname` Service 的 GetRealnameLink 方法中,目标卡定位后,`real_name_status=1` 检查前,插入策略检查:after_order + 无有效充值/订单 → 返回 CodeRealnameNotAvailable - [ ] 9.2 验证 before_order 和 none 模式下实名链接接口行为不受影响 ## 10. 后台管理更新接口(UpdateRealnameMode) -- [ ] 10.1 在 `iot_card` Store 中新增 `UpdateRealnamePolicy(ctx, cardID uint, policy string) error` 方法 -- [ ] 10.2 在 `device` Store 中新增 `UpdateRealnamePolicy(ctx, deviceID uint, policy string) error` 方法 -- [ ] 10.3 在 `iot_card` Service 中新增 `UpdateRealnamePolicy(ctx, cardID uint, policy string) error` 方法(含幂等检查) -- [ ] 10.4 在 `device` Service 中新增 `UpdateRealnamePolicy(ctx, deviceID uint, policy string) error` 方法(含幂等检查) -- [ ] 10.5 在 `asset_dto.go` 中新增 `UpdateAssetRealnameModRequest` 和 `UpdateAssetRealnameModResponse` DTO -- [ ] 10.6 在 `asset` Handler(`internal/handler/admin/asset.go`)中新增 `UpdateRealnameMode` 方法,遵循 `UpdatePollingStatus` 模式 -- [ ] 10.7 在路由注册文件中注册新接口 `PATCH /api/admin/assets/:identifier/realname-mode` -- [ ] 10.8 更新文档生成器 `cmd/api/docs.go` 和 `cmd/gendocs/main.go`,添加新 Handler +- [x] 10.1 在 `iot_card` Store 中新增 `UpdateRealnamePolicy(ctx, cardID uint, policy string) error` 方法 +- [x] 10.2 在 `device` Store 中新增 `UpdateRealnamePolicy(ctx, deviceID uint, policy string) error` 方法 +- [x] 10.3 在 `iot_card` Service 中新增 `UpdateRealnamePolicy(ctx, cardID uint, policy string) error` 方法(含幂等检查) +- [x] 10.4 在 `device` Service 中新增 `UpdateRealnamePolicy(ctx, deviceID uint, policy string) error` 方法(含幂等检查) +- [x] 10.5 在 `asset_dto.go` 中新增 `UpdateAssetRealnameModRequest` 和 `UpdateAssetRealnameModResponse` DTO +- [x] 10.6 在 `asset` Handler(`internal/handler/admin/asset.go`)中新增 `UpdateRealnameMode` 方法,遵循 `UpdatePollingStatus` 模式 +- [x] 10.7 在路由注册文件中注册新接口 `PATCH /api/admin/assets/:identifier/realname-mode` +- [x] 10.8 更新文档生成器 `cmd/api/docs.go` 和 `cmd/gendocs/main.go`,添加新 Handler ## 11. 验证与收尾 - [ ] 11.1 运行 `lsp_diagnostics` 检查所有修改文件,确保无编译错误 -- [ ] 11.2 使用 PostgreSQL MCP 验证四张表的字段已正确添加,存量数据 realname_policy 均为 'none' +- [x] 11.2 使用 PostgreSQL MCP 验证四张表的字段已正确添加,存量数据 realname_policy 均为 'none' - [ ] 11.3 手动验证 before_order 拦截:充值/购买接口在未实名时返回 CodeNeedRealname - [ ] 11.4 手动验证 after_order 拦截:实名链接接口在无充值/订单时被拦截,有充值后放行 - [ ] 11.5 手动验证 none 模式:充值/购买/实名链接均正常放行