Files
2026-07-29 12:20:12 +08:00

14 KiB
Raw Blame History

ADDED Requirements

Requirement: 平台提供只读外部集成调查中心

系统 MUST 为已认证的平台账号提供只读 Integration Log 调查能力,平台账号不应用店铺或企业数据范围过滤,第一阶段不设置细粒度权限码;代理、企业和个人客户 MUST NOT 访问该调查能力。所有成功响应 MUST 使用统一 {code, msg, data, timestamp} 格式。

Scenario: 平台账号访问调查中心

  • WHEN 已认证的平台账号查询 Integration Log 总览、列表或详情
  • THEN 系统返回平台范围内符合查询条件的完整业务摘要,且不应用店铺或企业数据范围过滤

Scenario: 非平台主体尝试访问

  • WHEN 代理、企业或个人客户直接请求平台 Integration Log 调查接口
  • THEN 系统统一拒绝访问,且不泄露目标记录是否存在

Requirement: 外部交互异常总览

系统 MUST 提供受时间范围约束的 Integration Log 总览至少返回交互总数、结果分布、提供方分布、入站与出站分布、异常数量、结果未知数量、陈旧待处理数量、本地状态变化数量、平均耗时、P95 耗时和按时间分桶的趋势。总览 MUST 区分实际成功、结果未知、明确失败、处理中和未发送终态,不得把 completedignoredmergedrate_limitedcancelled 计为外部请求成功。

Scenario: 查询指定时间范围总览

  • WHEN 平台账号提交合法的开始时间、结束时间和时间粒度
  • THEN 系统在该时间范围内返回固定结构的汇总、分类计数和趋势数据,并为每个稳定结果编码返回中文名称及派生类别

Scenario: 区分未发送终态与成功

  • WHEN 时间范围内同时存在 successcompletedmergedrate_limited 记录
  • THEN 系统仅把 success 计入实际成功,并把其余记录计入对应的未发送或提前完成分类

Requirement: Integration Log 组合筛选列表

系统 MUST 提供按创建时间和主键稳定倒序的分页列表,支持组合筛选 integration_id、provider、direction、operation、原始 result 或派生结果类别、external_id、resource_type 与 resource_id、resource_type 与 resource_key、trigger_source、trigger_scene、trigger_series、state_changed、http_status、provider_code、request_id、correlation_id 和创建时间范围。筛选条件 MUST 使用精确匹配或受控枚举,不得提供任意 SQL、任意 JSONPath 或任意 JSONB 字段搜索。

Scenario: 组合查询外部失败记录

  • WHEN 平台账号同时指定 provider、operation、失败派生类别、资源和时间范围
  • THEN 系统仅返回同时满足全部条件的记录,并为列表项返回稳定编码、中文名称、主要资源、结果、耗时、状态变化、请求标识、关联标识和发生时间

Scenario: 查询结果为空

  • WHEN 合法筛选条件没有命中任何记录
  • THEN 系统返回成功的空分页结果,而不是资源不存在错误

Scenario: 拒绝无界或非法筛选

  • WHEN 查询时间范围、页码、每页数量或枚举值超过接口约束
  • THEN 系统返回统一参数错误,且不执行无界全表查询

Requirement: 使用稳定 integration_id 查询结构化详情

系统 MUST 使用业务稳定的 integration_id 而非数据库自增 ID 定位单条详情,并按 identity、resource、trigger、result、content、linkage、timestamps 和 attempts 分区返回结构化 DTO。详情 MUST 包含可用的请求摘要、响应摘要、metadata、正文安全摘要、HTTP 状态、渠道结果码、可读安全结果摘要、耗时、本地状态变化、人工核对说明、request_id、correlation_id 和关联 Audit Event ID。

Scenario: 查询单条外部交互详情

  • WHEN 平台账号使用存在的 integration_id 查询详情
  • THEN 系统返回该记录的结构化详情及 provider、direction、operation、result 的稳定编码和中文名称,不要求前端解析数据库 Model 或任意 JSON 才能识别基础语义

Scenario: 稳定标识不存在

  • WHEN 平台账号使用不存在的 integration_id 查询详情
  • THEN 系统返回统一资源不存在错误,且不回退使用数据库自增 ID 猜测记录

Requirement: Integration Log 查询入参必须有明确来源

总览的时间范围、粒度及聚合筛选和列表的组合筛选 SHALL 来自调查人员输入、通知目标或其他调查视角携带的稳定值provider、direction、operation、result 等枚举选项 MUST 来自后端稳定常量。详情 integration_id MUST 来自 Integration 列表、通知目标或事件/request/correlation 时间线节点,也 MAY 由调查人员粘贴稳定 Integration ID系统 MUST NOT 使用数据库自增 ID、相似资源或相近时间猜测目标记录。

