# g1_sipgl 正式开发基线

本文保存正式开发的推进原则、技术路线、回归分层、环境门禁和完成定义。面向业务方逐条查看的 Scenario 说明、操作步骤和验收标准放在常驻 HTML 工作台：

- 公网入口：`http://tokyo.gainit.cn/sipgl/local-docs/development-baseline/`
- 本地文件：`local-docs/development-baseline/index.html`
- 业务口径来源：`scenarios/scenario_catalog.html`

## 已确认决策

1. 正式开发按 Scenario 的实际业务顺序推进：关封出口、入库报关、进口分拨、统一装箱出运、公共能力。
2. 移动端正式采用现有 Vue 3、TypeScript、Vite 和 Capacitor Android 技术路线。当前 mock 页面按 Scenario 逐步切换为真实 G1 OpenAPI，不另起嵌入 G1 的移动端路线。
3. 2026-08-19 定性：`G26000308` 半撤销事件是领域过程未遵循 G1 存储过程失败契约（`return_type='01'` + 结果集 `result=1` 才判定失败）导致的配置问题，修复在 `g1_sipgl` 侧；基盘仍保留的独立缺陷只有旧链路动作执行顺序（PRE 结果检查晚于工作流推进），由 G1 基盘项目解决。`g1_sipgl` 不修改基盘源码，但相关 Scenario 必须保留“PRE 失败不得推进状态”的自动回归和发布门禁。

## 开发顺序

当前 Scenario Catalog 包含 85 条写入型 Scenario：

| 阶段 | 主线 | 数量 | 渠道分布 |
|---|---|---:|---|
| 1 | 关封出口 | 21 | PC/后台 8，移动端 13 |
| 2 | 入库报关 | 21 | PC/后台 7，移动端 14 |
| 3 | 进口分拨 | 22 | PC/后台 12，手机端/小程序 10 |
| 4 | 统一装箱出运 | 16 | PC/后台 7，移动端 7，混合 2 |
| 5 | 公共能力 | 10 | PC/后台 9，移动端 1 |

交付和验收必须遵循上述顺序。技术前置、公共组件和共用领域过程可以在首次需要时建设，但不得改变业务验收顺序，也不得为不同业务主线复制语义不一致的同类过程。

## 纵向业务切片

开发单位不是单独的 PC 页面、移动页面或存储过程，而是一条可以验收的纵向业务切片：

1. 从真实角色可见的菜单、表单、按钮或移动工作台进入。
2. 调用具备状态校验、权限、幂等、事务和失败协议的领域动作。
3. 完成 PC/移动端交互和 G1 OpenAPI 契约。
4. 写入正确的业务状态、库存、费用、报文、派生对象和审计记录。
5. 自动测试通过后加入永久回归集合。

每个交付包建议包含 1～5 条连续且强相关的 Scenario，避免跨越多个业务阶段形成大批量半成品。

## 第一阶段：关封出口

| 泊位 | Scenario 范围 | 交付闭环 |
|---|---|---|
| A | `SIPGL-GF-ORD-001`～`005` | PC 草稿、提交、时间修改、业务维护、送货通知单 |
| B | `SIPGL-GF-INB-001`～`002` | PC 受理、移动端叫下一车、指定库门 |
| C | `SIPGL-GF-INB-003`～`014` | 卸货、协助、测量、做关、库位、残损、桩脚牌、复核和异常冻结 |
| D | `SIPGL-GF-FEE-*`、`SIPGL-GF-MSG-*` | 最终计费、收费开票放行、监管数据补发 |

每个泊位完成时都必须能独立演示并生成自动化证据；阶段结束时形成一条 PC 建单 → PC 受理 → 移动端现场作业 → PC 收费/监管的黄金业务链。

## 自动回归分层

### 已登记 Scenario 脚本

