fix: 轮询按运营商账户限流
All checks were successful
构建并部署前端到测试环境 / deploy (push) Successful in 55s

This commit is contained in:
luo
2026-10-26 14:31:15 +08:00
parent 049f8257fb
commit 06684e1fc0
88 changed files with 7919 additions and 486 deletions

View File

@@ -0,0 +1,45 @@
# Change: 接入轮询配置匹配预览、调序、重算和统计
## Why
`docs/轮询配置管理_API简化版.md` 新增 7 个接口。当前 `PollingConfigService` 仅有配置 CRUD、启停和启用列表,轮询配置页面没有匹配预览、优先级整体调整、异步重算及统计入口。需要按已明确的契约补齐,并延续之前菜单、权限和界面交付标准。
## What Changes
- 为全部 7 个新增接口补充服务方法、请求/响应类型及契约测试。
- 在既有「轮询配置」`/polling-management/config` 内增加匹配预览入口:支持当前配置 GET 预览,以及携带多条未保存修改的 POST 预览。支持新增草稿(id=0)、覆盖配置和模拟停用,展示卡信息、命中配置和最终任务间隔;预览不写数据。
- 草稿表单支持资产状态、套餐状态、五项检查间隔及重置日前窗口字段,准确区分前四项间隔的 null 继承、0 禁用和正数间隔;保护期 null 不检查。新增字段仅进入文档明确的 overrides,不擅自扩展旧 CRUD 保存契约。
- 为超级管理员接入优先级排序提交和确认后的异步重算,界面和事件双重身份检查,不创建普通用户可分配的专属操作权限。
- 在既有配置页面提供按 task_id 查询重算进度入口;启动后可自动查询,关闭、卸载和终态清理轮询,失败保留任务 ID 与错误信息。
- 在「轮询管理」下新增「轮询配置统计」`/polling-management/config-stats`,包含重置日前加密查流量统计、分层统计两个独立授权区域;不额外增加一级菜单或详情路由。
- 界面沿用店铺列表及店铺详情标准;业务时间使用 `formatDateTime`;搜索展开仅在条件数 >=4 时启用;运营商账户复用按名称搜索的远程下拉。
- 完成后在 `docs/权限.md` 与最终回复列明实际新增菜单名称、URL、父菜单、页面权限和按钮权限,仅列普通账号配置。
## Impact
- Affected specs: `polling-config-extensions`(新增);仓库当前没有已归档 specs,已完成的 `add-gateway-rate-limit-management` 提供可复用账户搜索和通用交互能力,不更改它的接口与权限。
- Affected code: `src/api/modules/pollingConfig.ts`、`src/types/api/pollingConfig.ts`、类型统一导出、新权限常量、`src/views/polling-management/config/`、新增统计页、路由别名和静态路由、`scripts/tests/`、`docs/权限.md`。
- 保留当前工作区全部既有修改,包括网关限流、停复机时间控件、用户部署文件和 `package.json`。
- 不执行真实配置修改、优先级提交、重算任务创建、Git 推送或线上部署;写接口只用本地 mock 验证。
## Contract boundaries
- POST 匹配预览同时在 Query 与 JSON Body 传同一 ICCID;Body 包含必填 iccid,不能只传其中一处。
- 优先级接口没有明确成功 data DTO,不读取虚构的返回列表;成功后主动刷新配置列表。
- 重算 carrier_id 请求为 number/null,响应为 string,任务状态和计数按接口原值展示;不把重算完成误解为停复机执行或强制推后轮询。
- 两个统计接口提供明确 DTO,按该结构展示;周期 null 显示无数据,0 保留为真实零。分层统计注明 5 分钟缓存,未匹配项突出告警;统计刷新不宣称清除后端缓存。
- 新文档只明确 overrides 支持额外配置字段,未给出新版持久化 CRUD 契约。因此保留原保存行为,用独立草稿表单承载新增预览字段;待后端提供明确保存契约后再扩展原保存表单。
## Proposed ordinary-user configuration
| 项目 | URL / 编码 | 父菜单 / 位置 |
| --- | --- | --- |
| 轮询配置统计 | `/polling-management/config-stats`,页面权限 `polling_config_stats:page` | 轮询管理 |
| 匹配预览(当前配置/草稿) | `polling_config:match_preview` | 既有轮询配置 |
| 查询重算进度 | `polling_config:recalculate_progress` | 既有轮询配置 |
| 查看重置日前统计 | `polling_config_stats:pre_reset` | 轮询配置统计 |
| 查看分层统计 | `polling_config_stats:tiers` | 轮询配置统计 |
以上是前端配置约定,后端独立鉴权。既有轮询配置菜单和旧 CRUD 权限不因本次接入强制迁移。
用户于 2026-10-24 回复「执行」,并于 2026-10-26 回复「继续」,已批准按本提案实施。

