This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-08-11
|
||||
@@ -0,0 +1,34 @@
|
||||
## Context
|
||||
|
||||
`tb_integration_log.audit_event_id` 可空,现有所有调用方均未赋值;而事件查询已只使用该稳定字段返回外部交互引用。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- 正常路径让每条新 Integration Log 使用已持久化的 Audit Event 内部 ID。
|
||||
- 保持同一外部交互的开始、终态与重试使用同一稳定关联。
|
||||
- 在缺少关联时保留外部交互事实并输出可排查告警。
|
||||
|
||||
**Non-Goals:**
|
||||
- 不回填历史空关联记录。
|
||||
- 不按请求、资源、时间或摘要推断关联。
|
||||
- 不改变外部渠道协议、重试策略或审计查询响应格式。
|
||||
|
||||
## Decisions
|
||||
|
||||
- 为外部交互建立专用、已注册的 Audit Event,再将其内部 ID 传给 Integration Log 的开始或入站写入。这样在实际外呼或回调处理前已具备稳定关联;相比在完成后补写,不会留下因超时、崩溃或未发送而无关联的记录。
|
||||
- 调用链在可取得审计事件时传递关联;Integration Log 仓储允许关联缺失并记录告警。相比拒绝写入,外部交互事实不会因审计关联故障丢失。
|
||||
- `Complete` 仅延续既有关联,不接受用名称、时间或摘要寻找审计事件。重试沿用所属逻辑外部交互的审计事件。
|
||||
- 由完整用例负责在适当事务中创建审计事件并传递内部 ID;不让 Integration Log 仓储根据不完整上下文拼造操作者、资源或业务结果。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [调用链较多] → 先枚举所有 `Start`、`RecordInbound` 与未发送裁决调用点,逐链路传递关联并验证缺失时告警。
|
||||
- [审计事件写入先于外部调用] → 使用外部交互开始/入站事实的专用事件,终态仍由 Integration Log 保存,避免把未完成调用伪装为业务成功。
|
||||
- [现有写入顺序不共享事务] → 关联事件优先创建;创建失败时仍写入 Integration Log 并记录告警。
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. 部署新的审计事件类型、关联传递和缺失关联告警。
|
||||
2. 逐调用链接入并在隔离数据库验证新记录均有有效关联。
|
||||
3. 监控缺失关联告警;回滚时恢复调用链改动,不修改历史数据。
|
||||
@@ -0,0 +1,25 @@
|
||||
## Why
|
||||
|
||||
Integration Log 的 `audit_event_id` 从未由调用方写入,导致未来外部交互也无法从全局审计事件跳转至对应记录。现在将关联改为新记录的写入不变量,避免查询层继续收到空引用。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 新建的 Integration Log 在审计事件可用时稳定关联该事件;关联生成失败时仍保留外部交互事实。
|
||||
- 外部调用、回调、未发送裁决与终态更新保持同一稳定关联,不以名称、时间或摘要补猜。
|
||||
- 缺少关联时记录可排查告警,不阻断 Integration Log、外部调用或回调处理。
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- 无。
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `operations-audit`: 外部集成交互日志与审计事件的稳定关联成为新记录的必需事实。
|
||||
|
||||
## Impact
|
||||
|
||||
- `internal/infrastructure/integrationlog` 的写入契约与所有调用链。
|
||||
- 审计事件写入链路及 Integration Log 的创建、终态、入站回调和未发送裁决。
|
||||
- 无需为历史 Integration Log 回填数据、无需新增依赖或迁移。
|
||||
@@ -0,0 +1,35 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: 审计时间线
|
||||
|
||||
系统 SHALL 支持按事件、操作者、资源、请求、关联标识和资金维度查询已记录的审计事实。新建的 `tb_integration_log` 在已取得稳定审计事件时 SHALL 写入其内部 ID 作为 `audit_event_id`,并且该日志的非空 `integration_id` SHALL 出现在对应事件列表和事件详情的 `investigation_refs.integration_refs` 中;关联生成失败时系统 MUST 保留 Integration Log 并记录可排查告警,且 MUST NOT 按名称、时间或摘要推断关联。历史 Integration Log 不在本要求的回填范围内。
|
||||
|
||||
#### Scenario: 审计时间线
|
||||
|
||||
- **GIVEN** 审计事实已存在
|
||||
- **WHEN** 使用对应维度查询
|
||||
- **THEN** 返回匹配的事实与稳定动作编码,不用访问日志替代
|
||||
|
||||
#### Scenario: 事件返回已关联外部交互引用
|
||||
|
||||
- **GIVEN** 一个在线审计事件有 `tb_integration_log.audit_event_id` 指向其内部 ID 的外部交互记录
|
||||
- **WHEN** 查询全局审计事件列表或该事件详情
|
||||
- **THEN** 该事件的 `investigation_refs.integration_refs` 返回该记录的 `integration_id`
|
||||
|
||||
#### Scenario: 事件没有关联外部交互引用
|
||||
|
||||
- **GIVEN** 一个在线审计事件没有稳定关联的外部交互记录
|
||||
- **WHEN** 查询全局审计事件列表或该事件详情
|
||||
- **THEN** `investigation_refs.integration_refs` 返回空数组
|
||||
|
||||
#### Scenario: 新外部交互日志具有稳定审计关联
|
||||
|
||||
- **GIVEN** 系统即将记录一次新的外部调用、入站回调或未发送裁决
|
||||
- **WHEN** 写入对应 Integration Log
|
||||
- **THEN** 该记录保存非空 `audit_event_id`,且其目标 Audit Event 已存在
|
||||
|
||||
#### Scenario: 缺少审计关联时保留外部交互日志
|
||||
|
||||
- **GIVEN** 一次新的外部交互日志没有稳定审计事件关联
|
||||
- **WHEN** 系统尝试写入该 Integration Log
|
||||
- **THEN** 系统持久化该 Integration Log、记录可排查告警,并返回空 `integration_refs`
|
||||
@@ -0,0 +1,14 @@
|
||||
## 1. 审计关联写入契约
|
||||
|
||||
- [x] 1.1 注册外部交互开始与入站事实的 Audit Event,并提供调用链获取其内部 ID 的最小写入入口。
|
||||
- [x] 1.2 让 `Attempt`、`InboundAttempt` 和终态写入优先保留审计事件关联;关联缺失时记录告警但继续写入 Integration Log。
|
||||
|
||||
## 2. 调用链接入
|
||||
|
||||
- [x] 2.1 枚举并接入全部外呼、入站回调、未发送裁决和重试调用点,正常路径传递已持久化审计事件 ID。
|
||||
- [x] 2.2 保持业务成功、失败、未知和幂等冲突的现有状态语义,不按弱字段推断关联。
|
||||
|
||||
## 3. 验证
|
||||
|
||||
- [x] 3.1 在隔离数据库验证正常路径关联已存在 Audit Event,缺少关联时 Integration Log 仍可写入且产生告警。(按用户要求跳过)
|
||||
- [x] 3.2 运行格式化、构建和 OpenSpec 校验。
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-08-11
|
||||
@@ -0,0 +1,28 @@
|
||||
## Context
|
||||
|
||||
事件投影已批量加载资源,但未加载 `tb_integration_log`;请求和关联时间线已有按 `audit_event_id` 归集集成引用的逻辑。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- 为列表和详情的事件投影一次批量补全稳定集成交互引用。
|
||||
- 复用现有去重规则,保持空数组响应形态。
|
||||
|
||||
**Non-Goals:**
|
||||
- 不通过请求、关联标识、资源、名称或时间推断关联。
|
||||
- 不变更 Integration Log 写入链路、数据库结构或现有时间线行为。
|
||||
|
||||
## Decisions
|
||||
|
||||
- 在事件投影中使用当前页/当前详情的内部审计事件 ID 批量查询 `tb_integration_log.audit_event_id IN (...)`,再按 ID 归集。该字段是唯一明确的事件归属;逐事件查询会造成 N+1 查询。
|
||||
- 复用 `integrationRefsByAuditID` 和 `uniqueIntegrationRefs`。不增加新的查询层或 DTO。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [历史集成日志未写入 `audit_event_id`] → 保持为空,不猜测关系;由写入链路后续补齐新数据。
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. 部署查询代码变更,无迁移。
|
||||
2. 用同时存在关联与未关联日志的事件验证列表和详情响应。
|
||||
3. 回滚时恢复事件投影的关联日志批量查询与引用合并代码。
|
||||
@@ -0,0 +1,23 @@
|
||||
## Why
|
||||
|
||||
审计事件列表和详情已声明可返回外部集成交互跳转引用,但当前投影未读取关联日志,导致 `integration_refs` 始终为空,前端无法从事件直接进入对应集成记录。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 为全局审计事件列表和单事件详情补全由已关联 Integration Log 生成的 `investigation_refs.integration_refs`。
|
||||
- 保持没有关联日志的事件返回空数组,且不根据名称、时间或摘要推断关联。
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- 无。
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `operations-audit`: 审计事件查询返回与事件稳定关联的外部集成交互跳转引用。
|
||||
|
||||
## Impact
|
||||
|
||||
- `internal/query/audit/events.go` 的事件投影。
|
||||
- `GET /api/admin/audit/events` 和 `GET /api/admin/audit/events/{event_id}` 的响应内容;无需新增依赖或迁移。
|
||||
@@ -0,0 +1,23 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: 审计时间线
|
||||
|
||||
系统 SHALL 支持按事件、操作者、资源、请求、关联标识和资金维度查询已记录的审计事实。事件列表和事件详情中的 `investigation_refs.integration_refs` SHALL 仅包含 `tb_integration_log.audit_event_id` 稳定关联至该事件的非空 `integration_id`;没有关联记录时 SHALL 返回空数组,系统 MUST NOT 按名称、时间或摘要推断关联。
|
||||
|
||||
#### Scenario: 审计时间线
|
||||
|
||||
- **GIVEN** 审计事实已存在
|
||||
- **WHEN** 使用对应维度查询
|
||||
- **THEN** 返回匹配的事实与稳定动作编码,不用访问日志替代
|
||||
|
||||
#### Scenario: 事件返回已关联外部交互引用
|
||||
|
||||
- **GIVEN** 一个在线审计事件有 `tb_integration_log.audit_event_id` 指向其内部 ID 的外部交互记录
|
||||
- **WHEN** 查询全局审计事件列表或该事件详情
|
||||
- **THEN** 该事件的 `investigation_refs.integration_refs` 返回该记录的 `integration_id`
|
||||
|
||||
#### Scenario: 事件没有关联外部交互引用
|
||||
|
||||
- **GIVEN** 一个在线审计事件没有稳定关联的外部交互记录
|
||||
- **WHEN** 查询全局审计事件列表或该事件详情
|
||||
- **THEN** `investigation_refs.integration_refs` 返回空数组
|
||||
@@ -0,0 +1,9 @@
|
||||
## 1. 审计事件投影
|
||||
|
||||
- [x] 1.1 批量查询当前审计事件关联的 Integration Log,并按审计事件内部 ID 归集非空集成交互 ID。
|
||||
- [x] 1.2 在列表和详情共用的事件投影中填充并去重 `investigation_refs.integration_refs`,无关联时保留空数组。
|
||||
|
||||
## 2. 验证
|
||||
|
||||
- [x] 2.1 运行格式化和构建,验证包含关联与未关联 Integration Log 的事件投影行为。
|
||||
- [x] 2.2 运行 OpenSpec 校验。
|
||||
Reference in New Issue
Block a user