| Scenario | 脚本 | 当前状态 | 写入与清理 |
|---|---|---|---|
| `SIPGL-GF-ORD-001` 保存关封进仓计划草稿 | `scripts/regression/SIPGL-GF-ORD-001.js` | 已关联验收台并接通安全执行器；最短路径 14/14、全量路径 16/16 通过 | 支持 `smoke/full` 覆盖模式和 `isolated/journey` 数据生命周期；与第二步共用 fixture，并在链尾验证八类对象零残留 |
| `SIPGL-GF-ORD-002` 提交关封单票货 | `scripts/regression/SIPGL-GF-ORD-002.js` | 已关联验收台；最短路径 13/13、全量路径 15/15 通过 | 单独执行时自动构造第一步前置草稿；业务链模式消费第一步同一 ID，结束后统一清理业务对象、作业、事件和费用 |
| `SIPGL-GF-ORD-003` 修改进仓计划时间 | `scripts/regression/SIPGL-GF-ORD-003.js` | 已关联验收台；最短路径 12/12、全量路径 14/14 通过 | 单独执行时自动构造第一、二步前置数据；业务链模式更新同一 ID，生成计划更改费和事件，链尾统一清理八类对象 |
| `SIPGL-GF-ORD-004` 业务端维护并受理 | `scripts/regression/SIPGL-GF-ORD-004.js` | 已关联验收台并通过真实业务菜单进入 | 沿用前三步 fixture，验证业务维护、成本、费用作废、客户隔离和业务受理 |
| `SIPGL-GF-ORD-005` 打印送货通知单 | `scripts/regression/SIPGL-GF-ORD-005.js` | 已关联验收台并验证旧系统三页 PDF | 打印不新增业务状态；保留打印履历并向第六步交付同一 fixture |
| `SIPGL-GF-INB-001` 受理关封送货车辆 | `scripts/regression/SIPGL-GF-INB-001.js` | 已关联验收台并从仓库真实菜单进入 | 验证车辆到场、新现场 Job、完整三任务链、排队和幂等；全量模式验证撤销旧 Job/全部 Task 后重新受理生成新编号，链尾统一清理十类对象 |

### 覆盖模式与数据生命周期

这两个维度独立选择：

- `smoke`（最短路径）：执行真实入口、两页签填写、保存、重新打开、核心字段和完整关系链断言。
- `full`（全量回归）：在最短路径上增加错误输入校验、草稿修改再保存和数据库读回。
- `isolated`（单步隔离）：每个 Scenario 结束后立即精确清理，适合提交级回归。
- `journey`（业务链串联）：同一 run 使用共享 fixture manifest；前一步产出的业务 ID 保留给后续 Step，全部 Step 完成或失败后统一精确清理。

覆盖模式决定“测多少”，数据生命周期决定“何时清理”。不得用 `--keep-data` 代替正式业务链 fixture；串联数据必须由 runner 统一托管和收尾。

### 数据 Pattern 与分支覆盖

第一期把“步骤”和“测试数据形态”拆成两个独立维度。关封出口当前登记两个流程级 Pattern：

- `GF_NO_LOOSE`：大包装 2 托、散货 0；手机端跳过做关，货主标签与桩脚牌按大包装数量生成。
- `GF_WITH_LOOSE`：大包装 2 托、散货 8 件；货主标签固定 1 张，手机端必须做关，后续库位、桩脚牌和复核按做关明细推进。

验收台顶部选择 Pattern 后，当前步骤的 fixture、分支模式（`COMMON / EXECUTE / BYPASS`）、附加断言、后台准备和回归请求保持一致；人工勾选及最近通过记录按 Pattern 隔离。步骤×Pattern 覆盖矩阵用于识别需要执行、共享或跳过的移动端分支，不以复制 Scenario 的方式表达数据差异。

### 纯后台步骤准备

人工测试可以在常驻验收台点击“新建测试单并完成到当前步骤”。这套能力与自动回归相互独立：

- 六个已开发步骤分别登记 `scripts/backend-automation/<Scenario ID>.js`；公共编排器为 `prepare-to-step.js`。
- 关封出口后台准备接受 `--pattern GF_NO_LOOSE|GF_WITH_LOOSE`，fixture manifest 固化 `patternId`；切换 Pattern 会先按原 `prep_id` 精确清理旧测试单，再创建新单，禁止在同一 fixture 上改换货型。
- 选择第 N 步时，在后台按实际业务顺序完成第 1～N 步，并保留同一张业务主单、票货、开票快照、车辆预约、仓库作业、费用和事件，用户可以直接检查第 N 步完成态或继续测试后续步骤。
- 每次点击“新建测试单并完成到当前步骤”都会创建新的 `prep_id` 和正式测试编号，从第 1 步重新推进；不会复用上一张成功或失败的同流程测试单。
- 新建同流程测试单前，执行器按旧 `prep_id + external_order_no/marks` 所有权精确清理上一张验收台 fixture 并验证零残留，避免测试数据累积；其他业务流暂存的 fixture 保持原有隔离策略。
- 主单使用 `f_next_bus_id('SUPERVISED')` 正式编号，票货沿用进仓编号；提交、改期和仓库受理调用领域过程，业务受理及仓库受理调用真实 `workflow.do`，打印先生成正式报表再登记成功履历。
- 后台准备结果只说明 fixture 状态和关系完整，不更新 `automationStatus`、`lastPassedRun` 或任何验收结论。
- 测试数据不会在每一步后自动清理；清理只按 `prep_id + external_order_no/marks` 所有权校验删除，并逐表验证零残留。