View File

@@ -0,0 +1,87 @@
## ADDED Requirements
### Requirement: 当前及未保存配置匹配预览
The frontend SHALL implement GET and POST `/api/admin/polling-configs/match-preview`. ICCID MUST be nonempty and at most 30 characters. POST MUST send the identical ICCID in query and JSON body, with optional overrides. Results MUST show the card, all matched configurations and final task intervals, preserving interval/disabled/unmatched modes, inherited and draft indicators. Preview MUST NOT call create/update/delete/status APIs.
#### Scenario: 当前配置预览
- **WHEN** 获匹配预览权限的用户输入 ICCID 查询当前配置
- **THEN** 前端 MUST 发起 GET 查询并展示 card、matched、intervals,不擅自推导匹配顺序或最终间隔。
#### Scenario: 草稿覆盖预览
- **WHEN** 用户添加 id=0 的新草稿或覆盖已有配置并提交
- **THEN** 前端 MUST 发起 POST,Query 与 Body 的 iccid 一致,overrides 保留原有顺序、id 和 disabled
- **AND** 编辑未保存字段 MUST 不触发真实写接口,旧预览结果 MUST 不污染新的卡或草稿。
### Requirement: 草稿字段与检查语义
The draft form SHALL support every documented override field. The four ordinary task intervals MUST distinguish null/omitted inheritance, zero disable-without-inheritance and positive intervals subject to documented minima. Protect interval null MUST mean no check and non-null values MUST be integers of at least 30. Pre-reset window fields MUST use documented minima and clearly explain that both are required for effect. New preview-only fields MUST NOT be silently added to undocumented persisted CRUD bodies.
#### Scenario: 禁用与继承不同
- **WHEN** 用户将实名、流量、套餐或卡状态检查设为禁用
- **THEN** 对应值 MUST 为 0,不得变成 null 或被过滤掉
- **AND** 继承模式 MUST 使用 null/省略值,正数模式 MUST 校验对应 30 或 60 秒下限。
#### Scenario: 新字段隔离
- **WHEN** 草稿设置资产状态、套餐状态或重置日前窗口
- **THEN** 字段 MUST 仅进入已定义的 overrides 契约,不得因预览自动保存配置。
### Requirement: 优先级调整与异步重算
The frontend SHALL implement PUT `/api/admin/polling-configs/priorities` and POST `/api/admin/polling-configs/recalculate-due` with superadmin-only UI and event guards, explicit confirmation and duplicate-submit prevention. Ordered IDs MUST be nonempty, unique and valid; no undefined success DTO SHALL be assumed. Recalculation MUST be described as advance-only asynchronous work, not immediate completion of all card actions.
#### Scenario: 保存优先级顺序
- **WHEN** 超级管理员确认有效顺序
- **THEN** 前端 MUST 提交 ordered_ids 并在成功后重新获取列表
- **AND** 普通账号 MUST 无法通过 UI 或处理函数发起调序或重算启动。
#### Scenario: 启动重算
- **WHEN** 超级管理员选择运营商账户或全部并确认
- **THEN** 前端 MUST 提交 number/null carrier_id、保留 task_id 并展示真实任务状态,不在 POST 返回时直接宣称重算完成。
### Requirement: 任务进度查询
The frontend SHALL expose GET `/api/admin/polling-configs/recalculate-due/{task_id}` under a normal-user progress permission. It MUST show task ID, status, total/processed/advanced, response string carrier ID, errors and formatted timestamps. Automatic polling MUST cease on terminal status, closure, unmount or scope change, and late responses MUST be discarded.
#### Scenario: 查询已知任务
- **WHEN** 获进度权限的用户输入非空 task_id
- **THEN** 前端 MUST 对路径参数编码后查询并展示实际数据
- **AND** 查询权限 MUST 不授予创建重算任务的能力。
#### Scenario: 终态及关闭
- **WHEN** 任务 completed/failed 或对话框关闭、组件卸载
- **THEN** 自动查询 MUST 停止,不得后台无限轮询或由旧结果覆盖新任务。
### Requirement: 轮询配置统计
The frontend SHALL provide a new config statistics page under polling management for GET `/api/admin/polling-stats/pre-reset` and GET `/api/admin/polling-stats/tiers`, gated by page and separate ordinary view permissions. It MUST preserve null versus zero, label approximate counts, highlight unmatched-card warnings and indicate the five-minute tiers cache without promising forced cache invalidation.
#### Scenario: 重置日前统计
- **WHEN** 用户查看有数据或 null 的 previous/upcoming 周期
- **THEN** 前端 MUST 展示运营商、重置时间、套餐卡数、窗口检查/未检查及接口给定的分钟桶
- **AND** null MUST 显示无周期数据,真实 0 MUST 保留,不将桶擅自转换成未定义的差分或精确比例。
#### Scenario: 分层统计
- **WHEN** 用户打开分层统计
- **THEN** 前端 MUST 展示 by_config、by_package_state、computed_at、total_cards 和两个未匹配告警计数
- **AND** config_id=0 MUST 显示未匹配,不假定该配置存在。
### Requirement: 界面一致性与配置交付
The frontend SHALL reuse shop-list/detail conventions, `formatDateTime`, carrier-name remote search and search expansion only for at least four fields. Handoff MUST list the actual new menu name, URL, parent, page codes and ordinary action codes, excluding superadmin-exclusive configuration and distinguishing local mock verification from live integration.
#### Scenario: 菜单权限配置
- **WHEN** 本次实现交付
- **THEN** MUST 提供轮询管理下统计页及现有配置页新增按钮的准确配置
- **AND** 既有 CRUD 权限 MUST 不因未声明迁移被移除,不创建新的一级菜单。

