修复停复机忽略免实名策略并归档变更
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled

This commit is contained in:
2026-09-07 10:06:17 +08:00
parent 370fd3e67f
commit 5424751993
7 changed files with 170 additions and 11 deletions

View File

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-09-07

View File

@@ -0,0 +1,23 @@
## Context
统一停复机实名判断已有五处调用,行业卡和已实名卡当前直接放行。资产侧既有策略优先级为设备策略优先、无设备时使用卡策略。
## Goals / Non-Goals
**Goals:** 将相同优先级用于停复机实名门槛,避免免实名资产被错误停机或阻止复机。
**Non-Goals:** 不修改实名事实、卡分类、套餐激活流程、轮询调度、重试策略或生产数据;不将免实名当成免套餐或免风控。
## Decisions
- 保留 `isRealnameOK` 单一入口,改为接收 context 并返回错误;行业卡或已实名卡直接返回,无额外数据库查询。
- 其他卡通过既有有效绑定查询确定载体。独立卡和无有效绑定卡使用自身策略;有效绑定设备使用设备策略,通过 GORM 仅查询策略列。绑定或设备读取错误上抛,禁止回退放行。
- 五处调用全部接收错误;设备批量复机保留逐卡继续及错误聚合,手动命令保留失败审计。
- Audit Event、Integration Log、Outbox 继续使用现有命令路径查询失败不执行外部命令。Domain Ledger 为 N/A无金额变化。
- 用可删除的本地 Go smoke 程序执行真实停复机服务GORM 查询回调提供合成卡、绑定、设备和套餐,不连接数据库或网关;验证前后行为差异,再构建 API/worker。不新增永久测试。
## Risks / Trade-offs
- 未实名普通设备卡会新增设备策略读取;行业卡、已实名卡和独立卡不增加此读取。
- 设备策略读取失败会中止该卡本次操作,这是避免错误停机或错误放行的保守选择。
- 无需迁移。发布由维护者完成;主 Specs 暂不同步,保留独立 Change 供发布审阅与归档。

View File

@@ -0,0 +1,24 @@
## Why
停复机服务仅按行业卡类型或实名事实放行,遗漏已配置的无需实名策略,导致具有生效套餐的未实名普通卡被重复请求停机。用户要求只修代码,不核对或修改生产数据。
## What Changes
- 停复机统一实名判断识别实际生效的 `none` 策略;保留行业卡与已实名卡的既有放行规则。
- 独立卡使用卡策略,有效绑定设备的卡使用设备策略;读取失败不得按免实名放行。
- 自动停复机、设备复机及手动停复机共用判断;套餐、流量、风控、保护期及失败重试规则不变。
- 不修改卡类型或实名事实,不访问生产或上游接口验证,不引入永久测试。
## Capabilities
### New Capabilities
无。
### Modified Capabilities
- `polling-operations`: 停复机实名门槛遵循实际生效策略。
## Impact
修改 `internal/service/iot_card/stop_resume_service.go` 的统一判断及其调用;复用现有 GORM 模型和绑定查询。无 Schema、路由或配置变更。通过本地隔离运行与 API/worker 构建验证。

View File

@@ -0,0 +1,29 @@
## ADDED Requirements
### Requirement: 停复机遵循实际生效实名策略
系统 SHALL 在自动停机、自动复机、设备批量复机和手动停复机的实名门槛中放行行业卡、已实名卡及实际生效策略为 `none` 的卡。独立卡或无有效设备绑定的卡使用卡策略,有有效设备绑定的非独立卡使用设备策略。系统 MUST 保留真实实名状态,不得以豁免伪造已实名事实。其他策略的未实名普通卡 MUST 保持实名限制;套餐、流量、风险、保护期及非轮询停机不自动复机等既有限制保持不变。
#### Scenario: 免实名独立卡有生效套餐
- **WHEN** 未实名普通独立卡配置 `none`,存在生效套餐且流量未耗尽,当前网络在线
- **THEN** 系统不因未实名向上游请求停机
#### Scenario: 免实名卡从轮询停机恢复
- **WHEN** 上述卡当前因 `not_realname` 停机,满足其他自动复机条件
- **THEN** 系统不因未实名阻止自动复机
#### Scenario: 设备策略优先
- **WHEN** 未实名普通卡有效绑定设备,卡与设备的实名策略不同
- **THEN** 系统以设备策略判定实名豁免,卡自身的 `none` 不得覆盖设备的实名要求
#### Scenario: 行业卡与已实名卡兼容
- **WHEN** 行业卡未实名或普通卡已实名
- **THEN** 系统保留已有实名门槛放行行为
#### Scenario: 无套餐和流量耗尽不豁免
- **WHEN** 免实名卡没有生效套餐或流量已经耗尽
- **THEN** 系统仍按对应业务原因执行停机判断
#### Scenario: 策略读取失败
- **WHEN** 未实名普通卡的有效设备绑定或设备策略查询失败
- **THEN** 系统报告错误且不对该卡发起本次停复机命令,不按卡策略回退放行