### L0 静态质量门禁

- SQL、CustomHTML、JavaScript 语法检查。
- TypeScript 类型检查和移动端构建。
- 配置对象、字段、字典、权限和接口注册完整性。

### L1 领域过程与数据库集成测试

每个写入过程至少覆盖：

- 正常状态流转。
- 前置状态不满足时拒绝。
- 重复点击和幂等。
- 旧 `stateVersion`、并发或状态竞争。
- 权限和数据范围。
- 事务失败后原状态不变。
- 派生对象、库存、费用、报文、状态事件和审计记录。

手机端现场节点额外执行统一 Task 权威门禁：每个节点必须同时覆盖“待XX可开始、XX中/暂停可恢复、已完成不可重入、前序未完成不可越级”。扫码过程、开始过程和前端路由必须使用同一状态矩阵；Job 只作聚合门禁，Cargo 只作库存硬阻断，Vehicle 只约束卸车/拆箱现场入口。当前自动入口为 `scripts/verify-20260824_warehouse_task_authority.sql` 与 `npm --prefix mobile-app run test:stage-state`。

### L2 OpenAPI 契约测试

- 登录和认证。
- 请求参数和参数缺失。
- 权限与角色。
- JSON 返回结构和错误码。
- 幂等键。
- PC 和移动端复用同一领域动作时的语义一致性。

### L3 PC＋移动端业务流程测试

- PC 必须从真实 G1 菜单进入，不绕过权限和菜单路径。
- 移动端业务流程使用手机视口运行，和 PC 共享同一批业务数据。
- 页面断言之外必须检查数据库最终事实。
- 关键黄金流程串联多个角色和终端。

### L4 Android 壳冒烟

只覆盖 Capacitor 壳特有能力：安装升级、登录态、扫码/相机、照片上传、打印和断网恢复。普通业务逻辑不在 APK 层重复全部 Web 用例。

## 变更影响分析

Scenario 实施矩阵需要持续记录：

- Scenario ID、顺序、角色和渠道。
- 表单、菜单、裁剪视图、工作流和权限。
- `p_` 过程、OpenAPI 和返回契约。
- 读写的数据表、字典和状态。
- 测试数据工厂、自动测试 ID 和套件。
- 开发、联调、候选、完成和回归状态。

发生修改后按以下顺序选择回归：

1. 识别被修改的基盘、表单、过程、API、表、字典或工作流。
2. 反查直接和间接引用它的 Scenario。
3. 加入建立当前状态所需的上游步骤。
4. 加入验证修改未破坏后续状态的关键下游步骤。
5. 公共对象变更至少运行一条已经完成的黄金业务链。
6. 报告必须说明每个 Case 被选中的原因。

## 执行节奏

| 触发时机 | 执行范围 | 放行规则 |
|---|---|---|
| 每次提交 | L0、本次 Scenario 的 L1/L2、反向依赖选测 | 全部通过 |
| Candidate | 新增用例、当前业务切片、已完成上游 | 候选通过后才晋级正式套件 |
| Nightly | 所有已完成 Scenario、至少一条完整黄金链 | 失败保留首现场；重试只用于诊断 |
| 发布前 | G1 平台通用回归、SIPGL 业务回归、Android 冒烟 | 三者同时通过 |

## Scenario 完成定义

一条 Scenario 只有同时满足以下条件，才可以标记为完成：

- 业务口径、角色、前置条件和验收标准已确认。
- PC 或移动端真实入口可操作，不依赖 fixture 或 mock。
- 领域过程具备状态校验、幂等、权限、事务和审计。
- 正常、拒绝、重复提交至少三类自动测试通过。
- 同时断言页面结果和数据库事实。
- 反向依赖选中的既有 Scenario 回归全部通过。
- Scenario、配置档案、操作记录和 changelog 已同步。
- Candidate 通过并晋级正式套件。

## Sprint 0 门禁

已完成：

- 正式开发基线发布到常驻文档服务。
- Scenario 主清单作为 85 条验收内容的数据源。
- Vue 3＋Capacitor 确认为正式移动端路线。
- 半撤销事件已定性为配置问题（领域过程失败契约），PRE 旧链路时序缺陷归属 G1 基盘项目，SIPGL 保留回归门禁。

待落实：

- 建立隔离的写入型回归环境并明确写入授权。
- 后续建立隔离回归环境时配置独立客户测试账号；当前过渡 runner 使用现有 `codex_customer_ui/customer` 专用账号、客户 `C001`、唯一 `run_id`、测试前缀和精确 ID 清理，凭据只存放在 Shanghai root 的 `600` 权限文件。
- 在当前单 Case candidate runner 基础上建立 nightly/release-before 套件。