View File

@@ -0,0 +1,30 @@
## 1. 契约与权限
- [x] 1.1 用户确认提案并记录审批。
- [x] 1.2 为 7 个接口补充类型及服务,区分预览 overrides 与既有 CRUD 请求。
- [x] 1.3 新增普通功能权限常量,复用超级管理员身份门禁与账户名称搜索。
## 2. 页面接入
- [x] 2.1 在轮询配置中接入当前配置 GET 预览和草稿 POST 预览,包含多条覆盖、停用模拟及完整结果。
- [x] 2.2 校验 ICCID、优先级、字段长度、null/0/正数间隔语义和成对生效的重置日前窗口。
- [x] 2.3 接入超级管理员调序界面、顺序与 ID 校验、确认和防重复提交。
- [x] 2.4 接入超级管理员异步重算启动、普通任务进度查询、终态与生命周期清理。
- [x] 2.5 新增轮询配置统计页,对接 pre-reset / tiers,准确展示空值、真实零、告警与缓存时间。
- [x] 2.6 注册一个统计菜单路由,沿用店铺页面、时间格式、条件数决定展开及运营商名称搜索标准。
## 3. 验证与交付
- [x] 3.1 覆盖全部 7 个新增接口 URL、方法、Query / Body、task_id 编码和返回契约。
- [x] 3.2 覆盖草稿语义、预览不写数据、权限、确认、防重、进度终态/卸载和迟到响应测试。
- [x] 3.3 检查列表、预览、统计、空状态、失败重试及响应式布局。
- [x] 3.4 运行相关和全量回归、类型检查、生产构建、针对性 lint / 格式 / 编码检查。
- [x] 3.5 在 `docs/权限.md` 与最终回复交付普通菜单和按钮配置及真实验证范围。
## 验证记录(2026-10-26)
- 新增轮询配置测试 20/20,全量 Node 回归 174/174;类型检查、生产构建、针对性 ESLint/Stylelint、格式与 UTF-8 检查通过。
- 本地 mock 浏览器复核配置列表、当前配置预览、草稿控件、确认后重算任务与自动终态停止、两种统计以及普通账号进度入口。375px 统计/进度无页面横向溢出,1440px 预览和统计截图已复核,1024px 普通账号入口已检查。
- 补正原配置列表检查间隔列的无效 slots 渲染,并使用唯一列 prop;原保存字段不变。
- 所有模拟 API 在本地拦截,未进行真实后端联调、菜单数据库写入、Git 推送或生产部署。生产构建仍提示项目既有 API 循环依赖、其他页面常量绑定及大 chunk 警告。
- 菜单与普通按钮编码已写入 `docs/权限.md`;不输出仅超级管理员专属配置。