Scenario: 从列表打开详情

  • WHEN 调查人员选择 Integration 列表中的一条记录
  • THEN 前端使用列表返回的稳定 integration_id 请求详情
  • AND 后端不要求前端提供数据库主键或重复提供资源条件

Scenario: 从其他调查视角跳转

  • WHEN 事件、request 或 correlation 时间线节点关联一条外部交互
  • THEN 节点返回可跳转的稳定 integration_id,前端据此打开详情

Scenario: 查询身份来自认证上下文

  • WHEN 调用方请求 Integration Log 总览、列表或详情
  • THEN Handler 从认证上下文判断其是否为平台身份
  • AND 不接受 query、path 或 body 传入平台、店铺或企业范围

Scenario: 从通知目标打开 Integration 详情

  • WHEN GET /api/admin/notifications/{id}/target 返回 available=truetarget_type=integration_log 和非空 target_key
  • THEN 前端将 target_key 原样作为 integration_id 调用 Integration 详情
  • AND 不直接解析通知列表的 ref_type/ref_id/ref_key 或按资源与时间重新搜索

Scenario: 通知目标不可用

  • WHEN 通知目标解析返回 available=false 或缺少 target_key
  • THEN 前端只展示通知正文,不显示 Integration 详情跳转

Requirement: 尝试序列只使用显式技术序列

系统 MUST 仅在记录具有相同非空 trigger_series 时将其组织为同一技术尝试序列,并按 attempt、发生时间和主键稳定排序。可重试或分阶段外呼的新接入 MUST 写入稳定 trigger_series 和单调递增的 attempt缺少 trigger_series 的历史记录 MUST 作为单次交互展示,系统不得仅因 provider、operation、资源或时间接近而猜测其属于同一重试序列。

Scenario: 展示显式尝试序列

  • WHEN 用户查询的记录带有 trigger_series,且存在同序列的多个尝试
  • THEN 详情按 attempt 和时间返回完整尝试序列,并逐条保留是否发送、结果、耗时和状态变化

Scenario: 历史记录缺少序列标识

  • WHEN 用户查询的历史记录没有 trigger_series
  • THEN 系统只返回当前单次交互,不把相同资源或相同 operation 的相邻记录拼成重试序列

Requirement: 业务关联链路与技术重试保持不同语义

系统 MUST 将 correlation_id 解释为跨请求、异步任务、外部交互和业务事实的业务链路标识,将 trigger_series + attempt 解释为一次外部操作的技术尝试序列。按 correlation_id 查询时 MUST 返回相关外部交互节点,但 MUST NOT 将这些节点统一标记为重试;跨 Audit Event、Outbox、Asynq 和 Domain Ledger 的完整时间线由统一审计调查 Query 组合Integration Log Query 只提供外部交互节点。

Scenario: 同一业务链路包含不同外部操作

  • WHEN 同一 correlation_id 下存在预下单、回调和查单等不同 operation
  • THEN 系统按业务发生时间展示相关交互并保留各自 operation不把回调或查单描述为预下单重试

Scenario: 同时存在业务链路和尝试序列

  • WHEN 一条业务链路中的某个 operation 具有多个显式 trigger_series 尝试
  • THEN 系统既保留 correlation_id 的业务链路关系,也在该 operation 内单独展示技术尝试序列

Requirement: 调查中心不承担恢复和导出

Integration Log 调查接口 MUST 只有读取能力。第一阶段 MUST NOT 提供重试、补偿、结果确认、外部单号绑定、人工恢复、状态修改、记录删除或导出接口。recovery_strategy 仅作为人工核对说明展示,不得被解释为可执行命令。

Scenario: 查看结果未知记录

  • WHEN 平台账号查看 result 为 unknown 的详情
  • THEN 系统展示已记录的人工核对说明,但响应中不包含恢复动作地址、可执行命令或写操作按钮契约

Scenario: 尝试调用恢复或导出能力

  • WHEN 调用方尝试通过审计中心执行 Integration Log 恢复、修改、删除或导出
  • THEN 系统不存在对应业务路由或统一拒绝请求,且原 Integration Log 不发生变化

Requirement: 安全凭据不得进入或离开 Integration Log

