14 KiB
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 区分实际成功、结果未知、明确失败、处理中和未发送终态,不得把 completed、ignored、merged、rate_limited 或 cancelled 计为外部请求成功。
Scenario: 查询指定时间范围总览
- WHEN 平台账号提交合法的开始时间、结束时间和时间粒度
- THEN 系统在该时间范围内返回固定结构的汇总、分类计数和趋势数据,并为每个稳定结果编码返回中文名称及派生类别
Scenario: 区分未发送终态与成功
- WHEN 时间范围内同时存在
success、completed、merged和rate_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=true、target_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契约