View File

@@ -0,0 +1,41 @@
## Context
项目已经有网关管理、轮询配置预览与统计、单卡历史、统一导出任务、预签名 CSV 上传、运营商账户编辑和系统配置。最新文档把这些基础能力扩展为按账户调度与停复机指令队列,必须做契约升级,而不是另建同名模块。
## Decisions
- 为新增调度/告警/轮询开关契约建立独立 API 和类型模块,已存在的接口在原服务扩展。分页、枚举、账户搜索、时间格式、权限门禁和异步生命周期优先复用已验证能力。
- 仅平台账号使用现有平台身份判断(user_type=1/2),仅超级管理员使用 isSuperAdmin。每个写操作同时在入口和处理函数检查,后端继续独立鉴权;禁止用按钮权限绕过身份。
- 详情遵循店铺详情的独立隐藏兄弟路由,普通页与详情按钮使用不同权限编码;需要数据库菜单配置的隐藏详情与导出任务菜单一并交付。单卡轮询状态通过已有资产信息弹窗/页签进入,卡 ID 来自授权资产详情,绑定卡不使用设备 ID 代替。
- 展示 effective 与 configured 参数的区别;configured 为空并非零值。执行上限与 consume_capacity 的关系在可判断时前置校验,无法获知的停复机进程容量不凭空假设,由服务端验证。
- 批量、告警关闭和导入共享接口影响说明及逐项结果展示。每次确认使用目标状态对应的 impact;获取失败不展示硬编码替代文案,更不绕过确认。跨筛选、视图、资产或账号变更时清理勾选和迟到结果。
- 系统配置修改沿用现有权限,增加 polling 模块、枚举选择与 JSON 合法性提示;不因前端接入自动切换 scheduler、rate_limit_mode 或 queue_enabled。
- CSV 文件保留标识符原始文本,客户端只做文档明确的格式/数量校验;后端仍负责逐行资产范围、风险状态和权限判定。
- 模式与范围明确:observe 不宣称已拦截,队列前 500 条的 pending 计数标注近似范围;近似 QPS/p95 保留单位和接口定义。未知枚举保留原值。
## Proposed route organization
在已有「轮询管理」`/polling-management` 下新增以下可见菜单,均非仅超级管理员专属页面;其中平台限定页面还需身份控制:
| 菜单 | URL | 账号边界 |
| --- | --- | --- |
| 运营商账户调度参数 | `/polling-management/carrier-params` | 查看按后端权限;维护仅超级管理员 |
| 请求检查场景 | `/polling-management/check-scenes` | 查看按后端权限;维护仅超级管理员 |
| 失败告警 | `/polling-management/failure-alerts` | 查看、处理按权限;批量关闭仅平台 |
| 账户队列监控 | `/polling-management/carrier-queues` | 按后端权限 |
| 停复机规则演练 | `/polling-management/stop-resume-dry-run` | 仅平台 |
| 不轮询清单 | `/polling-management/polling-pauses` | 仅平台 |
| 轮询开关导入 | `/polling-management/polling-status-imports` | 仅平台 |
隐藏详情拟用 `/polling-management/carrier-params/detail/:carrier_id`、`/polling-management/failure-alerts/detail/:id`、`/polling-management/polling-status-imports/detail/:id`。导出管理沿用现有 `/asset-management/export-task-management/` 下同场景命名规则,不新建一级菜单。最终以实际注册路由和权限交付为准。
## Risks / Trade-offs
- 本次跨多个既有业务页,必须保留已有 dirty worktree:使用定点修改和基于当前状态的回归,禁止重置前一轮实现。
- C 端不在本仓库,明确外部待办;不得越出命名项目搜索或修改其他工程。
- 文档 46/16 是后端相对旧版本的统计,并非当前代码差异;以接口覆盖矩阵逐项闭环。
- 分页读取过程中数据可能变化,不能凭前端缓存自动扩大写操作目标。导入、批量操作发生部分成功后明确不可回滚,不提供虚构的整批恢复。
## Validation
覆盖所有新增/变更接口方法与 Query/Body、true/false/null/0、clear_fields、warnings、保护期删除、账号类型 1/2/3/4、五百条上限、CSV 流程、部分成功、账户级告警、特殊视图、导出场景以及异步终态/关闭/卸载。运行类型、生产构建、全量 Node 回归和针对性 lint/编码检查;浏览器使用本地 mock,明确区别于真实后端联调。