## 回归环境安全边界

当前 debug、dev、prod 共享数据库，不能长期承载全量写入回归。现为首批六个 Scenario 启用过渡期白名单写入 runner 和后台步骤准备器；扩大覆盖前应建立隔离数据源或独立回归环境。

过渡期如果必须在共享环境验证，只允许：

- 使用专用账号、客户、仓库和明确测试前缀。
- 每次执行生成唯一 `run_id`。
- 所有测试数据能按 `run_id` 反查。
- 清理过程严格校验 domain、对象和测试前缀。
- 失败时仍执行受限清理并保留失败现场。
- 禁止无范围删除、表结构重建和影响真实业务状态的测试。

## 开发业务数据重置

正式开发期间需要周期性清空演示和回归数据时，统一使用 `scripts/reset-development-data.sh`，不要手写无范围 `DELETE` 或逐个重放历史 seed 的清理段。

```bash
# 只读预览；默认模式
scripts/reset-development-data.sh --dry-run --operator <执行人>

# 自动备份后执行
scripts/reset-development-data.sh --execute \
  --confirm RESET_G1_SIPGL_DEVELOPMENT_DATA \
  --operator <执行人>
```

固定边界：

- 清空 `g1_sipgl` 中全部 `t_*` 业务运行表；新建正式业务流水表应继续使用 `t_*` 命名。
- 清理 `g1_config` 中严格限定 `domain_id='g1_sipgl'` 的审批实例、消息、删除记录和运行日志。
- 保留 `m_*` 主数据/业务配置、`p_*` 参数模板、`z_*` 备份对象、G1 配置、编号计数器、用户和用户偏好。
- 执行入口会先备份到 `exports/development-data-reset/<时间戳>/`；支持的正式入口是包装脚本，不应绕过备份直接调用底层过程。
- 执行前必须确认没有 Scenario runner、后台数据准备或人工写入正在进行；过程使用互斥锁阻止两个重置任务并发。

## HTML 一键回归接口约定

常驻 HTML 通过 `local-docs/development-baseline/regression-registry.json` 读取自动化状态。每条 Scenario 的业务回归脚本接入时，在注册表中增加用例信息，并由受认证的内部 runner 提供执行接口。

HTML 不接收 shell、SQL、脚本路径或任意命令。当前过渡 runner 采用 Nginx 授权来源白名单、HTTP Origin 同源校验、服务端硬编码 Case/命令白名单和单任务互斥锁；后续正式 runner 仍须满足：

- 只接受注册表中的 Case ID，不接受任意命令文本或文件路径。
- 具备用户认证、CSRF/重放保护和权限检查。
- 同一套件使用互斥锁，避免并发写测试数据。
- 记录环境、版本、用户、run_id、开始/结束时间和结果。
- 返回步骤、断言、截图、trace、数据库差异和清理结果。
- 数据库写入严格限定测试环境和 `domain_id='g1_sipgl'`。

建议接口：

```text
GET  /api/scenario-regression/status
POST /api/scenario-regression/run
POST /api/scenario-regression/cancel
GET  /api/scenario-regression/status?runId=<run_id>
```

取消接口只接受当前活动的 `run_id`。收到请求后状态进入 `CANCELLING`，不再启动下一条 Scenario；当前 Scenario 仍执行自身精确清理，完成后状态为 `CANCELLED` 并释放互斥锁。不得通过重启验收台服务或直接强杀远程进程代替该入口。

`POST` 请求只传受控标识：

```json
{
  "scope": "SCENARIO",
  "scenarioIds": ["SIPGL-GF-ORD-001"],
  "target": "regression",
  "suite": "candidate"
}
```

`SIPGL-GF-ORD-001/002/003` 已接通安全 runner；未登记的 Scenario 仍不会执行。三步强制使用 `customer` 角色账号真实登录，依次覆盖客户门户草稿保存、提交及修改计划时间，不使用管理员账号或直接请求新增表单旁路。每个关键动作先等待目标控件可见、加载遮罩消失、网络趋稳和有限动画结束，再保留默认 900ms 可视停顿。Runner 流式返回真实浏览器截图，HTML 以大尺寸取证面板展示轨迹、当前/历史画面、断言和失败原因；正文“查看本步骤最近通过画面”按当前 Scenario 的 `lastPassedRun` 打开，runner 通过后自动回写 registry。最终 `full + journey` run `20260808-024816-a8efe837` 三步分别 16/16、15/15、14/14，通过后八类对象零残留。
