Files
story/docs/integration-diagnostics.md
T

24 KiB
Raw Permalink Blame History

集成诊断工作台开发说明

对应接口契约:OpenAPI 0.55.0
适用角色:ops_viewer、ops_operator、ops_approver、ops_admin
适用阶段:模拟联调、真机联调、试点运行和生产故障处置

1. 建设目标与安全边界

集成诊断工作台用于把设备、通话、RTC房间、供应商任务和接口请求关联到同一条脱敏诊断记录,减少联调时在多个数据库表和日志系统之间人工拼接信息的成本。查询始终使用已经验证的OIDC身份和明确的X-Tenant-Id,服务端先解析运营账号与客户组织关系,再固定租户条件执行查询。

工作台不返回字幕正文、录音地址、RTC短期令牌、设备签名密钥、供应商API Key、Outbox正文或配置密钥内容。ops_viewer和ops_approver只能查询;ops_operator可执行配置刷新、安全停止、状态对账、死信重试和诊断包导出;设备吊销仅允许ops_admin执行。所有修改动作必须填写原因、提供幂等键,并记录操作人、请求关联编号、资源和结果。

字幕正文和原录音不属于诊断查询返回。需要排查内容问题时,必须转入运营敏感数据临时访问流程,按单次通话申请最小能力、由另一人审批并逐次审计。

2. 功能设计

2.0 外部依赖预检

API和Worker按配置周期检查OIDC JWKS、方舟HTTPS入口及火山RTC HTTPS入口。OIDC检查要求响应成功、JSON可解析且至少包含一把签名密钥;方舟和RTC只执行DNS、TCP及证书校验TLS握手,不发送模型或语音业务请求,不消耗额度。V35把每个进程和依赖的最近结果写入平台级状态台账,字段包括最近检查、最近成功/失败、耗时、探针周期、连续失败和有限错误码。台账不保存实际端点、证书正文、原始网络错误或任何凭据。

联调页面把超过三倍探针周期未更新的记录显示为“结果过期”,即使其最后状态为成功也不能作为当前可用证据。进程启动时删除本进程已停用依赖的旧记录,避免从方舟或RTC切回本地实现后继续展示历史探针。探针失败不会让健康API或Worker退出就绪状态,但会进入Prometheus和告警规则,便于区分“平台自身不可用”和“外部联调条件未满足”。

2.1 精确检索

检索字段 输入 主要关联路径 返回信息
device_id 设备公开UUID device → conversation → rtc_task 设备状态、在线状态、固件/配置版本及相关通话
conversation_id 通话公开UUID conversation → device/rtc_task/provider_event 通话状态、预留期限、房间及供应商任务状态
room_id RTC房间编号 rtc_task → conversation → device 对应通话、设备和供应商任务
provider_task_ref 供应商任务编号 rtc_task → conversation → device 供应商、任务状态、启动/停止尝试次数
request_id 接口请求关联编号 audit_event → resource → conversation/device 该请求涉及的脱敏资源状态

查询只支持完整值匹配,不提供字幕、姓名、手机号等个人数据的模糊检索。单次最多返回50条,设备检索可返回该设备的多条历史通话,其余唯一业务编号通常只返回一条。

2.2 状态展示

每条记录包含以下诊断字段:

  • 设备公开编号、注册/吊销状态、Redis在线状态、固件版本、期望/已应用配置版本和最近归一化错误码;
  • 通话公开编号、通话状态、房间资料有效期;
  • 短期入房凭证签发时间和过期时间,不返回凭证正文、摘要或可重建凭证的签名材料;
  • RTC房间编号、供应商代号、稳定任务编号、任务状态、启动和停止尝试次数;
  • 已接收供应商通知数量、最近通知类型与时间;
  • 最近一次相关请求编号。