View File

@@ -0,0 +1,43 @@
# Change: 按最新运营商账户限流契约补齐调度、告警与轮询开关管理
## Why
`docs/2026-10-26-轮询按运营商账户限流-前端接口变更说明.md` 是前两轮简化文档之后的完整变更契约,包含 46 个新增接口与 16 个改动接口。当前前端已实现其中的网关管理和轮询配置扩展基础,但仍缺少账户调度、失败告警、演练、单卡排查、批量开关及导入清单,并存在必须升级的持久化配置和已废弃保护期字段。
本次以该日期文档为准做增量接入,不重复建设前两轮已有页面,不把文档中所有“新增”理解为当前项目均未实现。
## What Changes
1. 轮询配置保存升级:创建/编辑/列表/详情支持 asset_status、package_state、pre_reset_window、pre_reset_carddata_interval;四项检查间隔支持 null 继承、0 禁用、正数间隔。编辑清空显式使用 clear_fields,保存成功展示 warnings;移除 protect_check_interval。更新草稿、匹配预览和拖拽优先级,保留既有预览、进度及统计权限。
2. 保护期退场:移除后台相关输入与展示,不再请求/保存保护期间隔;兼容后端仍返回但废弃的 device_protect_status,不影响其他资产功能。
3. 现有网关页面增量:错误分类支持 terminal 类别专属 auto_disable_polling 与测试结果;限流组展示真实 observe/enforce 模式;网关调用统计按已补全 DTO 展示账户/操作汇总、失败分类、豁免来源和趋势,不再保留“字段未定义”的临时限制。成功率按 0–1 显示,p95=-1 显示超出最大桶,不伪造精确耗时。
4. 轮询管理新增「运营商账户调度参数」「请求检查场景」「失败告警」「账户队列监控」「停复机规则演练」「不轮询清单」「轮询开关导入」。失败告警使用普通列表、账户汇总、停机被拒三个视图;单卡轮询状态放入现有单卡及设备绑定卡入口,不新建一级菜单。
5. 调度参数、场景修改严格仅超级管理员;规则演练、文件导入、不轮询清单、告警批量关闭及指定导出严格仅平台账号(user_type=1/2)。普通权限不得越过账号身份边界。
6. 卡/设备列表补齐 enable_polling 筛选、列和最多 500 项的批量开关。批量提交前取 impact 文案并确认、要求原因;展示成功/跳过/失败/无权限逐项结果,部分成功不回滚。设备级联语义保持后端决定;风险停机/已销户不提供强制开启。
7. 单资产开关改为展示接口 impact 确认文案并处理拒绝响应;订单或有效期变动后读取后端实际状态,不在前端模拟自动恢复。
8. 导入复用预签名上传:purpose=polling_status_import、CSV 表头与首列标识符、最多 50000 行、file_key 前缀校验,提交后列表与逐行结果按真实状态显示。长 ICCID 保持字符串,不转数字;上传失败不得创建任务,异步轮询要清理。
9. 导出复用统一任务,增加 polling_pause、polling_stop_refused_alert、stop_resume_rule_dry_run 场景、列表/详情/下载权限和必要菜单路由;卡/设备导出携带 enable_polling,客户端不重写旧历史文件。
10. 系统配置支持 polling 模块和文档中的 string/int/bool/json 配置,以服务器返回校验规则和错误为准;轮询并发页提示仅 legacy 调度生效,并链接账户参数。运营商实名管控 0→1 改为展示后端返回的实际影响说明,确认后带 realname_control_confirm 重提,不先擅自确认。
11. 延续 UI 标准:店铺列表和详情组件、统一 formatDateTime、运营商账户名称搜索、日期范围按临期资产样式、搜索条件 >=4 才显示展开。普通账号交付清单只列实际新增/变更菜单、URL、父菜单及 xxx:xxx 权限;保留旧配置、不列仅超级管理员专属项。
## Impact
- Affected specs: `carrier-polling-scheduler-integration`(新增综合接入规范)。当前无已归档 specs;前两轮 `add-gateway-rate-limit-management`、`add-polling-config-preview-and-statistics` 已完成,不更改其既有路由 URL 与权限编码。
- Affected code: pollingConfig / gateway / asset / card / device / carrier / storage / exportTask / systemConfig 的 API、类型与界面,相关路由、权限、上传组件、导出场景配置及测试。
- 不执行后端限流调度算法或数据迁移,不在真实环境触发批量操作、导入、调序、重算、配置修改、Git 推送或生产部署。测试写操作只使用本地 mock。
- 保留工作区已有未提交的轮询配置实现与其他用户修改。
## Scope boundaries and contract risks
- 文档要求的 C 端资产详情不在当前后台仓库:检索未发现独立 C 端工程。本次只落实本仓库可定位的后台部分,C 端保护期下线在交付中明确列为外部同步项,不声称已经修改。
- 本文 46 个新增接口中,前两轮已经建立 24 个方法,预计补齐剩余 22 个;实施前按路径与方法逐项核对,不以数量替代验收。附录已给出多数新 DTO,旧接口的完整 OpenAPI 未随本文提供时,不猜测未定义字段或清空规则。
- 网关统计内部字段已经补全,覆盖前一提案的“未知字段动态展示”临时约定。轮询配置新持久化字段已经明确,覆盖上一提案“新增字段仅用于预览”的暂定边界。旧说明与回归测试需同步升级。
- warnings 未定义固定结构时以实际字符串/对象安全展示,不假设固定业务键;clear_fields 仅使用文档支持的可空字段,不任意清除配置。
- 演练 page_size 特例最大 500,其余文档分页最大 100;演练结果筛选只影响明细不影响汇总,导出接口没有 result 参数时不擅自加入。假设实名管控 on/off 账户集合不得重叠。
- 停机被拒视图仅发送文档支持的五类筛选;切换视图清除忽略项及旧勾选。账户级告警 card_id=0 不得当作有效单卡 ID 请求历史或轮询状态。
## Delivery
先实现配置/保护期和公共契约,再接调度与排查,随后接批量/导入/导出,最后完成权限矩阵、mock 浏览器和回归验证。普通菜单与按钮配置写入 `docs/权限.md` 并在最终回复给出增量清单;现有菜单和权限不重复要求用户新增。
用户于 2026-10-26 批准执行,并明确仅修改后台前端;交付时另列 C 端同步事项,不修改 C 端代码。

