计划:修正测试批次实施前置契约

This commit is contained in:
焦龙言
2026-09-22 13:39:18 +08:00
parent 9da9cd0a59
commit 40c56c6b33
@@ -339,7 +339,7 @@ git commit --only shierfeng-fastapi-backend/module_business/entity/do/test_batch
**Interfaces:**
- Consumes: `BizTestBatch`、`BizTestBatchUser`、`CurrentUserModel`、请求头 `X-Test-Batch-Id`。
- Produces: `TestBatchScope(batch_id, mode, status, writable)`、`TestBatchScopeDependency(write: bool = False)`、`TestBatchAccessService.assert_super_admin(current_user: CurrentUserModel) -> None`、`lock_active_batch(db: AsyncSession, scope: TestBatchScope) -> BizTestBatch | None`。
- Error contract: 不合法头返回 `ServiceWarning('测试批次标识必须为正整数')`;未授权或状态失效返回 `PermissionException(data={'reason': 'TEST_BATCH_UNAVAILABLE'}, message='当前测试批次不可用')`。
- Error contract: 不合法头返回 `ServiceWarning('测试批次标识必须为正整数')`;未授权或批次已清理返回 `PermissionException(data={'reason': 'TEST_BATCH_UNAVAILABLE'}, message='当前测试批次不可用')`;写请求命中已关闭批次时返回同一 `reason` 与明确文案 `当前测试批次已关闭`。
- Test fixtures: `make_current_user(user_id=7, permissions=None)`、`make_admin()`、`make_test_scope(batch_id, status='ACTIVE', writable=True)` 供后续测试统一使用。
- [ ] **Step 1: 写上下文解析与越权失败测试**
@@ -368,15 +368,24 @@ class TestBatchAccessTest(unittest.IsolatedAsyncioTestCase):
`test_batch_fixtures.py` 提供统一构造器:
```python
def make_current_user(user_id: int = 7, permissions: list[str] | None = None) -> CurrentUserModel:
def make_current_user(
user_id: int = 7,
permissions: list[str] | None = None,
*,
admin: bool = False,
) -> CurrentUserModel:
return CurrentUserModel(
permissions=permissions or [],
roles=[],
user=UserInfoModel(userId=user_id, userName='admin' if user_id == 1 else f'user-{user_id}'),
user=UserInfoModel(
userId=user_id,
userName='admin' if user_id == 1 else f'user-{user_id}',
admin=admin,
),
)
def make_admin() -> CurrentUserModel:
return make_current_user(1, ['*:*:*'])
return make_current_user(1, ['*:*:*'], admin=True)
def make_test_scope(batch_id: int, status: str = 'ACTIVE', writable: bool = True) -> TestBatchScope:
return TestBatchScope(batch_id=batch_id, mode='TEST', status=TestBatchStatus(status), writable=writable)
@@ -1753,7 +1762,7 @@ git commit --only shierfeng-fastapi-frontend/src/api/system/testBatch.js \
**Interfaces:**
- Consumes: Tasks 3、7、8 的批次 service,Task 4/5 的旧 DELETE 固定拒绝,Task 10 的批次管理和纳入入口。
- Produces: SQL 菜单只保留批次清理权限;Web 无物理删除按钮/调用;旧 DELETE 路由改用对应页面 `:list` 权限后返回统一业务拒绝。
- Produces: SQL 菜单移除八个旧删除权限并新增八个批次管理权限;Web 无物理删除按钮/调用;旧 DELETE 路由改用对应页面 `:list` 权限后返回统一业务拒绝。
- Exact contract: 13 个 controller、86 条目标路由、85 条 interface-auth 依赖、61 个唯一权限、18 个页面权限、43 个按钮权限、41 条写路由。
- [ ] **Step 1: 先更新精确权限与无删除入口失败契约**
@@ -2054,13 +2063,14 @@ git commit --only shierfeng-fastapi-app/src/api/system/testBatch.js \
```text
1. 备份并在隔离实例完成恢复演练;恢复校验失败则停止。
2. 只读盘点目标库 18 张业务表、16 个批次字段、索引、外键和 on_delete;任一差异则停止。
3. 在 staging 应用对应方言补丁,既有 test_batch_id 非 NULL 行数必须为 0。
4. 发布后端、Web、PDA;保持 TEST_BATCH_ONLINE_PURGE_MAX_ROWS=0。
5. 验证正式模式列表、扫码、首页和六报表与发布前基线一致。
6. 用 staging 数据分别压测 100、500、1000、逐级增加的闭包,记录锁等待、事务耗时和回滚耗时。
7. 取满足运维窗口和数据库锁等待预算的最大实测行数,配置正整数上限并重启后端。
8. 首次创建批次、首次纳入旧数据和首次清理分别走独立变更审批。
2. 只读盘点目标库现有业务表、索引和外键,并确认即将新增的 2 张批次表及 16 个 `test_batch_id` 字段尚不存在;结构与补丁前置不符则停止。
3. 在 staging 应用对应方言补丁,验证 18 张业务表、16 个批次字段、索引、外键和 `on_delete`,且既有 `test_batch_id` 非 `NULL` 行数必须为 0。
4. 在已审批维护窗口内先对目标库应用同一补丁,立即重复结构和既有数据校验;任一检查失败则停止应用发布并按数据库变更回退预案处理。
5. 发布后端、Web、PDA;保持 `TEST_BATCH_ONLINE_PURGE_MAX_ROWS=0`。
6. 验证正式模式列表、扫码、首页和六报表与发布前基线一致。
7. 用 staging 数据分别压测 100、500、1000、逐级增加的闭包,记录锁等待、事务耗时和回滚耗时。
8. 取满足运维窗口和数据库锁等待预算的最大实测行数,配置正整数上限并重启后端。
9. 首次创建批次、首次纳入旧数据和首次清理分别走独立变更审批。
```
手册给出 MySQL `information_schema` 与 PostgreSQL `pg_catalog` 的只读查询,用于核对字段、索引、外键和删除规则;给出清理失败后的检查项,禁止手工补删半条链。