存在通话时,接口同时从conversation.created_at/ended_at和conversation_state_history的首次状态到达时间计算五类耗时:创建至ROOM_ISSUED、房间资料签发至设备确认STARTING_AGENT、设备确认至供应商ACTIVE、STOPPING至最终结束,以及创建至最终结束。尚未到达的阶段返回空值,时间倒置的数据不生成负数;页面以毫秒、秒或分秒展示,不使用浏览器请求时间代替业务阶段耗时。

2.3 授权修复动作

动作 允许状态 处理结果
配置刷新 设备属于选定客户组织 以当前期望版本创建幂等apply_config设备命令
状态对账 STARTING_AGENT或STOPPING 分别创建启动/停止对账Outbox任务;稳定状态返回queued=false
安全停止 PREPARING/ROOM_ISSUED 不调用供应商,直接收敛为EXPIRED并释放房间
安全停止 STARTING_AGENT/ACTIVE 收敛为STOPPING并可靠投递供应商停止任务
安全停止 STOPPING或最终状态 幂等返回当前状态,不重复创建副作用
设备吊销 设备属于选定客户组织 写入吊销时间并立即阻断后续设备签名请求;若存在未结束通话,则在同一事务内过期或可靠停止
死信重试 状态为dead且事件类型已注册 重置为pending,保留并递增人工重试次数、操作人和时间;未知事件类型拒绝重试
诊断包导出 五类精确检索条件有效 生成ops-diagnostic-minimal-v1脱敏JSON快照,不写正文副本
发布候选验收快照 候选版本、SHA-256构建摘要、环境、范围和必需依赖明确 在单个事务内冻结迁移、依赖、问题、任务和告警门禁,生成ops-acceptance-minimal-v1归档JSON
试点运行日报 业务日期、IANA时区和归档原因有效 聚合六类运行证据并生成ops-pilot-daily-minimal-v1脱敏JSON,不在服务端保存正文
试点运行周报 周一业务日期、IANA时区和归档原因有效 聚合内容审核、记忆、隐私、固件和配置差异,并明确要求外部投诉证据

配置刷新、状态对账、安全停止和设备吊销均从具体诊断结果卡片打开页面内“受控联调操作”确认区,不再通过浏览器弹窗采集原因。确认区固定展示目标设备;状态对账和安全停止还固定展示目标通话,切换客户组织或重新检索会清除旧操作草稿。操作原因必填、最长500字符,空理由不能提交。安全停止与设备吊销还必须勾选对应影响确认,其中设备吊销明确提示后续签名请求将被拒绝,安全停止明确限定为当前通话。取消只清空页面草稿,不调用修改接口。角色、租户、状态、幂等和审计仍由服务端重新校验,前端确认不能替代服务端门禁。

诊断包导出和死信重试同样使用页面内表单。导出表单在打开时冻结检索字段和精确编号,展示中文字段名称、完整目标值、脱敏边界和审计提示;用户随后修改检索框不会改变已经打开的导出目标,重新执行查询则清除旧导出草稿。死信重试表单冻结任务公开编号、注册事件类型、聚合类型、自动/人工尝试次数和最近稳定错误码,并要求填写最长500字符的原因,再勾选“根因或依赖问题已经处理”的影响确认。刷新任务列表、切换客户组织或取消会清除旧任务草稿。页面不展示Outbox正文、内部聚合编号或锁信息。

2.4 死信作业摘要

死信列表最多返回100条,只展示作业公开编号、已注册事件类型、聚合类型、自动尝试次数、人工重试次数、稳定错误码和时间。接口不返回Outbox正文、内部聚合编号或锁持有者。人工重试会重新启用一轮自动重试预算,但不清除人工重试历史;若根因未修复,任务仍会按显式重试分类再次进入退避或死信。

2.5 联调问题闭环

问题清单按客户组织保存需求P0282规定的可追踪字段:问题现象、严重级别、设备编号、通话编号、发生时间、请求关联编号、责任方、根因、解决结果、修复版本、回归证据和回归结论。设备、通话和请求编号均为诊断引用;记录不得粘贴字幕正文、录音地址、短期凭证、长期密钥或带签名下载地址。设备和通话编号同时填写时,服务端验证二者属于同一关联链,避免建立错误关联。