View File

@@ -0,0 +1,98 @@
## ADDED Requirements
### Requirement: 最新轮询配置保存契约
The admin frontend SHALL align create/update/list/detail and preview with the latest configuration fields, including asset/package matching, pre-reset window, four tri-state intervals, clear_fields and save warnings. It MUST remove protect_check_interval and must not confuse zero with null or silently discard successful-save warnings. Existing routes and permissions MUST be preserved.
#### Scenario: 保存及清空
- **WHEN** 用户保存新增条件、禁用间隔或清空可空字段
- **THEN** 前端 MUST 使用明确的更新字段和 clear_fields,保留 0、false,展示实际 warnings
- **AND** 不得继续发送保护期间隔,预览必须与同一次编辑值一致。
### Requirement: 保护期移除与兼容
The frontend SHALL remove deprecated protection-period input and UI in this repository while tolerating device_protect_status in old responses. It MUST disclose that the independently deployed C-end code is outside this repository rather than claim to modify it.
#### Scenario: 旧响应兼容
- **WHEN** 后台详情仍返回固定 none 的保护期字段
- **THEN** 页面 MUST 不显示保护期,不因废弃字段缺失影响资产查询或其他功能。
### Requirement: 账户调度、场景与状态排查
The frontend SHALL provide carrier scheduling parameter list/detail, request-check scenes, carrier queue monitoring and single-card polling state with the documented effective/configured values, queue states, confirmations and stop/resume commands. Superadmin-only writes MUST be guarded both in UI and handlers. Null defaults and real zeros MUST remain distinct.
#### Scenario: 调度参数维护
- **WHEN** 超级管理员修改参数或恢复默认
- **THEN** 前端 MUST 校验可确定的容量、比例和递增延迟约束,提交对应接口并展示服务端拒绝原因
- **AND** 普通按钮权限 MUST 不能启用专属写操作。
#### Scenario: 单卡状态排查
- **WHEN** 获授权用户从单卡或设备绑定卡查看状态
- **THEN** 前端 MUST 使用真实 card_id 请求 polling-state,展示各检查类型及 stop_resume_command
- **AND** 账户级告警 card_id=0 MUST 不得作为有效卡身份进入该入口。
### Requirement: 失败告警与停机被拒视图
The frontend SHALL provide ordinary, carrier-summary and stop-refused alert views, details, handled status and platform-only close-polling actions. Only unresolved alerts may be marked handled. The special view MUST hide and omit check_type/error_category/alert_level. Bulk results MUST distinguish success, skipped, failed and unauthorized/nonexistent without suggesting rollback.
#### Scenario: 切换特殊视图
- **WHEN** 用户切换到停机被拒
- **THEN** 请求 MUST 只带该视图支持的筛选,清除旧选择,展示额外设备/停机/套餐/轮询字段
- **AND** 导出 MUST 使用独立场景与对应权限。
#### Scenario: 批量关闭
- **WHEN** 有权限的平台账号确认关闭告警对应卡的轮询
- **THEN** 前端 MUST 提交合法 alert_ids 和原因,逐项展示结果并刷新
- **AND** 不能把账户级告警当设备级操作,不能自动重试整批已部分成功的请求。
### Requirement: 平台规则演练与实名确认
The frontend SHALL provide platform-only dry-run summary, paginated details, hypothetical carrier controls and export without executing gateway actions. Hypothetical on/off carrier sets MUST not overlap. Real carrier control changes from off to on MUST display the backend impact message and only resubmit with realname_control_confirm after explicit confirmation.
#### Scenario: 只读演练
- **WHEN** 用户运行演练或按结果筛选明细
- **THEN** 前端 MUST 仅请求 dry-run,汇总保留后端定义的范围,不调用真实停复机或修改管控接口
- **AND** 明细 result 筛选不得被描述为已改变汇总。
### Requirement: 轮询开关、清单与 CSV 导入
The frontend SHALL support card/device polling filters, batch toggles, platform pause-history and CSV import workflows. It MUST load impact descriptions from the API before confirmation, require reasons, enforce unique 1–500 asset IDs, preserve false filters, maintain string identifiers and show all item outcomes. Enterprise accounts MUST not invoke batch toggles. Upload purpose and returned key prefix MUST match the documented polling-status-import contract; file limits and async cleanup MUST be enforced.
#### Scenario: 确认并批量开关
- **WHEN** 有权限账号选择资产开启或关闭
- **THEN** 前端 MUST 展示对应 impact 后确认、提交、展示部分成功结果
- **AND** 风险停机或已销户卡不得获得强制开启选项,403 必须回滚前端开关并保留原状态。
#### Scenario: 导入任务
- **WHEN** 平台账号上传带表头的合法 CSV 并确认
- **THEN** 前端 MUST 先获取预签名、上传成功后再提交任务,保留 ICCID 原文,展示任务与逐行错误
- **AND** 上传失败不得创建任务,终态、关闭和卸载 MUST 停止自动查询。
### Requirement: 系统模式与监控指标
The frontend SHALL add the polling system-config module, support documented JSON editing, display actual rate-limit/scheduler mode, and explain legacy-only concurrency behavior. Gateway monitoring SHALL use the now-defined operation DTOs, show success rates in the correct scale, identify approximate p95/queue-sample limits and not invent missing metrics.
#### Scenario: 观察模式
- **WHEN** 接口返回 observe
- **THEN** 页面 MUST 说明只统计不拦截,区分 would_limit 与真正 rate_limited
- **AND** 不得因前端接入自动修改生产调度或限流开关。
### Requirement: 导出、路由与权限交付
The frontend SHALL integrate the three new export scenes and preserve enable_polling filters for existing card/device exports. New pages, hidden details and export-task routes MUST follow existing menu conventions. Final handoff MUST list actual incremental menu names, URLs, parents and ordinary xxx:xxx button codes, excluding superadmin-exclusive configuration and preserving previous menu codes.
#### Scenario: 配置交付
- **WHEN** 实现完成
- **THEN** 前端 MUST 同步 docs/权限.md 和最终回复中的增量菜单与按钮清单
- **AND** MUST 区分平台身份限制、普通按钮权限、真实后端验证与本地 mock,以及本仓库外的 C 端同步事项。

