Files
junhong_cmp_fiber/.scratch/ur73-resume-realname-policy/PRD.md
2026-07-21 15:26:07 +09:00

96 lines
8.3 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.
# PRDUR#73 按运营商实名能力控制复机
Status: ready-for-agent
---
## Problem Statement
当前停复机代码同时存在“行业卡无需实名”和“所有卡都必须实名”的互相冲突分支。卡业务类别被错误当成实名能力,导致相同运营商能力下出现不同复机结果,也使手动复机、设备复机、自动复机和开放接口无法共享同一规则。
七月迭代的数据同步公共方案将卡实名、流量和网络状态收口到统一 DDD 边界。UR#73 不能继续在旧 Service 中补条件,否则会形成第二套卡状态规则和状态写入口。
## Solution
复机是否要求实名只由卡所属运营商的 `realname_link_type` 决定:`none` 不要求实名,`template``gateway` 要求卡已实名。`card_category` 仅保留分类展示用途,不再参与任何复机资格判断。
该规则进入数据同步公共 Asset/Card 领域模型,由统一复机 Application UseCase 供后台单卡、设备、自动任务和 OpenAPI 调用。Gateway 成功后的状态收敛、领域事件、Outbox、Audit Event 和同步触发全部复用公共 DDD不在旧 Service 直接更新卡状态。
## User Stories
1. 作为运营人员,我希望不支持实名能力的运营商卡即使本地仍为未实名,也可在满足其他条件时复机。
2. 作为运营人员,我希望需要实名的运营商卡在未实名时被明确拒绝。
3. 作为运营人员,我希望普通卡和行业卡遵循相同的运营商能力规则,卡类别不再造成例外。
4. 作为设备操作人员,我希望设备下每张卡独立按其运营商能力判断,不因设备中其他卡的状态被错误放行或拦截。
5. 作为 OpenAPI 调用方,我希望复机与后台入口使用同一资格规则。
6. 作为维护人员我希望所有入口只调用一个复机用例避免轮询、Service 和 Handler 各自维护规则。
7. 作为审计人员,我希望成功、拒绝和失败都进入统一审计链路并能关联后续同步观测。
## Implementation Decisions
### 业务规则
- `realname_link_type=none` 表示运营商不要求实名;复机资格不检查 `real_name_status`
- `realname_link_type=template``gateway` 表示运营商要求实名;仅 `real_name_status=1` 可继续复机。
- `card_category=normal/industry` 只用于分类和展示,不参与手动复机、设备复机、自动复机、套餐触发复机或 OpenAPI 复机判断。周期轮询资格不由 UR#73 调整。
- `realname_policy` 只描述实名与购买顺序,不替代运营商能力;本需求不得用它决定复机是否要求实名。
- 保留所有既有非实名约束,包括风险停机、已销户、机卡分离状态限定、停复机保护期、有效套餐、流量耗尽、网络状态和数据权限。
- 多卡设备逐卡判断。满足条件的卡正常处理,不满足条件的卡跳过或拒绝;不得因其中一张卡无需实名而放行全部卡。
- 未知 `realname_link_type`、运营商记录缺失或配置读取失败属于配置/内部错误,不得静默按 `none` 放行,也不得调用 Gateway。
- 未实名拒绝继续使用统一禁止访问业务错误,并向用户返回中文原因“卡未实名,无法操作”。
### DDD 与公共数据同步边界
- 本需求依赖七月“数据同步触发与轮询优化”公共能力先落地;公共能力尚未完成时,不允许先在旧 StopResume Service 中打临时补丁。
- “运营商是否要求实名”和“卡当前是否具备复机资格”属于 Asset/Card 领域规则。领域方法只接收已加载的运营商能力和卡状态,不直接查询 GORM、Redis、Fiber 或 Gateway。
- 后台单卡复机、后台设备复机、自动复机、套餐激活后的复机和 OpenAPI 复机统一调用 Application 复机用例;各入口不得自行判断 `card_category``real_name_status``realname_link_type`
- Application 用例负责加载并锁定必要状态、调用领域资格规则、执行 Gateway 端口、记录业务结果并发布可靠事件。
- 旧 Service 如需过渡,只能作为无业务判断的内部门面转发到新用例;不得继续直接写实名、网络状态、停机原因或复机时间。
- `ApplyCardObservation` 是上游观测写入卡状态的唯一入口。复机 Gateway 返回成功不授权旧 Service 直接修改本地网络状态。
- 复机成功边界发布网络状态同步触发按公共方案创建立即、3 分钟、5 分钟观测序列;观测结果通过 `ApplyCardObservation` 应用,达到开机预期后剩余任务直接完成。
- 状态变化产生统一领域事件和 Outbox触发其他业务联动不得由多个入口重复执行相同副作用。UR#94 本期保持现有轮询调度和重排策略。
- Audit Event 和 Integration Log 使用公共审计设施;不得继续扩展旧资产审计为第二套长期写入系统。
### 接口与前端
- 后台继续复用 `POST /api/admin/assets/{identifier}/start`;卡和设备均走统一复机用例。
- OpenAPI 继续复用现有卡复机接口;机卡分离限定仍先于一般复机规则生效。
- 本需求不新增 API不因规则修正改变成功响应外层结构。
- 前端不读取 `card_category` 预判,不在本地复制运营商能力规则。
- 提交期间禁用重复操作;失败原地展示后端中文业务原因;成功后重新拉取资产详情。
- 详情刷新读取本地状态快照;异步观测尚未收敛时沿用公共同步状态展示,不伪造 Gateway 已确认结果。
### 发布与兼容
- 删除或改造所有以 `card_category=industry` 跳过实名的生产分支和注释。
- 删除手动单卡、设备批量及自动复机中直接判断“必须已实名”的重复分支,统一转调领域规则。
- 发布前核查 `realname_link_type!=none` 但资产 `realname_policy=none` 的冲突数据;修正结果遵循公共数据同步方案,不在运行时静默选边。
- API、Worker 和公共卡状态能力在同一维护窗口切换,不保留新旧复机规则双写或双判定。
## Testing Decisions
- 领域单元测试覆盖 `none/template/gateway` 与实名 0/1、普通/行业卡的完整矩阵,并证明卡类别不影响结果。
- Application 测试使用可控 Gateway Adapter验证不合格时绝不调用 Gateway合格时只调用一次并正确发布审计和同步触发。
- HTTP 集成测试覆盖后台卡复机、设备复机和 OpenAPI 入口穿过真实认证、权限和统一错误处理PostgreSQL、Redis 使用开发配置Gateway 使用测试 Adapter禁止对真实业务卡执行停复机。
- 验证设备内混合运营商能力、混合实名状态时逐卡处理,不发生整设备误放行。
- 回归风险停机、销户、保护期、无有效套餐、流量耗尽、非机卡分离 OpenAPI 卡等既有限制。
- 验证 Gateway 成功后旧 Service 没有直接写状态,公共同步序列生成一次,观测确认后由 `ApplyCardObservation` 更新状态并提前完成剩余任务。
- 验证重复请求、重复事件和重复观测不造成重复 Gateway 调用、重复领域事件或重复审计。
- 人工验收使用明确隔离的联调卡,对三个运营商能力值分别验证;核对 PostgreSQL 状态、Outbox/Audit Event、Integration Log 和同步任务关联链路。
## Out of Scope
- 不修改 `card_category` 的存储和展示。
- 不新增实名能力字段,继续使用运营商 `realname_link_type`
- 不重新设计风险停机、销户、机卡分离、保护期、套餐或流量规则。
- 不新增显式同步按钮或同步 API。
- 不修改周期轮询的卡资格、卡类别过滤、配置、频率、队列或重排策略UR#94 只把轮询观测的状态应用收口到公共用例。
- 不在 UR#73 单独实现公共观测、Outbox、审计或 0/3/5 调度的另一份副本。
- 不通过本需求处理运营商回调、事件同步和全部数据同步入口;回调与事件由 UR#94 交付,周期轮询策略本轮保持现状并留待后续设计。
## Further Notes
- 推荐实施顺序:数据同步公共 DDD → UR#73 接入统一复机用例 → 前后端联调。
- 当前代码仍存在行业卡豁免、强制实名和直接写网络状态等多套实现;它们是迁移输入,不是目标架构。
- 本 Spec 对数据同步公共 DDD 的复用是硬约束,不得以“先快速修一行”替代。