问题状态为OPEN → IN_PROGRESS → RESOLVED → VERIFIED → CLOSED,严重级别为LOW/MEDIUM/HIGH/CRITICAL。重新处理时可以回到IN_PROGRESS;进入RESOLVED及后续状态必须填写解决结果、根因和修复版本,进入VERIFIED或CLOSED还必须填写回归结论和脱敏回归证据。V36汇总当前客户组织全部问题,而不是只统计页面最近100条;任何未关闭的HIGH或CRITICAL问题均计入高严重度发布阻断。该布尔结果只证明此项门禁,不替代供应商、真机、安全、恢复和合规门禁。创建请求使用幂等键,后续维护使用强ETag,防止两名联调人员静默覆盖彼此结论。只读运营角色可以查看,ops_operator和ops_admin可以登记和维护,每次写入均记录独立审计。

问题维护不再使用连续浏览器弹窗,而是从具体问题卡片打开统一的页面内流转编辑区。编辑区固定问题公开编号、当前状态、当前责任方、现象和ETag版本,再根据动作只显示当前必需字段:调整级别要求选择不同值;接手或重新打开要求最长120字符的责任方;登记解决同时要求根因、最长128字符的修复版本及解决结果;登记回归同时要求脱敏回归证据和结论;关闭要求显式确认已经复核根因、修复版本、解决结果和回归证据。正文类字段最长4000字符。切换筛选、刷新清单、切换客户组织或取消会清除草稿;并发更新仍由服务端If-Match校验,冲突时保留页面输入和错误提示供人工复核。

背景资料准备失败是无需供应商对账的本地终态。精确查询该通话时,诊断记录返回conversation_status=FAILED和conversation_failure_code=context_preparation_failed,RTC状态、房间和供应商任务均为空;工作台与设备HTTP 422响应使用同一个失败码,联调人员可直接登记问题,不得把空RTC任务误判为任务丢失。

2.6 发布候选验收快照

验收快照用于阶段8每次真实联调、试点扩量或生产发布前的技术状态冻结。操作人必须填写候选版本、sha256:构建摘要、LAB/STAGING/PRODUCTION环境、验收类型、覆盖范围、必需外部依赖和最长255字符的归档原因。服务端在一个数据库事务内读取当前迁移版本及脏状态、当前客户组织的联调问题全量汇总、租户及平台级Outbox积压、未解决HIGH/CRITICAL告警,以及所选外部依赖的最新探针状态。

六项门禁分别为候选构建可识别、数据库迁移清洁、必需依赖当前可用、无未关闭高严重度联调问题、无待处理/处理中/死信可靠任务、无未解决高严重度告警。探针记录超过三倍探针周期即视为过期;缺少记录不能按成功处理。实验室环境允许运行版本为dev,便于本地准备;预发布和生产环境要求运行版本等于候选版本,同时提交号和构建时间不能为unknown。overall_gate_satisfied是六项技术条件的合取结果,不包含真机音频体验、真实供应商协议、灰度观察、容量、安全、合规或人工审批,快照正文固定携带该免责声明。

OpenAPI 0.51.0在告警计数之外加入最多100条阻断告警定位项,只包含告警公开编号、规则码、级别、处置状态、关联资源类型/公开编号、首次/最近命中时间和资源核对结果。PRESENT表示关联资源仍存在,MISSING表示快照时已找不到关联公开资源,AGGREGATE表示队列类聚合告警,UNKNOWN表示该资源类型没有自动存在性判断。该字段不返回告警标题、摘要、接收组或原始错误;MISSING只能作为运营复核证据,不能自动关闭告警。总数超过100时blocking_items_truncated=true,必须转到告警工作台查看完整队列。

