# 检查与真实业务验收

## 统一检查 {#check}

```bash
pnpm openxiangda check --json
```

CI、离线开发或尚未发布的候选包使用 `pnpm openxiangda check --local --json`，MCP 对应 `check_app.local=true`。它仍执行完整纯规则、生成、静态检查、测试与构建，但不请求平台；结果明确为 `validationScope: local`，不能证明现场权限、密钥和模型兼容。默认 check 仍预检目标，正式 deploy 始终执行现场预检，不提供跳过参数。

默认目标为测试环境。CLI 与 MCP `check_app` 使用同一执行器：先在本地完成配置和完整契约校验，再核对目标平台的校验实现与只读环境条件，随后生成文件、执行静态检查、测试和构建。明确检查生产目标时指定 `--environment production`。

结果中的 AppSpec/lifecycle 单独列出需求与设计缺口；普通 check 可以继续验证尚未完成的实现。正式测试发布前核对总纲、关联变更、权限、性能预算和 AC 计划，测试部署之后再执行真实角色验收。生产晋级按 [AppSpec 报告](./appspec.md)核对指定测试版本的实际结果。

用户明确延期的性能项使用报告的 `performanceDeferral`，记录实际授权与后续安排并保留原超标样本。结果明确区分功能通过与性能延期；不补造测量，不放宽功能 AC。

本地与平台使用同一份纯校验规则，并核对实现摘要和配置投影摘要。必需登录提供方、目标环境的密钥可用性、已有模型的物理字段约束和应用管理权限会在构建前检查；预检不读取密钥明文、不创建物理表、不修改环境。现场变化仍由平台在真正执行时复核。

检查会写本地生成结果并按需初始化后端，不是只读操作。前置阶段失败后，下游阶段标为 skipped，不继续构建或上传。保留错误码、pointer、details 和下一步，修正原因后重试。

每次检查都直接执行当前工作区声明的 check/test/build 脚本；构建工具和包管理器可以自行使用缓存。目标平台的权限、密钥和模型条件仍在正式检查和部署前预检。Devkit 不维护额外的工作区摘要凭据，也不会因为分支、提交或文档变化引入候选复用分支。

成功检查返回 `sealedArtifact.state: check-did-not-seal`、`sealed: false`、`usableForDeploy: false`。旧 AppPackage 不是当前检查结果。要发布测试环境可直接运行 deploy，它已包含完整检查；不要连续重复执行 check、test 和 build。

## 按变化范围验收 {#acceptance}

应用测试归当前项目维护。模板不限制页面数量、源文件数、总行数、业务类名或登录布局；初始模板与通用组件的模拟响应回归由工具链发行门禁维护。类型、声明、构建制品和实际运行性能仍需按各自规则验证，源码行数不能替代性能测量。

Web 默认保留开发服务回环访问检查。按需 Nest 使用 `tsx --test` 发现项目中的业务测试；没有用例时只有零项测试，不能当成业务已验收。浏览器目录 `apps/web/e2e/` 起初只有编写说明，添加本应用的 `*.spec.ts` 后运行 `pnpm test:e2e`；真实角色验收绑定 AppSpec 和指定测试版本。

修改资源时验证声明、实际交付端的字段语义及受影响的新增、详情、修改、删除、筛选、导出和版本冲突。按实际设计的目标设备验证交互；存在移动办理任务时验证对应移动页面，不受历史后台 PC 约定限制。用允许角色验证成功，用禁止角色验证页面、操作、行和字段边界；存储值及审计应符合声明。平台内部的数据库和性能回归由平台维护者负责，应用不重复搭建平台数据库测试。

应用入口或导航变更必须从平台应用列表实际点击进入，再验证应用根路径、登录返回和刷新后的深链接。使用后台的应用检查 `/admin` 进入首个有权菜单、自定义页只出现一个 Shell、菜单切换与未保存保护、无权限拒绝；纯用户应用验证其声明首页，不强制增加后台。直达开发者给出的 `/home` 或报表链接通过，不能替代平台实际入口验收。