View File

@@ -0,0 +1,17 @@
## 1. 修复
- [x] 1.1 使用合成卡与套餐运行真实停复机判断,捕捉免实名卡被判停机的修复前失败。
- [x] 1.2 统一解析停复机实名策略,更新自动、设备及手动调用的错误处理。
## 2. 验证
- [x] 2.1 运行隔离 smoke覆盖免实名停复机、设备优先级、兼容行为、套餐限制及读取失败。
- [x] 2.2 格式化修改的 Go 文件,构建 API/worker校验独立 Change 并移除临时验证程序。
## 验证结果
- 临时 `go run ./cmd/realname-smoke-tmp`:修复前 6 个场景失败,其中免实名独立卡被判为 `not_realname` 且不可复机;修复后全部 12 个场景通过。
- 验证执行真实 `checkStopReasons``shouldResume`,允许保持在线的场景同时执行 `EvaluateAndAct`GORM 查询由合成数据回调提供,不连接数据库或网关。未验证真实上游停复机,也未执行设备批量及手动命令端到端场景。
- `gofmt -w internal/service/iot_card/stop_resume_service.go && go build ./cmd/api ./cmd/worker`:退出码 0Go 模块缓存写入出现 permission denied 警告,未阻断构建。
- `openspec validate fix-stop-resume-realname-policy --strict`:通过。
- 临时 smoke 文件及命令目录已删除,无永久测试、数据修改或生产操作。主 Specs 留待独立同步/归档流程。

View File

@@ -62,6 +62,34 @@
- **WHEN** 授权操作者查询 `card_status` 的并发状态
- **THEN** 返回的 `task_type_name` 为“卡状态检查”
### Requirement: 停复机遵循实际生效实名策略
系统 SHALL 在自动停机、自动复机、设备批量复机和手动停复机的实名门槛中放行行业卡、已实名卡及实际生效策略为 `none` 的卡。独立卡或无有效设备绑定的卡使用卡策略,有有效设备绑定的非独立卡使用设备策略。系统 MUST 保留真实实名状态,不得以豁免伪造已实名事实。其他策略的未实名普通卡 MUST 保持实名限制;套餐、流量、风险、保护期及非轮询停机不自动复机等既有限制保持不变。
#### Scenario: 免实名独立卡有生效套餐
- **WHEN** 未实名普通独立卡配置 `none`,存在生效套餐且流量未耗尽,当前网络在线
- **THEN** 系统不因未实名向上游请求停机
#### Scenario: 免实名卡从轮询停机恢复
- **WHEN** 上述卡当前因 `not_realname` 停机,满足其他自动复机条件
- **THEN** 系统不因未实名阻止自动复机
#### Scenario: 设备策略优先
- **WHEN** 未实名普通卡有效绑定设备,卡与设备的实名策略不同
- **THEN** 系统以设备策略判定实名豁免,卡自身的 `none` 不得覆盖设备的实名要求
#### Scenario: 行业卡与已实名卡兼容
- **WHEN** 行业卡未实名或普通卡已实名
- **THEN** 系统保留已有实名门槛放行行为
#### Scenario: 无套餐和流量耗尽不豁免
- **WHEN** 免实名卡没有生效套餐或流量已经耗尽
- **THEN** 系统仍按对应业务原因执行停机判断
#### Scenario: 策略读取失败
- **WHEN** 未实名普通卡的有效设备绑定或设备策略查询失败
- **THEN** 系统报告错误且不对该卡发起本次停复机命令,不按卡策略回退放行
## 可达操作索引
本节只用于入口导航,不是行为 Requirement业务义务以上述 Requirements 为准。