快照不建立服务端历史表,返回后由浏览器下载归档。页面同时保留本次响应,直接展示六项门禁和阻断告警定位,切换客户组织时立即清除,避免把上一组织的结果误作当前状态。幂等记录保证网络重试返回同一编号与生成时间;审计只保存候选标识、环境、范围、所选依赖、结果和脱敏策略。输出不包含探针地址、凭据、原始错误、告警正文、Outbox正文、字幕或录音。

2.7 试点运行日报

OpenAPI 0.55.0要求日报绑定候选版本与不可变构建摘要,再按指定IANA时区的自然日生成设备、通话、供应商、上传、告警和费用快照。自然日活动和生成时刻积压采用不同字段,通话始终返回8个状态,费用按币种分列且不做汇率换算。日报只保存幂等和审计元数据,不保存服务端正文;详细口径、接口和数据来源见试点运行日报开发说明。

2.8 试点运行周报

OpenAPI 0.55.0要求周报绑定候选版本与不可变构建摘要,再按周一开始的七个业务自然日生成内容审核、正式记忆、隐私请求、固件分布和配置差异快照。人工修订率和故事确认率同时返回样本数及可计算标识;没有分母时不能解释为0%。平台没有投诉权威表,因此周报固定保留外部投诉证据缺口。详细设计见试点运行周报开发说明。

3. 接口设计

所有接口要求Authorization: Bearer ...和X-Tenant-Id。修改接口还要求Idempotency-Key,请求体为{"reason":"..."}。

方法与路径 最低角色 说明
GET /api/v1/ops/diagnostics/search?field={field}&value={value} ops_viewer 按五类字段精确查询脱敏状态
GET /api/v1/ops/diagnostics/external-dependencies ops_viewer 查询API/Worker外部依赖预检台账
POST /api/v1/ops/diagnostics/conversations/{id}/stop ops_operator 按当前状态执行本地收敛或可靠停止
POST /api/v1/ops/diagnostics/conversations/{id}/reconcile ops_operator 对启动/停止中间态创建幂等对账任务
POST /api/v1/ops/diagnostics/devices/{id}/config-refresh ops_operator 创建当前配置重新应用命令
GET /api/v1/ops/diagnostics/jobs ops_viewer 查询当前客户组织的脱敏死信摘要
POST /api/v1/ops/diagnostics/jobs/{id}/retry ops_operator 对已注册类型的死信作业执行受控重试
POST /api/v1/ops/diagnostics/bundles ops_operator 按精确检索条件生成脱敏JSON诊断包
POST /api/v1/ops/diagnostics/acceptance-snapshots ops_operator 幂等生成并下载发布候选技术验收快照
POST /api/v1/ops/diagnostics/pilot-daily-snapshots ops_operator 按业务自然日幂等生成并下载脱敏试点运行日报
POST /api/v1/ops/diagnostics/pilot-weekly-snapshots ops_operator 按周一开始的业务自然周幂等生成并下载脱敏试点运行周报
POST /api/v1/ops/diagnostics/devices/{id}/revoke ops_admin 吊销设备,并联动收敛该设备未结束通话
GET /api/v1/ops/integration-issues ops_viewer 查询最近100条问题及全量高严重度发布阻断汇总,可按状态筛选
POST /api/v1/ops/integration-issues ops_operator 幂等登记问题现象、严重级别、关联编号、发生时间和责任方
PATCH /api/v1/ops/integration-issues/{id} ops_operator 使用If-Match维护严重级别、责任方、根因、修复版本和回归证据

成功响应返回动作、最新状态、是否排队和相关命令编号。跨客户组织、只读角色或不存在资源不会泄露其他租户信息;响应统一带Cache-Control: no-store。稳定错误包括OPS_ACCESS_DENIED、DIAGNOSTIC_NOT_FOUND、DIAGNOSTIC_STATE_CONFLICT和IDEMPOTENCY_KEY_CONFLICT。

4. 业务流程设计

4.1 联调定位流程