View File

@@ -0,0 +1,38 @@
## 1. 契约与基线
- [x] 1.1 用户批准提案,记录当前 dirty worktree 和前两轮回归基线。
- [x] 1.2 建立文档接口到现有/新增方法、页面、权限及测试的覆盖矩阵,核对 46 新增与 16 改动的实际差异。
- [x] 1.3 新增账户调度、场景、告警、队列、单卡状态、批量开关、导入/清单、演练及 impact 类型和服务。
## 2. 既有页面升级
- [x] 2.1 升级轮询配置持久化 DTO、表单、列表、clear_fields、warnings、三态间隔、保存前预览和优先级拖拽。
- [x] 2.2 清除本仓库保护期输入/展示与请求字段,保留后端废弃响应兼容;记录外部 C 端同步项。
- [x] 2.3 增加 terminal auto_disable_polling,升级错误分类列表/表单/测试。
- [x] 2.4 依完整 DTO 改造网关汇总、趋势和 observe/enforce 模式展示。
- [x] 2.5 增加 polling 系统模块与 JSON 编辑校验、旧并发页说明;运营商实名管控改用服务端影响说明二次确认。
## 3. 调度、排查与演练
- [x] 3.1 完成账户调度参数列表/详情/超级管理员维护和容量边界。
- [x] 3.2 完成请求检查场景列表及超级管理员维护、严格递增确认延迟校验。
- [x] 3.3 完成账户队列和停复机指令监控、初始化状态、真实指标及异步生命周期。
- [x] 3.4 在单卡及设备绑定卡接入轮询状态与停复机命令,校验真实卡 ID 和账号权限。
- [x] 3.5 完成失败告警普通/汇总/停机被拒视图、详情、处理、记录联动、平台批量关闭。
- [x] 3.6 完成平台规则演练、假设管控条件、汇总/分页明细、只读保障与导出。
## 4. 开关、清单与文件任务
- [x] 4.1 卡/设备列表新增轮询筛选和列,导出保留 false 筛选,接入批量开关原因、影响确认和逐项结果。
- [x] 4.2 单资产开关使用 impact 文案,处理风险/已销户拒绝,刷新后端实际状态。
- [x] 4.3 平台不轮询清单支持全部筛选、历史/系统操作者、批量开启及导出。
- [x] 4.4 平台 CSV 导入支持预签名、purpose、file_key、行数校验、创建和任务列表/逐行详情。
- [x] 4.5 接入三个导出场景及任务列表、详情、下载权限,维持历史文件兼容。
## 5. 验证与交付
- [x] 5.1 注册新可见/隐藏路由和权限,保留前两轮 URL、时间/账户搜索/展开标准。
- [x] 5.2 完成接口覆盖矩阵测试、权限与部分成功/视图切换/上传/轮询清理回归。
- [x] 5.3 验证类型、构建、全量测试、lint、格式、编码和本地 mock 浏览器交互/响应式。
- [x] 5.4 同步旧文档和 `docs/权限.md`,交付新增菜单名称/URL/父菜单、普通按钮编码;排除仅超级管理员专属项。
- [x] 5.5 明确真实联调范围、尚缺后端契约和外部 C 端同步项,不将 mock 结果当作线上验证。