平台可以查看 Integration Log 中已经安全筛选的完整业务摘要但密码、操作密码、验证码、Access Token、Refresh Token、Secret、私钥、回调 Token、EncodingAESKey、Authorization、Cookie、签名 URL、支付密钥、完整加密回调正文和其他系统安全凭据 MUST 在写入前删除,查询接口 MUST NOT 返回这些内容。原始第三方错误正文 MUST NOT 直接进入 provider_message调用方必须提供有界、可读且不含凭据的业务结果摘要。

Scenario: 请求摘要包含业务字段和安全凭据

  • WHEN 外部调用摘要同时包含普通业务字段和系统安全凭据
  • THEN 系统保留普通业务字段并在持久化前删除安全凭据,详情接口只返回持久化后的安全摘要

Scenario: 入站回调包含完整正文

  • WHEN 系统接收运营商、支付或企业微信回调
  • THEN Integration Log 只保存受控业务摘要、正文大小和安全 hash不通过调查接口返回完整原始或解密正文

Requirement: 历史 Integration Log 缺口必须显式兼容

系统 MUST 保留并查询现有 Integration Log不在线伪造回填缺失的 trigger_series、correlation_id、资源 ID 或可读 provider_message。查询 DTO MUST 对无法可靠解析的历史字段返回明确的数据完整性标识;对使用现有确定性 ICCID hash 保存 resource_key 的运营商历史记录,资源查询 MUST 支持按相同受控算法定位,但 MUST NOT 向调用方暴露 hash 作为业务标识。已保存为不可逆摘要的 provider_message MUST 原样标识为历史摘要,不得生成虚假的可读原文。历史 request_summary/response_summary/metadata MUST 在响应前按字段白名单和统一凭据删除规则再次清理MUST NOT 直接透传旧 JSON。

Scenario: 查询只有 ICCID hash 的历史运营商记录

  • WHEN 平台账号使用合法 ICCID 查询资源外部交互轨迹,且历史记录只保存确定性 ICCID hash
  • THEN 系统使用受控兼容规则命中该记录,并把资源解析状态标记为历史兼容,不把 hash 返回为 ICCID

Scenario: 历史链路字段缺失

  • WHEN 历史记录缺少 correlation_id、trigger_series 或可靠资源 ID
  • THEN 系统仍返回现有事实并标明对应关联能力受限,不猜测链路、重试次数或资源关系

Scenario: 历史 JSON 含有未覆盖的安全凭据

  • WHEN 历史 Integration Log 摘要含有 Token、Secret、Authorization、Cookie、签名 URL 或其他禁止字段
  • THEN Query 在返回前删除禁止字段并保留其余完整业务摘要
  • AND 不直接序列化历史 JSON 到响应

Requirement: Integration Log 查询必须分页并命中受控索引

列表 MUST 默认每页 20 条、最大 100 条,并要求受控时间范围;总览 MUST 限定时间范围和固定聚合维度。实现 MUST 使用创建时间、结果、provider、external_id、资源、trigger_series、request_id、correlation_id 和 audit_event_id 的受控索引完成主要查询,不得逐条补查产生 N+1不得为第一阶段的摘要展示增加任意 JSONB GIN 搜索。

Scenario: 查询高频轮询历史

  • WHEN 平台账号查询包含大量 Gateway 高频记录的合法时间窗口
  • THEN 系统使用分页和匹配的时间或筛选索引返回结果,单页查询不加载窗口外全部记录,也不逐条查询关联基础信息

Scenario: 深分页或超大时间窗口

  • WHEN 调用方请求超过允许范围的页码、每页数量或时间窗口
  • THEN 系统返回统一参数错误,引导调用方缩小时间窗口,而不是执行高成本扫描

Requirement: Integration 调查只覆盖在线留存窗口

Integration overview、列表、详情和关联时间线 MUST 仅查询 PostgreSQL 在线数据,列表和总览 DTO MUST 返回 retention{online_from, archived_before, timezone}。月初清理后的上月记录只保留在对象存储,第一阶段 MUST NOT 提供归档下载、对象存储扫描、冷热联合查询或恢复能力。显式时间范围早于或跨越 online_from 时 MUST 返回稳定的已归档错误,不能返回成功空结果或部分结果。

Scenario: 查询已归档的外部交互月份

  • WHEN 平台账号查询的 Integration 时间范围全部早于 online_from
  • THEN 系统返回数据已归档和当前在线窗口
  • AND 不执行 PostgreSQL 无效扫描或对象存储查询

Scenario: 当前月份外部交互调查

  • WHEN 查询范围完全位于在线窗口
  • THEN 系统返回符合条件的 Integration Log 与 retention 元数据
  • AND 详情和尝试序列仍遵循现有稳定 ID 与显式 trigger_series 契约