sequenceDiagram
    participant O as 联调/运营人员
    participant API as 诊断API
    participant DB as PostgreSQL
    participant R as Redis
    O->>API: OIDC令牌 + 客户组织 + 精确编号
    API->>DB: 校验运营账号与租户关系
    API->>DB: 查询设备/通话/RTC任务/通知/审计
    API->>R: 查询设备在线状态
    API-->>O: 返回脱敏统一诊断记录
    O->>API: 选择修复动作并填写原因、幂等键
    API->>DB: 锁定资源并检查当前状态
    API->>DB: 写状态/命令/Outbox与审计
    API-->>O: 返回最新状态、是否排队和请求编号

4.2 安全停止流程

系统先锁定目标通话并重新读取权威状态。尚未启动供应商任务时,只执行本地过期收敛;供应商任务可能存在时,事务内把通话置为STOPPING并写可靠停止任务;已在停止或最终状态时直接幂等返回。这样可避免运营页面重复点击产生第二个供应商任务。

4.3 状态对账流程

只有启动中和停止中状态需要向后台恢复链路排队。任务使用通话内部编号和操作幂等键形成去重边界,Worker继续遵守固定供应商任务编号、未知启动先查询、停止不受启动熔断影响等规则。稳定状态不伪造对账任务。

4.4 设备吊销流程

系统先锁定设备,再锁定该设备唯一未结束通话。设备状态、revoked_at和版本号在事务内更新;PREPARING/ROOM_ISSUED通话直接进入EXPIRED且RTC任务进入COMPLETED,STARTING_AGENT/ACTIVE通话进入STOPPING并写入可靠停止任务,已经STOPPING则不重复投递。状态历史、吊销审计和停止意图与设备吊销一起提交,避免出现“身份已失效但云端任务继续运行”的分裂状态。

4.5 死信恢复与诊断包流程

运营人员先根据稳定错误码修复依赖,再选择死信任务、填写原因并提交。服务端锁定任务,确认租户、dead状态和已注册类型后重置待执行字段并记录人工重试元数据。诊断包则复用同一套精确查询和租户边界,把当前脱敏状态序列化为JSON;导出编号、条件、条数和脱敏策略进入审计,但服务端不建立新的内容副本。

4.6 联调问题处理流程

联调人员先通过精确诊断检索确认设备、通话和请求关联编号,可从诊断结果一键带入三个编号,再补充问题现象、严重级别和责任方。责任方接手后把状态置为处理中,完成修复后填写根因、修复版本和解决结果并置为待回归;回归人员按可复现步骤验证,登记请求关联号、诊断包编号、重复次数等脱敏证据和结论,最后关闭问题。若回归失败或问题复现,记录回到处理中,原解决结果、回归证据和审计历史继续保留。HIGH或CRITICAL问题在关闭前持续阻断对应发布门禁。服务端通过版本条件更新保证并发修改可见,不以最后写入者静默覆盖前一人的结论。

4.7 发布候选技术预检流程

运营人员先冻结候选版本和构建摘要,再按本次联调或发布范围选择真实必需依赖。API完成角色和客户组织校验后,在幂等事务中依次读取迁移、问题、探针、可靠任务和告警状态,计算六项独立门禁及总结果,同时写入最小审计。浏览器下载JSON后交由阶段8证据库归档;任一门禁失败时以gates中的稳定代码定位处理项,修复后使用新的幂等键重新生成,不修改旧快照。技术门禁全部通过后仍需继续执行真实设备、供应商、灰度和人工审批清单。

5. 数据库设计

诊断模块不建立正文副本或独立影子库,复用以下权威表:

