收口七月卡状态回调与系列授权兼容契约
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
完成运营商实名回调、业务事件观测序列与受控配置装配,同时恢复 UR43 已交付的 packages[].remove 字段及旧响应兼容,统一更新 OpenSpec、OpenAPI 和交付文档。 Constraint: 七月测试环境里程碑不新增或运行自动化测试 Rejected: 以必填 operation_type 替换 packages[].remove | 会破坏已交付前端契约 Confidence: high Scope-risk: broad Directive: 后续修改系列套餐管理接口必须保持 packages[].remove 和 ShopSeriesGrantResponse 兼容 Tested: go run ./cmd/gendocs;go build -buildvcs=false ./...;openspec validate complete-july-iteration-test-release --strict;git diff --check Not-tested: 按本 Change 约定未运行 go test,真实运营商与 Gateway 联调延期
This commit is contained in:
@@ -38,6 +38,11 @@
|
||||
| 代理主钱包充值与人工调整正向入账 | 延期(测试环境冻结;生产前由 6.5 为入账补齐同事务 Audit Event) | 充值/人工调整业务事实、`tb_agent_wallet` 与唯一成功流水在同一事务形成权威事实 | N/A(本接缝不调用支付或审批外部系统) | 同事务写入 `wallet.agent_main.credited`,消费者按成功流水复核;支付/审批 Integration Log 由 UR#34 外部流程负责 |
|
||||
| 代理订单主钱包退款回充 | 延期(测试环境冻结;生产前由 6.5 为退款资金变更补齐同事务 Audit Event) | 原成功扣款流水定位付款钱包并限定金额;退款审批、`tb_agent_wallet` 与唯一成功退款流水同事务形成权威事实 | N/A(本资金接缝不调用渠道或审批外部系统) | 同事务写入 `wallet.agent_main.refunded`,消费者复核退款流水、原扣款事实、金额上限和资产快照 |
|
||||
| 代理商资金概况信用投影 | N/A(普通受权读取;不返回其他数据范围的资金事实,不执行资金或配置变更) | 只读投影 `tb_shop`、主/佣金钱包、提现汇总和主账号;派生金额不另建事实表 | N/A(无外部系统调用) | N/A(纯 Query 不产生可靠副作用) |
|
||||
| 受控系统配置更新 | N/A(用户已明确取消全局 Audit Event;仅超级管理员可更新代码注册 Key,未知 Key、非法类型和值域均拒绝) | `tb_system_config` 是配置值、类型、模块及更新人的 PostgreSQL 权威事实,更新后失效 Redis 缓存 | N/A(配置更新不调用外部系统;不得写 Integration Log 冒充配置审计) | N/A(配置更新不产生可靠异步副作用) |
|
||||
| 电信实名结果回调 | N/A(Audit Event 已移出本 Change;运营商来源真实性验证也不在本票边界) | `tb_iot_card` 是实名状态、首次实名时间和逆转窗口的权威事实 | 每次入站先写 `tb_integration_log`,仅保存正文摘要;覆盖 `invalid_payload/ignored/not_found/conflict/success/failed` 终态 | 实名事实首次变化时由公共 `ApplyCardObservation` 同事务写入实名状态变化 Outbox;重复成功不重复写事件 |
|
||||
| 移动实名成功回调 | N/A(Audit Event 已移出本 Change;不接入旧平台登录、MSISDN 补查或来源真实性验证) | `tb_iot_card` 是实名状态、首次实名时间和逆转窗口的权威事实 | 每次入站先写 `tb_integration_log`,仅保存正文摘要;覆盖 `invalid_payload/not_found/conflict/success/failed` 终态,并通过 pending 租约恢复中断处理 | 仅合法成功报文进入公共 `ApplyCardObservation`;实名事实首次变化时同事务写入 Outbox,重复成功不重复写事件 |
|
||||
| 联通实名成功回调 | N/A(Audit Event 已移出本 Change;不复制旧 `inner_callback`、第三方推送或 Gateway 二次确认) | `tb_iot_card` 是实名状态、首次实名时间和逆转窗口的权威事实;上游 `dateChanged` 只用于幂等和留痕 | 每次入站先写 `tb_integration_log` 正文摘要;覆盖 `invalid_payload/not_found/conflict/success/failed`,关闭时记录 `ignored` | 仅合法成功报文进入公共 `ApplyCardObservation`;实名事实首次变化时同事务写入 Outbox,重复成功不重复写事件 |
|
||||
| 联通解除实名回调 | N/A(只识别并留痕外部解除通知,不把单次回调作为本地实名逆转事实) | `tb_iot_card` 保持原实名状态、首次实名时间、检查时间及逆转计数,回调不写领域事实 | 每次入站先写 `tb_integration_log` 正文摘要;覆盖 `invalid_payload/not_found/conflict/ignored/failed` 终态并支持 pending 租约恢复 | N/A(不调用公共实名观测,不产生状态变化、停机或套餐事件) |
|
||||
|
||||
## 旧 Writer 与旧表写入口清单
|
||||
|
||||
|
||||
@@ -8,23 +8,23 @@ Status: ready-for-agent
|
||||
|
||||
代理系列授权及套餐授权的数据结构和接口已经存在,首次授权也已经能够在同一事务中创建系列授权与多条套餐授权。但前端没有把现有系列套餐列表和授权详情正确组合成批量选择视图,后续追加套餐时不容易区分未授权与已授权,也容易混淆上级当前成本、目标代理授权成本和建议零售价。
|
||||
|
||||
现有 `PUT /api/admin/shop-series-grants/{id}/packages` 还将新增、改价和移除混在同一请求中:已经授权的套餐再次提交不同价格会被直接改价。这会使一个看似“新增授权”的并发请求静默覆盖其他运营人员刚设置的成本价,业务意图和审计语义均不明确。
|
||||
现有 `PUT /api/admin/shop-series-grants/{id}/packages` 已通过每个套餐项的 `remove` 字段支持新增、改价和移除,其中 `remove=true` 的软删除语义已经交付并被前端使用。本需求必须在增强批量原子性、权限和价格边界时保持该字段兼容,不能将它删除或改成必填的新顶层命令字段。
|
||||
|
||||
## Solution
|
||||
|
||||
复用现有套餐列表和系列授权详情,不新增候选 API。首次授权直接使用现有套餐列表选择多项,并由 `POST /api/admin/shop-series-grants` 在同一事务创建系列及套餐授权;后续管理同时读取现有套餐列表与 `GET /api/admin/shop-series-grants/{id}`,按 `package_id` 合并成同一批量选择视图,已授权项置灰、未授权项可多选。
|
||||
|
||||
保留现有批量写路径,但新增必填 `operation_type=authorize|update_cost|remove`。单次请求只能表达一种命令,并在一个事务内全成全败:`authorize` 只新增并支持同价幂等,不同价重复整批冲突;`update_cost` 只明确修改已授权套餐价格;`remove` 只明确移除授权。
|
||||
保留现有批量写路径和 `packages:[{package_id,cost_price,remove}]` 契约:`remove=true` 表示移除,未设置或为 `false` 时根据当前授权状态新增或改价。单次最多 100 项并在一个事务内全成全败;既有请求和响应结构必须继续可用。
|
||||
|
||||
## User Stories
|
||||
|
||||
1. 作为平台或上级代理,我希望一次选择多个系列套餐并授权给目标代理。
|
||||
2. 作为授权人员,我希望看到公司成本价、目标代理当前授权成本价和建议零售价,不再混淆单一 `cost_price` 的含义。
|
||||
3. 作为授权人员,我希望已经授权的套餐明确置灰,避免重复选择。
|
||||
4. 作为授权人员,我希望新增授权、调价和移除是三个明确动作,避免误操作。
|
||||
5. 作为并发操作人员,我希望重复同价授权安全幂等,不同价并发请求明确冲突而不是覆盖。
|
||||
4. 作为授权人员,我希望继续使用已交付的每项 `remove` 字段完成移除,避免发布后旧前端失效。
|
||||
5. 作为并发操作人员,我希望批量请求全成全败,并在价格或授权状态冲突时得到明确反馈。
|
||||
6. 作为上级代理,我只能把自己有权销售的套餐授权给直属下级,不能借候选或构造请求越权。
|
||||
7. 作为审计人员,我希望知道一次批量操作的命令、系列、目标代理、套餐及前后价格。
|
||||
7. 作为维护人员,我希望 OpenAPI 和前端契约准确记录 `remove` 字段,避免后续再次误删。
|
||||
|
||||
## Implementation Decisions
|
||||
|
||||
@@ -32,7 +32,7 @@ Status: ready-for-agent
|
||||
|
||||
- 复用 `tb_shop_series_allocation` 和 `tb_shop_package_allocation`,不新建授权关系表。
|
||||
- 系列授权记录是目标店铺获得该系列销售能力的入口;套餐授权记录保存目标店铺对具体套餐的成本价、零售价、状态和上下架状态。
|
||||
- 本需求不重建系列佣金、强充配置、套餐零售价或价格继承规则,也不新增候选 Query;只规范现有列表组合、首次批量授权和后续明确的批量套餐命令。
|
||||
- 本需求不重建系列佣金、强充配置、套餐零售价或价格继承规则,也不新增候选 Query;只规范现有列表组合、首次批量授权和兼容既有字段的后续批量管理。
|
||||
- 赠送套餐 `is_gift=true` 不属于代理授权候选,也不能通过构造请求加入。
|
||||
- 金额统一使用分,类型为 `int64`,禁止浮点金额。
|
||||
|
||||
@@ -58,33 +58,29 @@ Status: ready-for-agent
|
||||
|
||||
- 继续使用 `POST /api/admin/shop-series-grants`,在一个事务内创建 `ShopSeriesAllocation` 与请求中的多条 `ShopPackageAllocation`;不拆成两步,不允许留下无套餐的空系列授权。
|
||||
- `packages` 从当前可选字段收紧为必填,至少 1 项、最多 100 项;每项为 `package_id + cost_price`,同一请求内套餐 ID 必须唯一。
|
||||
- 首次授权中的套餐必须满足与后续 `authorize` 相同的系列、赠送、状态、上级授权、价格和权限规则;任一套餐失败则系列授权、全部套餐授权、价格历史和成功审计均不落库。
|
||||
- 首次授权中的套餐必须满足与后续新增授权相同的系列、赠送、状态、上级授权、价格和权限规则;任一套餐失败则系列授权、全部套餐授权和价格历史均不落库。
|
||||
- 首次授权不需要 `operation_type`,因为 `POST` 的业务语义已经唯一明确为“创建系列授权并首次授权套餐”;该接口不承担后续调价或移除。
|
||||
|
||||
### 批量写契约
|
||||
### 批量写兼容契约
|
||||
|
||||
- 保留 `PUT /api/admin/shop-series-grants/{id}/packages`,请求固定为:
|
||||
|
||||
```json
|
||||
{
|
||||
"operation_type": "authorize",
|
||||
"packages": [
|
||||
{"package_id": 1001, "cost_price": 6500},
|
||||
{"package_id": 1002, "cost_price": 7000}
|
||||
{"package_id": 1002, "cost_price": 7000},
|
||||
{"package_id": 1003, "remove": true}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- `operation_type` 是必填稳定枚举:
|
||||
- `authorize`:新增套餐授权。
|
||||
- `update_cost`:明确修改已有授权成本价。
|
||||
- `remove`:明确移除已有套餐授权。
|
||||
- `packages` 必填,最少 1 项;单次上限 100 项。同一请求中的 `package_id` 必须唯一,重复 ID 返回参数错误,不能以“最后一个覆盖前一个”处理。
|
||||
- `authorize` 和 `update_cost` 每项必须提供大于等于 0 的 `cost_price`;`remove` 只使用 `package_id`,如携带价格则拒绝,避免无效参数制造歧义。
|
||||
- 不再使用每项 `remove=true` 混合命令;旧模糊请求不得继续触发新增、改价或删除。
|
||||
- `operation_type` 缺失返回参数错误。该契约要求前后端同批发布,不提供会延续模糊语义的长期兼容层。
|
||||
- 每项 `remove=true` 时执行软删除;字段缺失或为 `false` 时必须提供大于等于 0 的 `cost_price`,未授权则新增,已授权则按现有规则更新价格。
|
||||
- `remove` 是已交付稳定字段,不得删除、改名或要求调用方改传必填顶层 `operation_type`。
|
||||
- 成功响应继续返回最新 `ShopSeriesGrantResponse`,不得强制旧前端适配新的结构化计数响应。
|
||||
|
||||
### `authorize` 规则
|
||||
### 新增授权规则
|
||||
|
||||
- 每个套餐必须未删除、属于当前系列且不是赠送套餐。套餐当前禁用或下架状态原样展示但不阻止授权,保持现有“可以先配置授权、销售时由可售策略拦截”的能力;本需求不把销售状态误当成授权状态。
|
||||
- 代理操作者必须拥有该套餐的有效授权;目标店铺必须仍满足现有直属下级和系列授权管理权限。
|
||||
@@ -93,7 +89,7 @@ Status: ready-for-agent
|
||||
- 目标代理已经存在有效授权但成本价不同:返回冲突,整批不做任何写入。不得借 `authorize` 静默改价。
|
||||
- 已软删除的旧授权是否允许按新授权恢复,应复用项目现有唯一索引和新建授权语义:创建新的有效记录或按明确恢复操作处理,但不能把旧价格静默带回;审计必须标明恢复来源。
|
||||
|
||||
### `update_cost` 规则
|
||||
### 更新成本价规则
|
||||
|
||||
- 每个套餐必须已经存在目标代理的当前有效授权;未授权项导致整批失败。
|
||||
- 新价格与当前价格相同时按幂等成功,不写重复价格历史。
|
||||
@@ -101,7 +97,7 @@ Status: ready-for-agent
|
||||
- 若目标代理已将该套餐继续授权给下级,沿用现有规则禁止修改成本价,返回“存在下级分配记录,请先回收后再修改成本价”;整批失败,不允许部分跳过。
|
||||
- 此命令是按套餐指定绝对目标成本价,与现有 `/shop-package-batch-pricing` 按店铺/系列整体固定或比例调价不同,二者不能互相冒充。
|
||||
|
||||
### `remove` 规则
|
||||
### `remove=true` 规则
|
||||
|
||||
- 每个套餐必须已经存在目标代理的当前有效授权;同一授权已不存在时按幂等成功,不重复写删除审计。
|
||||
- 若该套餐已经继续授权给下级、存在会被破坏的销售/授权不变量或项目现有回收前置条件,必须拒绝并要求先回收,不能留下下级拥有而上级无权的悬空链路。
|
||||
@@ -110,7 +106,7 @@ Status: ready-for-agent
|
||||
|
||||
### 事务、并发与幂等
|
||||
|
||||
- 批量命令是轻量 Application 事务脚本。Application 负责权限、命令解析、批量加载、规则校验、条件写入、价格历史和审计;不创建无业务行为的聚合根。
|
||||
- 批量管理是轻量 Application 事务脚本。Application 负责权限、逐项语义解析、批量加载、规则校验、条件写入和价格历史;不创建无业务行为的聚合根。
|
||||
- 一批请求在一个 PostgreSQL 事务内全成全败。必须先批量加载和校验所有套餐、目标授权及下级引用,再执行写入。
|
||||
- 数据库保留目标店铺与套餐的有效授权唯一约束;`authorize` 创建应使用条件写入/唯一冲突后的重新读取,正确区分同价幂等与不同价冲突。
|
||||
- 并发 `authorize` 同一批套餐时,一方成功后另一方重新核对当前价格;相同价格成功返回,不同价格冲突,不得将唯一约束错误暴露给客户端。
|
||||
@@ -126,23 +122,22 @@ Status: ready-for-agent
|
||||
|
||||
### 审计与响应
|
||||
|
||||
- 每次成功批量命令写统一 Audit Event,至少包含 `operation_type`、系列授权 ID、目标店铺、系列 ID、套餐 ID 列表、前后成本价、操作者和幂等项摘要。
|
||||
- 拒绝和冲突按公共失败审计规则记录;价格、账号等敏感信息遵循全局审计脱敏规则。
|
||||
- 成功响应返回最新授权详情或结构化结果,至少包括请求数、实际新增/更新/移除数、幂等数及相关套餐 ID;不得以“跳过”掩盖不同价格冲突。
|
||||
- Audit Event 已按七月总 Change 决策移出本期,本需求不新增审计 Writer;价格历史继续作为调价事实保存。
|
||||
- 成功响应保持已交付的最新授权详情结构,不引入破坏性响应变更。
|
||||
|
||||
### 前端交互
|
||||
|
||||
- 首次授权和后续管理复用同一个批量选择表格组件;数据来自现有套餐列表,后续管理再与现有授权详情按 `package_id` 合并。
|
||||
- 分列展示当前上级成本价、目标代理授权成本价、建议零售价;平台作为上级时当前上级成本就是公司成本。未授权成本价显示“-”,不能显示 0 元造成误解。
|
||||
- `is_authorized=true` 显示“已授权”并在新增授权模式置灰;切换到调价或移除模式时只允许选择已授权项。
|
||||
- 一个弹窗/提交只能处于授权、调价或移除一种模式,请求提交相应 `operation_type`。
|
||||
- 前端可以提供授权、调价或移除操作模式,但提交时继续组装既有套餐项:移除项设置 `remove=true`,新增或调价项提交 `cost_price`。
|
||||
- 提交前展示命令名称、目标代理、系列、套餐数量和价格摘要;提交期间禁止重复提交。
|
||||
- 并发不同价冲突时保留用户输入,提示刷新候选数据后重新确认,不能自动覆盖。
|
||||
|
||||
### 发布与回滚
|
||||
|
||||
- 不迁移、不回填现有授权数据。发布前核对同一店铺/套餐有效授权重复、孤立下级授权及价格历史异常。
|
||||
- 前后端同批切换必填 `operation_type`;旧前端流量应在发布窗口清空或阻断,不能让缺失命令类型的请求继续按旧逻辑执行。
|
||||
- 后端发布必须向后兼容现有前端请求,无需停机切换新命令字段;发布检查应确认 OpenAPI 仍包含 `packages[].remove`。
|
||||
- 回滚应用时保留新版本产生的授权、价格历史和审计;不得删除业务事实。
|
||||
|
||||
## Testing Decisions
|
||||
@@ -150,20 +145,19 @@ Status: ready-for-agent
|
||||
- 读取组合测试覆盖平台与代理视角的现有套餐列表、授权详情、系列过滤、分页、赠送套餐排除、禁用/下架存量项只读展示,以及不同视角下成本价字段的准确文案。
|
||||
- 字段权限测试验证无成本价查看权限的账号不能读取敏感价格,代理不能查询其他授权记录详情或借套餐列表扩大授权范围。
|
||||
- 首次创建测试覆盖套餐数组必填、多项同事务成功、重复 ID、跨系列、赠送、无上级授权、非法价格及任一项失败时系列授权也不落库。
|
||||
- `authorize` 测试覆盖多项成功、同价幂等、不同价冲突、同请求重复 ID、跨系列、赠送、禁用/下架、代理自身未授权和并发唯一冲突。
|
||||
- `update_cost` 测试覆盖未授权、同价幂等、成功调价、价格历史、存在下级分配时整批失败,以及绝对价格不会被误解成固定/比例调整。
|
||||
- `remove` 测试覆盖成功、已不存在幂等、存在下级授权拒绝和不影响客户历史订单/套餐使用。
|
||||
- 新增测试覆盖多项成功、重复请求、同请求重复 ID、跨系列、赠送、禁用/下架、代理自身未授权和并发唯一冲突。
|
||||
- 调价测试覆盖同价提交、成功调价、价格历史、存在下级分配时整批失败,以及绝对价格不会被误解成固定/比例调整。
|
||||
- `remove=true` 测试覆盖成功、已不存在幂等、存在下级授权拒绝和不影响客户历史订单/套餐使用,并验证缺失 `remove` 时不会误删。
|
||||
- 事务测试验证任一套餐失败时整批没有新增、改价、删除、价格历史或成功审计残留。
|
||||
- HTTP 集成测试穿过 Fiber 认证、Handler、Application/Query、GORM/PostgreSQL 和统一响应,验证必填枚举、错误码、分页与越权安全语义。
|
||||
- 前端验收覆盖首次与后续共用批量表格、两个现有读取接口的合并、已授权置灰、三种明确模式、批量摘要、空态、失败态和并发冲突刷新。
|
||||
- HTTP 集成测试穿过 Fiber 认证、Handler、Application/Query、GORM/PostgreSQL 和统一响应,验证 `remove` 字段、错误码、分页与越权安全语义。
|
||||
- 前端验收覆盖首次与后续共用批量表格、两个现有读取接口的合并、已授权置灰、`remove=true` 提交、空态、失败态和并发冲突刷新。
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- 不重建系列授权、套餐授权、佣金或强充模型。
|
||||
- 不新增 `package-options` 或其他重复的候选套餐读取接口。
|
||||
- 不允许创建没有任何套餐的空系列授权。
|
||||
- 不允许一个请求混合授权、调价和移除。
|
||||
- 不在 `authorize` 中修改已授权套餐价格。
|
||||
- 不删除或替换既有 `packages[].remove` 字段。
|
||||
- 不把赠送套餐授权给代理。
|
||||
- 不自动级联调整或回收下级代理授权。
|
||||
- 不修改存量客户订单、套餐使用记录或零售价配置。
|
||||
@@ -171,7 +165,7 @@ Status: ready-for-agent
|
||||
|
||||
## Further Notes
|
||||
|
||||
- 当前写接口已经接受 `packages:[{package_id,cost_price,remove}]`,并会在重复授权时直接改价;实现必须主动消除这段模糊语义。
|
||||
- 当前写接口已经接受 `packages:[{package_id,cost_price,remove}]`;这是已交付契约,实现和文档必须继续保留。
|
||||
- 仓库已有 `/shop-package-batch-pricing`,但它按整个店铺/系列进行固定或比例调整且允许逐项跳过,不能替代本需求按选中套餐设置绝对成本价、整批原子失败的 `update_cost`。
|
||||
- 用户已确认以必填 `operation_type` 将授权、调价和移除拆为明确命令,并接受前后端同批切换。
|
||||
- 用户已于 2026-07-24 明确纠正:`remove` 字段不应移除,必须恢复并保持兼容。
|
||||
- 用户纠正并确认:首次授权保持现有 `POST` 同时授权系列和套餐;后续添加套餐由 `PUT /{id}/packages` 负责;读取复用现有套餐列表和授权详情,不新增候选接口。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 02 — 后续套餐授权的原子命令契约
|
||||
# 02 — 后续套餐授权的原子兼容契约
|
||||
|
||||
**What to build:** 后续套餐管理接口以必填的操作类型明确区分新增授权、修改成本价和移除授权。每次请求只执行一种命令且整批原子:同价新增安全幂等、不同价新增明确冲突;调价和移除遇到下级授权等前置条件时整批拒绝。成功操作记录价格历史和审计,权限、并发和幂等行为不会泄露底层唯一约束错误。
|
||||
**What to build:** 后续套餐管理接口保留已交付的 `packages:[{package_id,cost_price,remove}]` 契约,以 `remove=true` 表示软删除,其他项按当前授权状态新增或改价。批量请求保持事务原子性,调价和移除遇到下级授权等前置条件时整批拒绝;成功调价记录价格历史,权限、并发和幂等行为不会泄露底层唯一约束错误。
|
||||
|
||||
**适用架构通道:** Application 事务脚本。完整业务边界为“系列授权下套餐授权的后续批量命令”,包括命令解析、批量加载、权限与业务校验、条件写入、价格历史及审计;不迁移现有整店/系列批量调价,不自动回收下级授权,也不修改订单、套餐使用或零售价。
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
|
||||
**Status:** ready-for-agent
|
||||
|
||||
- [ ] 后续管理请求必须携带 `authorize`、`update_cost` 或 `remove` 之一,套餐数量限制为 1 至 100 且 ID 唯一;旧的混合新增、改价、移除语义不再生效。
|
||||
- [ ] 三种命令均在一个 PostgreSQL 事务内完成批量校验与写入,正确处理权限、赠送套餐、跨系列、绝对成本价、下级依赖、同价幂等及不同价冲突。
|
||||
- [ ] 集成测试覆盖并发新增、全量回滚、价格历史、审计、错误码和越权安全语义,并验证响应包含实际操作数、幂等数与相关套餐标识。
|
||||
- [ ] 后续管理请求继续接受 `packages[].remove`,套餐数量限制为 1 至 100 且 ID 唯一;不得要求必填顶层 `operation_type`,不得改变既有响应结构。
|
||||
- [ ] 新增、改价和 `remove=true` 软删除均在一个 PostgreSQL 事务内完成校验与写入,正确处理权限、赠送套餐、跨系列、绝对成本价和下级依赖。
|
||||
- [ ] 集成测试覆盖 `remove` 兼容、并发新增、全量回滚、价格历史、错误码和越权安全语义。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 03 — 后续授权管理批量界面与发布验收
|
||||
|
||||
**What to build:** 授权人员在同一批量表格中管理既有系列授权:套餐列表与授权详情按套餐标识合并,已授权项在新增模式置灰,授权详情独有的存量项仍只读展示;调价和移除只允许选择已授权套餐。界面提交明确命令,提供批量摘要、空态、失败态及并发冲突后的刷新提示,并具备可安全发布和回滚的验收材料。
|
||||
**What to build:** 授权人员在同一批量表格中管理既有系列授权:套餐列表与授权详情按套餐标识合并,已授权项在新增模式置灰,授权详情独有的存量项仍只读展示;调价和移除只允许选择已授权套餐。界面继续使用 `packages[].remove` 提交移除,提供空态、失败态及并发冲突后的刷新提示,并具备可安全发布和回滚的验收材料。
|
||||
|
||||
**适用架构通道:** 主通道为 Query 与前端;辅助通道为 Application API 集成。完整业务边界为“后续授权管理的读取组合、命令交互与上线验收”;不新增候选读取接口,不扩大现有数据或价格字段权限,不重构未触碰的套餐列表。
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
**Status:** ready-for-agent
|
||||
|
||||
- [ ] 后续管理页面并行复用现有套餐列表和授权详情,准确展示三类价格、授权状态及受权限变化影响的存量只读项。
|
||||
- [ ] 新增、调价、移除三种模式只提交对应命令;提交期间防重,冲突时保留输入并要求刷新确认,且响应与失败状态对用户清晰可见。
|
||||
- [ ] 完成 Fiber 到 PostgreSQL 的端到端验收、前后端同批切换核查、上线前数据异常核查和保留业务事实的回滚说明。
|
||||
- [ ] 新增、调价、移除模式继续组装既有套餐项,移除项设置 `remove=true`;提交期间防重,冲突时保留输入并要求刷新确认。
|
||||
- [ ] 完成 Fiber 到 PostgreSQL 的端到端验收、`remove` 契约兼容核查、上线前数据异常核查和保留业务事实的回滚说明。
|
||||
|
||||
Reference in New Issue
Block a user