平台浏览器入口有两个：`/view/<应用标识>/...` 是正式环境入口，`/dev/<应用标识>/...` 是预发（测试环境）入口，路径中的应用标识即 `app.code`。测试部署通过后从 `/dev/<应用标识>` 做浏览器验收；生产晋级后用 `/view/<应用标识>` 复核。`/dev` 入口要求已登录平台账号（应用内数据和功能仍按应用角色权限控制），未部署的环境返回明确的 503 页面，响应头 `X-OpenXiangda-Environment` 标识当前环境。本地 `pnpm openxiangda dev` 的回环地址只用于开发迭代，不能替代这两个平台入口的验收。

只改文案时验证受影响页面。复杂事务、并发和值转换使用聚焦测试。浏览器验收实际操作并检查错误，不能用模拟响应或空页面加载代替真实角色验收。

应用后端生成 Native 事务或 BusinessProcess 数据守卫时，业务测试通过统一根包的公开测试入口校验真实生成的请求，不复制验证规则或额外依赖底层包：

```ts
import { SCHEMA_VERSIONS, validateDataTransactionRequest } from 'openxiangda/testing';

const diagnostics = validateDataTransactionRequest({
  schemaVersion: SCHEMA_VERSIONS.dataTransactionRequest,
  idempotencyKey: submission.idempotencyKey,
  guards: submission.data.guards,
  operations: submission.data.operations.map(item => ({
    operation: item.kind, resourceCode: item.resourceCode, data: item.data,
  })),
});
```

合法请求返回空诊断数组；守卫失败码必须使用 `OPENXIANGDA_*`。纯合同校验不证明数据库锁、权限、实际执行或失败恢复通过，这些仍需要对应角色和原操作的运行验收。

匿名访问另验证续填、上传、校验、幂等提交、own.list/own.read；另一浏览器应无法获取前一浏览器的记录。工作流按已启用功能检查发起、处理、历史详情和消息跳转，不为未启用通道增加测试负担。

## 可选临时身份 {#temporary-identities}

需要平台协助创建真实测试身份时，使用短期本地计划：

```json
{
  "schemaVersion": "openxiangda.preproduction-acceptance-plan/v2",
  "environmentKey": "preproduction",
  "expiresInMinutes": 240,
  "actors": [
    { "key": "allowed", "roleCodes": ["resource_admin"] },
    { "key": "denied", "roleCodes": ["resource_viewer"] }
  ]
}
```

```bash
pnpm openxiangda accept --plan .openxiangda/acceptance-plan.json --json
```

示例角色需替换为应用实际角色。计划和返回的一次性登录链接不提交仓库。accept 不自动部署，也不是 check/deploy 的必填步骤；未运行应明确注明。

## 记录结果 {#evidence}

记录源码/包版本、AppVersion、环境、角色、预期及实际结果、必要请求标识。区分本地检查、分发安装、部署激活与业务验收。某项未执行时说明原因，不将其写成通过。

## 复制请求诊断 {#request-diagnostics}

标准浏览器请求错误保留服务端 requestId，文件导出及权限读取重试耗尽也使用同一错误类型。自定义页面通过公开入口读取固定格式诊断：

```ts
import { platformRequestDiagnostic } from 'openxiangda/react';

function supportDetails(error: unknown) {
  const diagnostic = platformRequestDiagnostic(error);
  return diagnostic ? JSON.stringify(diagnostic, null, 2) : null;
}
```

将这段结果放入当前操作的错误详情，附应用版本和原 operationId/DeploymentRun；不要复制 Cookie、令牌、完整请求正文或原始响应。诊断包含错误码、请求路径（无 query）、方法、站点内应用/环境、观测时间和合法 requestId。网络未收到响应时 requestId 为 null，不能编造关联标识。该信息不等于提交结果：写入未知时查询原操作，保留原键与原输入；不要自动换键再写。Nest SDK 的平台错误已有 `request` 上下文，平台管理仍通过授权范围内的日志/支持通道检索。

## 并发执行

同一工作区的公共 check 和测试 deploy 共享本地互斥锁，前一个命令结束后才能启动下一个。出现 WORKSPACE_OPERATION_BUSY 时等待当前进程完成；异常退出时先确认锁中进程已经退出，再移除提示中的锁文件。锁只保护工具执行，不阻止编辑器修改源码；检查和部署期间应暂停其他写入。平台部署状态仍以 status/logs 为准。