表 用途
device、device_twin、device_presence_state 设备身份、吊销时间、固件、期望/已应用配置和在线状态
conversation、conversation_state_history 通话权威状态和状态变更依据
rtc_task、provider_event RTC房间、短期凭证签发/过期时间、供应商稳定任务编号、尝试次数及通知摘要;V28只新增凭证时间元数据
device_command 配置刷新命令及设备回执
outbox_event 启动/停止对账和可靠停止任务;V26增加公开编号、人工重试次数、时间和操作人
audit_event 操作人、原因、请求编号、资源和结果
idempotency_record 修改动作的重放、并发和正文冲突保护
integration_issue V30联调问题权威记录;V36增加严重级别、根因、修复版本、脱敏回归证据和高严重度汇总索引
external_dependency_probe_state V35平台级探针当前状态、周期、时间、有限错误码和连续失败次数;不保存端点或凭据
schema_migrations、alert_incident 验收快照读取迁移脏状态和未解决HIGH/CRITICAL告警;不复制告警正文
upload_batch、media_segment、conversation_usage_event、conversation_cost_line 试点日报读取上传活动/积压与按币种费用,不建立日报副本

查询所有连接条件同时包含或继承客户组织边界;HTTP只暴露公开UUID。运营修改在同一数据库事务内完成状态、可靠任务和审计写入,任一步失败则整体回滚。验收快照和试点日/周报复用权威表及idempotency_record/audit_event,OpenAPI 0.50.0—0.55.0不新增数据库迁移或快照持久化表。

6. 验证

pwsh -NoProfile -File .\scripts\smoke-diagnostics.ps1
pwsh -NoProfile -File .\scripts\smoke-acceptance-snapshot.ps1
powershell -ExecutionPolicy Bypass -File .\scripts\smoke-pilot-daily-snapshot.ps1
powershell -ExecutionPolicy Bypass -File .\scripts\smoke-pilot-weekly-snapshot.ps1

烟测使用真实本地OIDC令牌和设备HMAC签名,验证五类查询、跨租户403、稳定状态对账、配置刷新、安全停止、死信重试、脱敏诊断包、设备吊销、请求编号回查和精确数据清理。联调问题采用定向数据库与HTTP验证,覆盖创建重放、租户隔离、严重级别阻断、根因/修复版本/回归证据门禁、关闭后汇总恢复和旧ETag冲突。服务集成测试另覆盖活动通话随设备吊销进入STOPPING并只投递一个停止任务。生产验收仍需使用真实设备、真实供应商账号和实际值班角色重复执行。

日常页面可用性采用一条轻量真实OIDC冒烟:test/e2e/visual-ops-sensitive-access-request.mjs创建临时通话诊断记录、已注册类型的临时死信任务及覆盖五种状态的临时问题记录,依次打开诊断包导出、配置刷新、状态对账、安全停止、设备吊销、死信重试、六种问题流转和敏感访问申请表单,验证目标绑定、字段门禁、ETag展示、危险操作显式确认、取消关闭以及零修改/导出请求。检查要求零横向溢出、零控制台错误和零失败请求,并在finally精确清理夹具。该检查不实际下载诊断包、修改问题、重试任务、停止通话或吊销种子设备,服务端副作用仍由上述HTTP与集成测试证明。

外部预检日常验证只运行V35迁移、internal/externalprobe定向用例和真实OIDC纵向查询。页面检查使用:

$env:PLAYWRIGHT_REQUIRE_FROM='C:\Users\19926\.cache\codex-runtimes\codex-primary-runtime\dependencies\node\node_modules'
$env:CHROME_PATH='C:\Program Files\Google\Chrome\Application\chrome.exe'
node .\scripts\visual-diagnostics-ui.cjs

该检查确认本地Keycloak的api/oidc_jwks为当前可用、服务归属和检查时间可见、接口无端点或原始错误字段;同时使用真实登录从页面下载实验室验收快照和试点运行日/周报,核对门禁、固定分布、统计守恒、外部投诉证据缺口与归档JSON后精确清理审计/幂等夹具,并保存test/e2e/screenshots/operations/ops-diagnostics-workspace.png。本地未配置方舟、火山RTC或托管内容安全时不生成对应成功记录;真实联调或生产快照必须把实际使用的方舟、RTC和content_safety_tls列为必需依赖。