feat(手机号资产关联): AUG26-009 手机号—资产关联、十项上限与后台解绑
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m2s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m2s
- 新增成对迁移 000223(tb_phone_asset_association,含有效关系部分唯一索引与 down 守卫)与 000224(解绑导入任务表),不回填历史 - H5:need_bind_phone 三支判定(开关关闭完全短路);已有主号幂等建联;十项上限按手机号 advisory 串行化(含换绑到全新号的并发场景);换绑原子迁移与冲突整单回滚;不写遗留列 - 后台:关联列表、单项/批量解绑、CSV 导入解绑(B1–B16),超管/平台 gate + 资产数据范围复核,三态统一文案 - 读侧:卡/设备列表与详情按页一次 IN 聚合;两类导出补「关联手机号」列并保留历史表头反解兼容 - 脱敏:关联审计走独立动作/资源只写脱敏手机号;访问日志手机号类字段脱敏 - 同步主 Spec openspec/specs/phone-asset-association 并归档 AUG26-009,补齐 requirement-evidence 与入口矩阵,context-health 通过
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
## 1. 关联事实与 H5 建联
|
||||
|
||||
- [x] 1.1 新增成对迁移 `migrations/000223_*`(编号按实施时目录最大编号复核,当前最大为 `000222`)、模型与常量:关联表含 `asset_type`、`asset_id`、`phone`、`status`、建立时间、建立来源(固定 `h5_sms_verification`)与失效信息;配有效关系部分唯一索引 `(phone, asset_type, asset_id)`、按 `phone` 计数索引、按 `(asset_type, asset_id)` 集合查询索引;`down` 带有效性守卫,不回填历史。
|
||||
- [x] 1.2 新增关联 store 的四个方法:`ExistsValid`(登录判定)、`CountValidByPhone`(十项上限)、`ListValidByAssets`(列表/导出一次批量聚合)、`CreateIfAbsent`(幂等建联)。
|
||||
- [x] 1.3 改造 `issueLoginToken` 为三支判定:无主号 → `true`;有主号但未与当前访问资产存在有效关系 → `true`;已关联 → `false`;全局开关关闭 → 恒 `false` 且不查询、不创建、不删除关系。关联查询使用 JWT 的 `asset_type/asset_id`,不使用 `phone` claim。保持登录响应形状不变。
|
||||
- [x] 1.4 扩展 `BindPhone`:已有主号且提交号码等于主号、验证码有效时幂等建联且不改账号手机号;号码不等于主号仍拒绝;无当前访问资产身份时只完成账号手机号绑定;建联前在事务内锁定手机号行计数,达十项返回上限文案且不写关联。
|
||||
- [x] 1.5 改造 `ChangePhone`:事务内先算「新号现有有效关系数 + 旧号待迁移数」,超十项整次失败;通过时把旧号全部有效关系原子迁移至新号;与「新号已存在的同资产有效关系」冲突时整次失败回滚;不写遗留列 `tb_personal_customer.phone`;审计只写脱敏手机号。加锁顺序统一为按手机号行 `id ASC`。
|
||||
|
||||
## 2. 读侧与后台解除
|
||||
|
||||
- [x] 2.1 资产列表与详情补关联手机号投影:按当页资产集合一次 `IN` 批量查询后装配,禁止逐资产查询;卡与设备两条 Query 路径都要覆盖。
|
||||
- [x] 2.2 IoT 卡与设备两个导出场景补「关联手机号」列:设备导出新列并入尾部并让 `deviceExportTailHeaderCount` 递增,`buildDeviceExportRow` 同步;`cardGroupCountFromHeaders` 保留旧表头反解兼容分支,保证历史任务可用 `ResolvedHeaders` 重导出。
|
||||
- [x] 2.3 实现单项解绑 `DELETE /phone-asset-associations/:id`:路径主键即指定一条关系;必须二次确认并填写原因(1~500 字符);锁关系后复核资产数据范围,标记失效并逐条审计(脱敏)。
|
||||
- [x] 2.4 实现勾选批量解绑 `POST /phone-asset-associations/batch-unbind`:资产集合去重、二次确认、原因必填;每项资产独立解除全部有效关系,返回成功数、失败数与逐项结果;部分成功不回滚成功项。
|
||||
- [x] 2.5 实现 CSV 解绑导入场景,按 B1–B16 全清单(不含 B17):B1 任务类型常量;B2 队列常量、`QueueForTaskType` 分支与队列权重;B3 新任务表成对迁移(含 `down` 守卫);B4 任务模型(含逐行结果明细 jsonb);B5 任务 store(`UpdateStatus`/`UpdateProgress`/`UpdateResult`);B6 `internal/bootstrap` 各装配文件注入;B7 worker 处理器(逐行独立事务、BOM 去除、UTF-8 校验失败按 GBK 回退、固定表头列序、行号自数据首行起计、任务级失败不产生行明细、不设行数硬上限);B8 `pkg/queue/handler.go` 处理器注册;B9 `cmd/worker/main.go` 启动补偿;B10 `internal/infrastructure/releasegate/checker.go:243` 未完成异步任务表清单追加新表;B11 应用 service(建任务、入队失败必落库);B12 Handler 与 DTO(入口限超级管理员与平台用户);B13 路由注册;B14 占位装配;B15 上传用途常量、存储映射、用途枚举与上传接口文档表四处同步;B16 审计动作码与资源注册。列:资产标识(必填,复用既有资产标识解析)+ 备注(可选),解绑原因由任务级必填字段与二次确认提供;**任务明细持久化解绑当时的完整手机号快照**(B13、B14 与 2.6 合并执行)。
|
||||
- [x] 2.6 注册本 Change 全部新增接口的路由(沿用超管/平台路由组级 gate 先例)、`cmd/api/docs.go` 与 `cmd/gendocs/main.go` 占位装配及 OpenAPI 文档(ENG-ROUTE-001),并补充三态统一失败文案常量供新用例使用;既有内联字面量按 As-Is 保留。
|
||||
|
||||
## 3. 验证与交付
|
||||
|
||||
- [x] 3.1 按 ENG-TEST-001 在维护者指定测试面验证正向行为:开关开启首次访问未关联资产返回 `need_bind_phone=true` 且完成验证后建立关系;已关联资产不再要求验证;开关关闭后登录不要求验证且不新建、不删除关系;第 11 项资产验证被拒绝且原十项不变;重复验证同一资产不产生第二条关系;换绑超限整次失败且新旧关系均不变;换绑迁移与新号既有同资产关系冲突时整次回滚。
|
||||
- [x] 3.2 验证反向断言:换货完成后关联记录数不变且新资产不继承旧资产关联;换货新资产首次登录返回 `need_bind_phone=true`;资产导入后关联记录数不变;后台资产编辑后关联记录数不变。
|
||||
- 说明:判定为完成(维护者裁定)。证据:全仓 `tb_phone_asset_association` 写入点仅本 Change 的 5 处(H5 建联、换绑迁移、后台单项解除、后台批量解除、CSV 导入解除),`exchange` / `customer_binding` / 资产导入 / 后台资产编辑模块对本表零引用且零改动;等价谓词「有主号但未与当前访问资产存在有效关系 → `need_bind_phone=true`」已实测。完整换货 / 资产导入端到端(需共享队列与对象存储)未执行,作为残留范围记录。
|
||||
- [x] 3.3 验证读侧与脱敏:资产列表按页一次聚合(以查询次数为准,禁止 N+1);卡与设备两类导出均含关联手机号列且历史任务表头仍可反解列组;批量任务结果在关系失效后仍返回完整手机号快照;审计、日志与错误中只出现脱敏手机号;越权、资产不存在、已无有效关系三态返回同一文案。
|
||||
- [x] 3.4 验证权限与批量语义:代理、企业、个人客户访问后台解绑入口返回 403;数据范围外资产不可见也不可解除;单项解绑未指定关系被拒绝;缺二次确认或原因被拒绝;批量与导入按资产解除全部有效关系,逐资产独立结果,失败行保留原状且不影响其他行,无行数硬上限。
|
||||
- [x] 3.5 验证迁移与交付命令:隔离库 `up/down/up`(有数据时 `down` 被守卫拒绝);`gofmt -w <changed-go-files>`、`go build ./cmd/api ./cmd/worker`、`go run cmd/gendocs/main.go`、`openspec validate add-phone-asset-associations --strict`、`openspec doctor --json`;自动化测试按项目决策为 N/A。fixture 只增删本 Change 自己的记录,禁止重置整库。
|
||||
Reference in New Issue
Block a user