Files
junhong_cmp_fiber/docs/feature-504-multi-view-audit-center/跨视角调查与前端导航契约.md
break c64f3d8b80
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m31s
全局审计完成
2026-08-07 11:02:52 +08:00

42 KiB
Raw Blame History

审计链路与前端接入指南

本文对应 build-multi-view-audit-center 任务 9.5,作为审计链路和前端接入的单一说明入口。它回答以下问题:链路 ID 从哪里产生、存到哪里、不同入口为什么有的没有 request_id、15 条审计接口如何调用、每个入参与返回字段表示什么,以及前端应在哪些现有业务页面增加入口。

所有接口都使用统一响应 {code,msg,data,timestamp};本文中的返回字段默认位于 response.data,列表项默认位于 response.data.items[]。本文定义调用契约,不包含前端页面实现;机器可读类型、枚举和约束以 docs/admin-openapi.yaml 为准。

一、先理解五个稳定 ID

字段 表示什么 谁产生 前端能否产生 主要用途
request_id 一次 HTTP 请求 请求携带 X-Request-ID 时沿用;否则 Fiber 中间件生成 UUID 业务页面不应为了审计查询临时生成HTTP 客户端可统一传入自己的全局唯一 ID 把 Access Log、同一次 HTTP 内的 Audit Event、Integration Log 和 Outbox 串起来
correlation_id 一条可跨 HTTP、Outbox、Asynq、Callback 和外部交互的业务链路 HTTP 起点默认等于 request_id进入异步或具体业务后可改为订单号、支付号、Integration ID、任务 ID 等稳定链路值 不得根据时间、资源或中文描述推断 查询完整业务链路;它不表示技术重试
parent_event_id 一个审计事件的直接父事件 批量根事件、异步派生或消费者在创建子事件时传播 不生成 表示直接因果和批量根子关系,不替代 correlation
integration_id 一次外部交互尝试的稳定 ID Integration Log Writer 生成或调用方提供 不生成 查询单次外部交互详情,也是轮询链路的重要入口
trigger_series + attempt 同一外部操作的显式技术尝试序列和序号 可重试的 Integration 调用方 不生成 判断第几次重试;没有 series 时只展示单次记录,禁止猜测重试

request_id 的实际生命周期

  1. 浏览器、开放接口调用方或外部回调发起 HTTP 请求。调用方如已提供 X-Request-ID,服务端沿用;否则服务端生成 UUID。
  2. 服务端把同一个值写入响应头 X-Request-ID,浏览器可读取该响应头用于问题反馈。
  3. Access Log 把它记录为 request_id,同时审计上下文在 HTTP 起点设置 request_id,并默认设置 correlation_id=request_id
  4. 当前请求内发生业务变更时Audit Writer 将其写入 tb_audit_event.request_id;发生外部交互时可写入 tb_integration_log.request_id;创建可靠事件时可写入 tb_outbox_event.request_id
  5. 前端只有在事件或 Integration 返回了该值,或运维人员从响应头/Access Log 得到该值时,才调用请求时间线。普通资源详情页不需要先取得 request_id

不是每个 HTTP 请求都会产生 Audit Event。例如普通列表查询只有 Access Log没有业务审计事件此时即使响应头有 X-Request-ID,请求时间线也可能没有业务节点。

request_id 在哪里落库

事实 存储位置 request_id 字段 correlation_id 字段 说明
HTTP 调试事实 Access Log 文件 JSON 字段 request_id 当前访问日志不承担业务 correlation 查询 用于按请求排查原始 HTTP审计时间线不会扫描日志文件
Audit Event tb_audit_event request_id,非空列但允许保存空字符串 correlation_id,非空列但允许保存空字符串 解释谁对什么资源做了什么
Integration Log tb_integration_log request_id,可空 correlation_id,可空 解释调用了哪个外部系统、结果和尝试序列
Outbox tb_outbox_event request_id,允许空字符串 correlation_id,允许空字符串 可靠投递事实;投递成功不等于业务成功
Asynq 任务 payload 或 Audit Event 的任务资源引用 按任务类型选择性携带 按任务类型选择性携带 Redis 队列不是审计查询数据源;查询只展示已持久化引用,不扫描历史队列
手动轮询运行记录 tb_polling_manual_trigger_log 没有该字段 没有该字段 只承担进度、结果、触发人和卡列表;人工触发命令另写 Audit Event

二、轮询为什么通常没有 request_id

普通自动轮询由 Scheduler/Asynq Worker 触发,不是 HTTP 请求,因此没有 request_id 是正确语义:

  1. Worker 调用 Gateway 前创建 Integration Log生成 integration_id
  2. 普通轮询的 tb_integration_log.request_id 保持空;trigger_seriescorrelation_id 通常使用该 integration_id
  3. Gateway 返回后如果观测结果实际改变卡、设备、套餐或网络状态Worker 才写 Audit Event。
  4. 该 Audit Event 的 request_id 仍为空,correlation_id 使用 Integration ID、Asynq Task ID 或稳定任务标识,从而与外部尝试和资源时间线关联。
  5. 前端看到 request_id 为空时隐藏“请求链路”;correlation_id 非空时显示“业务链路”;无论两者是否存在,都可以继续使用 integration_id 或资源引用。

人工轮询需要区分两个事实:

  • 管理员点击“手动触发”的 HTTP 命令会产生 Audit Event因此该“谁发起了轮询”事件有 request_id
  • 随后真正执行轮询的是 Worker。当前手动队列只携带卡 ID执行阶段没有原 HTTP request_idGateway 尝试和实际观测变化按 Worker 自身的 Integration ID/correlation 串联。
  • tb_polling_manual_trigger_log 继续显示进度和结果Audit Event 解释谁触发/取消Integration Log 解释 Gateway 是否被调用以及调用结果。三类事实不能合并成一张记录。

三、前端选择入口的顺序

前端不应把 request_id 当作所有审计入口的必填条件。统一按以下顺序选择:

  1. 业务页面已有内部 ID平台直接调用资源时间线。
  2. 代理或企业页面已有 ICCID、VirtualNo、分配单号、换货单号等业务 identifier调用主体资源活动接口。
  3. 订单、退款、充值、钱包或店铺页面:直接以任一稳定业务 ID 调用资金时间线,关联 ID 由服务端补全。
  4. 审计节点返回 investigation_refs按引用字段跳转事件、操作者、资源、请求、correlation 或 Integration 视角。
  5. 只有 resource_key 没有内部 ID先调用资源精确搜索零命中或多命中时让用户选择不自动猜测。
  6. 必需字段不存在:隐藏入口;不得用名称、中文说明、相近时间、编号前缀或第三方流水猜关系。

四、15 条接口总览

接口 何时调用 必填入参 主要返回
GET /api/admin/audit/events 平台审计中心全局列表或其他节点带筛选跳转 EventPage
GET /api/admin/audit/events/{event_id} 查看一个稳定审计事件 event_id EventDetail
GET /api/admin/audit/actors/{kind}/{id}/events 查看某个操作者行为 kindid EventPage
GET /api/admin/audit/resources/search 只有业务 Key、没有内部资源 ID resource_typekeyword ResourceSearchPage
GET /api/admin/audit/resources/{resource_type}/{resource_id}/timeline 平台业务页面或资源引用进入审计 resource_typeresource_id EventPage
GET /api/admin/audit/requests/{request_id}/timeline 已有真实 request ID 时调查一次 HTTP request_id LinkTimeline
GET /api/admin/audit/correlations/{correlation_id}/timeline 调查跨请求、异步和外部业务链路 correlation_id LinkTimeline
GET /api/admin/audit/finance/timeline 从订单、退款、充值、钱包、店铺等进入资金调查 至少一个稳定资金条件 FinanceTimelinePage
GET /api/admin/audit/risks/overview 平台风险中心总览 无;时间不传时使用在线窗口 RiskOverview
GET /api/admin/audit/risks/events 从风险分桶查看明细 无;分页和筛选可选 RiskEventPage
GET /api/admin/audit/integrations/overview 平台 Integration 调查总览 无;时间不传时使用在线窗口 IntegrationOverview
GET /api/admin/audit/integrations 外部交互列表和组合筛选 IntegrationListPage
GET /api/admin/audit/integrations/{integration_id} 查看单次外部交互和尝试序列 integration_id IntegrationDetailResponse
GET /api/admin/agent/resource-activities/{resource_type}/{identifier} 代理查看授权范围内资源活动 resource_typeidentifier SubjectActivityPage
GET /api/admin/enterprise/resource-activities/{resource_type}/{identifier} 企业查看当前有效授权卡或设备活动 resource_typeidentifier SubjectActivityPage

平台 /audit/* 接口仅允许超级管理员和平台账号访问;代理、企业必须使用各自的主体活动接口。全部为 GET不提供修改、删除、导出、恢复、重试、补偿或风险处置。

五、请求参数字典

通用时间与分页

字段 类型 是否必填 含义
created_from RFC3339 字符串 起始时间,包含该时刻;未传时从在线留存窗口开始
created_to RFC3339 字符串 结束时间,不包含该时刻;未传时为当前时间
page int 页码,默认 1
page_size int 每页数量,默认 20最大 100

显式时间早于 retention.online_from 或跨越在线边界时返回“数据已归档”稳定错误不会从对象存储读取部分结果。Integration 和风险查询最长连续 31 天。

全局事件 GET /audit/events

字段 类型/枚举 来源与用途
action string 稳定动作编码,使用返回的 action_code
category configuration/reliability/asset/security/identity/business 动作类别
actor_kind account/personal_customer/openapi/system_task/scheduled_job/external_system 操作者类型
actor_id string 与 actor_kind 共同定位操作者
source admin_api/personal_api/openapi/worker/scheduler/callback 操作入口
result success/failed/denied/partial/unknown 业务结果
risk low/normal/high/critical 风险等级
scope_type platform/shop/personal_customer 业务范围类型
scope_id string 业务范围稳定 ID
resource_type Registry 类型 资源类型
resource_id string 资源内部稳定 ID
resource_key string 资源业务稳定 Key
request_id string 可选精确筛选;来自真实 HTTP 请求,不是必填入口
correlation_id string 可选精确筛选业务链路
created_from/to/page/page_size 通用字段 时间和分页

事件详情、操作者和资源

接口 参数 说明
/audit/events/{event_id} path event_id 来自事件列表或 investigation_refs.event_id
/audit/actors/{kind}/{id}/events path kind/idquery action/result/risk/resource_type/resource_id/created_from/created_to/page/page_size kind/id 来自 actor_refaction 使用返回的稳定编码
/audit/resources/search query resource_type/keyword/page/page_size resource_type 仅 iot_card/device/shop/order/refundkeyword 为精确业务标识
/audit/resources/{resource_type}/{resource_id}/timeline path resource_type/resource_idquery created_from/created_to/action/result/page/page_size path 来自业务页面内部 ID、搜索结果或 resource_refs

资源搜索 keyword 规则:卡支持 ICCID/VirtualNo设备支持 VirtualNo/IMEI/SN店铺使用店铺编号订单使用订单号退款使用退款单号。

request 与 correlation 时间线

接口 参数 说明
/audit/requests/{request_id}/timeline path request_id 来自 Event/Integration 返回字段、响应头或 Access Log普通轮询为空时不调用
/audit/correlations/{correlation_id}/timeline path correlation_id 来自 Event、Integration、Outbox/任务或业务详情稳定字段

这两个接口不接受分页返回在线窗口内全部已持久化关联节点。request 查询会同时返回 access_log_lookup_request_id,供运维复制到 Access Log 检索;接口自身不扫描 Access Log。

资金时间线 GET /audit/finance/timeline

字段 类型 前端来源
shop_id uint 店铺详情或资金概况
wallet_id uint 代理主钱包或资产钱包详情
order_id/order_no uint/string 订单列表或详情
payment_id/payment_no uint/string 支付记录或已明确返回的支付单号
refund_id/refund_no uint/string 退款列表或详情
recharge_id/recharge_no uint/string 代理充值或个人资产充值
approval_instance_id uint 审批实例
third_party_trade_no string 已明确返回的第三方交易号
actor_kind/actor_id enum/string 调查某操作者涉及的资金事实,必须成对提供
correlation_id string 已有稳定业务链路时使用
created_from/to/page/page_size 通用字段 时间和分页

调用方至少提供一个稳定资金条件;同一业务的其他 ID 由服务端解析,不要求前端补齐。

风险接口

接口 参数 映射
/audit/risks/overview created_from/created_to/risk/result/action/source 独立风险中心筛选
/audit/risks/events 上述字段 + page/page_size risks[].code→riskresults[].code→resultactions[].code→actionsources[].code→source

Integration overview/list

overview 和 list 共用以下筛选overview 另有 bucket=hour/daylist 另有 page/page_size

字段 类型/枚举 来源与用途
integration_id string 列表、通知 target 或 investigation_refs 返回的稳定 ID
provider ctcc/cmcc/cucc/wechat_pay/alipay/fuiou/wecom/gateway 外部服务提供方
direction inbound/outbound 入站或出站
operation OpenAPI enum 外部操作稳定编码,使用列表/详情返回的 operation
result pending/success/failed/unknown/not_found/invalid_payload/conflict/ignored/merged/rate_limited/completed/cancelled 原始结果
result_category processing/succeeded/indeterminate/failed/not_sent 服务端从 result 派生的固定类别
external_id string 外部系统业务或请求标识
resource_type/resource_id/resource_key string 本地主要资源稳定引用
trigger_source/trigger_scene/trigger_series string 触发来源、业务场景和显式尝试序列
state_changed bool 是否改变本地业务状态
http_status 100599 外部 HTTP 状态码
provider_code string 外部服务稳定结果码
request_id/correlation_id string 已有稳定链路字段时筛选;自动轮询 request_id 为空
created_from/to 通用字段 时间范围,最长 31 天

当前 operation 枚举为:realname_callbackrealname_removal_callbackpayment_precreatepayment_querypayment_callbackget_access_tokenlist_visible_memberslist_visible_departmentsget_template_detailupload_approval_attachmentsubmit_approvalapproval_callbackget_approval_detailget_approval_infoquery_realname_statusquery_flowquery_card_statusquery_device_infoset_speed_tierstop_cardstart_cardset_device_wifiset_device_switch_modeswitch_device_cardreboot_devicereset_device。前端使用 OpenAPI 或接口返回值,不维护另一份中文到编码映射。

代理与企业主体活动

接口 resource_type identifier 其他参数
/agent/resource-activities/{resource_type}/{identifier} iot_card/device/asset_allocation_record/exchange_order/shop/enterprise 依次使用 ICCID、VirtualNo、分配单号、换货单号、店铺编号、企业编号 created_from/created_to/page/page_size
/enterprise/resource-activities/{resource_type}/{identifier} iot_card/device 卡用 ICCID设备用 VirtualNo created_from/created_to/page/page_size

代理店铺范围和企业 ID 只来自认证上下文,前端不能传 shop_id/enterprise_id 证明权限。

六、返回参数字典

统一响应与留存信息

字段 含义
code 统一响应码,成功为 0
msg 中文响应消息
data 本接口业务数据
timestamp 服务端响应时间
retention.online_from PostgreSQL 当前可在线查询的最早时间
retention.archived_before 早于该时间的数据已归档,不可通过这些接口读取
retention.timezone 留存边界时区,当前为 Asia/Shanghai

EventPage、EventDetail 与 EventView

EventPage 返回 total/page/page_size/items[]/retentionEventDetail 返回单个 EventView 并附带 retention。

EventView 字段 含义/前端用法
event_id 稳定审计事件 ID可打开事件详情
occurred_at/created_at 业务事实发生时间/审计记录写入时间
category 动作类别稳定编码
action_code/action_name 稳定动作编码/中文展示名;筛选使用 code
summary 中文事件摘要
actor_kind/actor_id/actor_name 操作者类型、稳定 ID、事件发生时名称快照
actor_shop_id/name 操作者所属店铺快照
actor_enterprise_id/name 操作者所属企业快照
source admin_api、worker、scheduler、callback 等入口来源
request_path/request_method/ip_address/user_agent HTTP 来源信息Worker/Scheduler 可为空
scope_type/scope_id/scope_name 业务范围类型、ID 和名称快照
result/risk_level 结果和风险等级稳定编码
error_code/error_summary 失败或拒绝时的稳定错误码和脱敏摘要
request_id 有值才显示“请求链路”;自动轮询通常为空
correlation_id 有值显示“业务链路”
parent_event_id 直接父事件 ID
batch_total/success_count/fail_count 批量根事件计数;非批量为 0
metadata 已脱敏动作扩展字段,具体含义由 action_code 定义
content_hash 事件不可变内容摘要
resources[] 事件涉及的全部资源及各自快照
investigation_refs 前端跨视角跳转的唯一稳定来源

resources[] 字段:resource_type/resource_id/resource_key/display_name 定位资源;relationprimary/affected/referencerole 为资源业务角色;identity_snapshot 为事件发生时身份;before_data/after_data 为该资源变更前后数据;subject_visibility/subject_summary/subject_data 为代理或企业安全投影;sort_order/created_at 为展示顺序和资源关联记录写入时间。

investigation_refs 字段:event_idactor_ref{kind,id}resource_refs[]{resource_type,resource_id,resource_key,display_name}request_idcorrelation_idintegration_refs[]{integration_id}。任一目标所需字段不完整时隐藏该入口。

ResourceSearchPage

返回 total/page/page_size/items[]/retention。候选项包含 resource_type/resource_id/resource_key/display_name/identity_snapshot/historicalhistorical=true 表示当前业务表未命中,只从在线历史事件快照解析,不代表资源当前仍存在。

LinkTimeline

字段 含义
request_id/correlation_id 本次查询使用的链路值,二者只会对应当前查询视角
access_log_lookup_request_id 可复制到 Access Log 的 request ID
nodes[] 按发生时间稳定升序的跨事实节点
retention Audit 与 Integration 的共同在线边界

nodes[] 包含:record_sourcenode_idoccurred_atcode/titleresult/result_namesummaryreference_onlyrequest_id/correlation_id/parent_event_idresources[]investigation_refsfidelity

record_source 可能是 audit_eventintegration_logoutbox_event;由事件资源派生的只读引用还可能是 asynq_taskdomain_ledger_refreference_only=true 只表示引用,不代表该节点独立改变了业务状态。fidelity 包含 request_availablecorrelation_availableparent_event_availabledirect_audit_link_availablestable_resource_availablefalse 时禁止猜测补齐。

FinanceTimelinePage

返回 total/page/page_size/items[]/retention。每个资金节点包含:

  • record_source/node_id/occurred_at:事实来源、来源内稳定 ID、发生时间。
  • code/title/result/result_name:来源内稳定编码和中文名称。
  • amount/balance_before/balance_after/currency:金额和余额,单位分,人民币为 CNY为空表示该节点不承载该金额。
  • shop_id/wallet{resource_type,wallet_id}:店铺和钱包引用。
  • amount_authority{authoritative,table,field,conflict_rule}:是否为权威金额及其数据库表字段;冲突时按 conflict_rule 展示。
  • facts:该事实来源的安全结构化业务字段。
  • investigation_refs继续进入事件、资源、操作者、request、correlation 或 Integration。

RiskOverview 与 RiskEventPage

RiskOverview 返回:total、服务端选择的 bucket=hour/daysignals/risks/results/actions/sources 分布、trend[] 和 retention。所有分布项统一为 {code,name,count},筛选使用 code、展示使用 name。

  • signals[].codehigh_risk/finance/security/failed/denied/partial/unknown
  • risks[].codelow/normal/high/critical
  • results[].codesuccess/failed/denied/partial/unknown
  • actions[].code:稳定 action_code。
  • sources[].codeadmin_api/personal_api/openapi/worker/scheduler/callback
  • trend[]bucket_at/total/high_risk/finance/security/failed/denied/partial/unknown

RiskEventPage 与 EventPage 结构相同items[] 只包含固定风险集合内的 EventView。

IntegrationOverview、ListPage 和 Detail

IntegrationOverview 返回 total/anomaly_count/unknown_count/stale_pending_count/state_changed_count/average_duration_ms/p95_duration_ms/results/providers/directions/trend/retentionresults[]{code,name,category,count}providers/directions 为 {code,name,count}trend[]{bucket_at,total,succeeded,processing,indeterminate,failed,not_sent}。分布 code 可原样回填 list 筛选name 只用于展示。

Integration ListPage 返回 total/page/page_size/items[]/retention。每项包含:

  • integration_id:详情入口。
  • provider/provider_namedirection/direction_nameoperation/operation_name:稳定编码和中文名。
  • resource{type,id,key}type/id 均存在时可进入资源时间线。
  • result/result_name/result_category:原始结果、中文名和派生类别。
  • duration_ms/state_changed/created_at:耗时、本地状态是否变化和创建时间。
  • request_id/correlation_id:分别控制请求链路和业务链路入口;自动轮询 request_id 可为空。

Integration Detail 按分组返回:

分组 字段与用途
identity integration_id/provider/provider_name/direction/direction_name/operation/operation_name/external_id
resource type/id/keytype/id 齐全时进入资源时间线
trigger source/scene/series/attemptseries 为空时不拼接其他重试
result code/name/category/http_status/provider_code/provider_message/duration_ms/state_changed/recovery_strategy;本接口只展示,不执行恢复
content 已脱敏 request_summary/response_summary/metadata/content_hash
linkage request_id/correlation_id/audit_event_id;稳定事件跳转优先使用 investigation_refs 中的 event_id
timestamps scheduled_at/started_at/created_at/updated_at
attempts[] 同 series 的 integration_id/attempt/operation/operation_name/sent/result/result_name/result_category/duration_ms/state_changed/created_at
fidelity trigger_series_available/attempt_sequence_reliable/correlation_available/resource_id_available/provider_message_fidelity
retention 在线留存边界

SubjectActivityPage

代理与企业安全活动返回 resource/total/page/page_size/items[]/retention

  • resourcerelated_resources[]resource_type/resource_id/resource_key/display_name 安全摘要;主体前端不得据此调用平台 /audit/*
  • items[].action_code/action_name:安全动作编码和中文名。
  • items[].subject_summary/subject_data:写入时生成的主体安全摘要和白名单业务字段,不是平台 before/after 删除字段后的结果。
  • items[].result/occurred_at:结果和发生时间。
  • 响应不包含平台 actor、risk、内部原因、before/after、Audit Event ID、request_id、correlation_id、Integration 内容或 investigation_refs。

七、跨视角只读接口

视角 接口 入参来源 响应重点
请求链路 GET /api/admin/audit/requests/{request_id}/timeline 审计或 Integration 节点的 investigation_refs.request_id,或开发人员从 Access Log 粘贴 request_idaccess_log_lookup_request_idnodes[]
业务链路 GET /api/admin/audit/correlations/{correlation_id}/timeline 审计、Integration、Outbox、任务或业务详情中的稳定 correlation correlation_idnodes[]
资金时间线 GET /api/admin/audit/finance/timeline 业务页面稳定 ID、调查节点引用或调查人员输入 分页 items[]、事实来源、金额权威、investigation_refs
风险总览 GET /api/admin/audit/risks/overview 调查人员选择的 RFC3339 时间范围及可选筛选,最长 31 天 信号、风险、结果、动作、来源和趋势
风险明细 GET /api/admin/audit/risks/events 风险总览分桶携带相同筛选,或调查人员输入 分页风险事件及 investigation_refs

以上接口仅允许超级管理员和平台账号访问,全部为 GET。认证身份只来自认证上下文不提供导出、修改、删除、风险处置、自动封禁、重试、补偿或恢复能力。

资产和组织页面逐行导航

源页面 前置接口 response.data 稳定字段 入口名称与可见条件 目标接口与参数映射 降级行为
卡列表 GET /api/admin/iot-cards/standalone items[].id/iccid/virtual_no/shop_id/device_virtual_no/authorized_enterprise_id 平台显示“审计记录”,要求 id 非零;代理显示“活动记录”,要求 iccid 非空;企业不从此列表进入 平台:/audit/resources/iot_card/{id}/timeline;代理:/agent/resource-activities/iot_card/{iccid} 缺少对应 ID/ICCID 时隐藏;企业改从企业卡列表进入
设备列表 GET /api/admin/devices items[].id/virtual_no/imei/sn/shop_id/bound_card_count/authorized_enterprise_id 平台要求 id;代理要求 virtual_no;企业不从此列表进入 平台:/audit/resources/device/{id}/timeline;代理:/agent/resource-activities/device/{virtual_no} 缺少字段时隐藏;企业改从企业设备列表进入
设备卡槽 GET /api/admin/devices/{virtual_no}/cards bindings[].id/iot_card_id/iccid/slot_position/is_current 平台可分别查看卡和绑定审计,要求相应 ID代理可查看卡活动要求 ICCID企业仅在设备和卡均有效授权时显示卡活动 平台卡:iot_card/{iot_card_id};平台绑定:device_sim_binding/{bindings[].id};代理/企业卡:iot_card/{iccid} 的主体活动接口 不用绑定 ID 证明授权;设备时间线继续使用上层设备 ID/VirtualNo
统一资产详情 GET /api/admin/assets/resolve/{identifier} asset_type/asset_id/identifier/virtual_no/iccid/bound_device_id/cards[].card_id/exchange_trace[].asset_id/can_view 平台在 asset_id 存在时显示“审计记录”;代理在卡 ICCID 或设备 VirtualNo 存在时显示“活动记录”;企业不显示 平台:card→iot_card/{asset_id}device→device/{asset_id};代理:卡用 iot_card/{iccid}、设备用 device/{virtual_no} 缺稳定字段时隐藏;换货轨迹仅 can_view=true 且资产 ID 存在时跳转;企业不得回退调用 resolve
资产分配列表/详情 GET /api/admin/asset-allocation-records[/{id}] items[].id/allocation_no/asset_type/asset_id/asset_identifier/from_owner_type/from_owner_id/to_owner_type/to_owner_id/related_device_id;详情另有 related_card_ids[] 平台要求记录或资产 ID代理要求 allocation_no 且当前关联资产或店铺仍在范围内;企业无独立入口 平台:asset_allocation_record/{id}{asset_type}/{asset_id};代理:/agent/resource-activities/asset_allocation_record/{allocation_no} 后端独立复核分配归属;不能因可打开旧详情就视为有权;企业从已授权资产活动查看结论
换货列表/详情 GET /api/admin/exchanges[/{id}] items[].id/exchange_no/old_asset_type/old_asset_id/new_asset_type/new_asset_id/shop_id/submitter_id 平台要求换货或资产 ID代理要求 exchange_no 且换货店铺仍在范围内;企业无独立入口 平台:exchange_order/{id},旧新资产分别使用响应类型和 ID代理/agent/resource-activities/exchange_order/{exchange_no} 旧新资产仅在各自仍可管理时开放;企业从有效授权资产活动查看结论
店铺列表/详情 GET /api/admin/shops[/{id}] items[].id/shop_name/shop_code/parent_id/business_owner_account_id 或详情同名字段 平台要求 id;代理要求 shop_code 且为自己或下级店铺;企业不显示 平台:/audit/resources/shop/{id}/timeline;代理:/agent/resource-activities/shop/{shop_code} 缺字段或越权时隐藏/显示不可用,不搜索平台审计
企业列表 GET /api/admin/enterprises items[].id/enterprise_name/enterprise_code/owner_shop_id 平台要求 id;代理要求 enterprise_code 且 owner shop 在范围内;企业自身不显示 平台:enterprise/{id};代理:/agent/resource-activities/enterprise/{enterprise_code} 当前没有企业详情接口,前端不得假设存在;企业 ID 不作为主体活动路径参数
企业卡列表 GET /api/admin/enterprises/{id}/cards items[].id/iccid/virtual_no/device_id 平台要求 id;企业要求 iccid 且当前授权有效;代理不从此列表进入 平台:iot_card/{id};企业:/enterprise/resource-activities/iot_card/{iccid} 路由中的企业 ID 不作为授权证明;后端始终使用认证上下文复核
企业设备列表 GET /api/admin/enterprises/{id}/devices items[].device_id/virtual_no 平台要求 device_id;企业要求 virtual_no 且当前授权有效;代理不从此列表进入 平台:device/{device_id};企业:/enterprise/resource-activities/device/{virtual_no} 字段为空或授权撤销时隐藏/显示活动不可用,不回退平台接口

账号、交易和资金页面逐行导航

源页面 前置接口 response.data 稳定字段 入口名称与可见条件 目标接口与参数映射 降级行为
账号列表/详情 GET /api/admin/accounts[/{id}] 列表 items[].id;详情 id 平台在 ID 非零时显示“审计记录” /audit/resources/account/{id}/timeline 缺 ID 时隐藏,不按用户名搜索
店铺列表/详情 GET /api/admin/shops[/{id}] 列表 items[].id;详情 id ID 非零时显示“审计记录”和“资金链路” 审计:shop/{id};资金:/audit/finance/timeline?shop_id={id} 缺 ID 时两个入口均隐藏
企业列表 GET /api/admin/enterprises items[].id ID 非零时显示“审计记录” /audit/resources/enterprise/{id}/timeline 不假设存在企业详情接口
订单列表/详情 GET /api/admin/orders[/{id}] items[].id/order_no 或详情 id/order_no ID 非零时显示“审计记录”和“资金链路” 审计:order/{id};资金:/audit/finance/timeline?order_id={id} 不要求前端补 payment/refund ID缺 ID 时隐藏
退款列表/详情 GET /api/admin/refunds[/{id}] items[].id/refund_no/order_id/approval_instance_id 或详情同名字段 ID 非零时显示审计和资金入口;审批 ID 非零时显示“审批审计” 审计:refund/{id};资金:finance/timeline?refund_id={id};审批:approval_instance/{approval_instance_id} 缺审批 ID 只隐藏审批入口,不解析退款编号猜测
代理充值列表/详情 GET /api/admin/agent-recharges[/{id}] items[].id/recharge_no/shop_id/agent_wallet_id/approval_instance_id 或详情同名字段 ID 非零时显示审计和资金入口;审批 ID 非零时显示审批审计 审计:agent_recharge/{id};资金:finance/timeline?recharge_id={id} payment_no 由服务端关联,不要求前端补猜
代理在线充值结果 POST /api/admin/agent-recharges recharge_id/recharge_no/payment_no recharge_id 非零时显示“资金链路” finance/timeline?recharge_id={recharge_id};可附加 payment_no 精确筛选 payment_no 不直接构造 Integration 详情;缺 recharge ID 时隐藏
资产钱包 GET /api/admin/assets/{identifier}/wallet wallet_id/resource_type/resource_id wallet_id 非零时显示“资金链路”;资源类型和 ID 齐全时显示“资产审计” 资金:finance/timeline?wallet_id={wallet_id};审计:resources/{resource_type}/{resource_id}/timeline 两个入口独立判断;缺某组字段只隐藏对应入口
店铺资金概况 GET /api/admin/shops/fund-summary items[].shop_id shop_id 非零时显示行内“资金链路” finance/timeline?shop_id={shop_id} 不要求该接口未返回的 agent wallet ID
店铺主钱包流水 GET /api/admin/shops/{shop_id}/main-wallet/transactions path shop_iditems[].id/asset_type/asset_id/asset_identifier 始终可按合法 path 显示资金入口;资产类型和 ID 齐全时显示资产审计 资金:finance/timeline?shop_id={shop_id};审计:resources/{asset_type}/{asset_id}/timeline 缺资产 ID 仍保留店铺资金入口,不按资产编号猜测
资产钱包流水 GET /api/admin/assets/{identifier}/wallet/transactions 上层钱包接口 wallet_iditems[].id/reference_type/reference_no 上层 wallet_id 非零时显示“资金链路” finance/timeline?wallet_id={wallet_id} reference_type/reference_no 仅展示;需后端节点明确返回资源引用后才能继续跳转

调查节点逐行跳转

investigation_refs 字段 入口名称 可见条件 目标接口与参数 降级行为
event_id “事件详情” 非空 GET /api/admin/audit/events/{event_id} 空值隐藏
actor_ref.kind/id “查看操作者行为” kind 和 id 均非空 GET /api/admin/audit/actors/{kind}/{id}/events 任一缺失即隐藏,不用当前账号资料补齐
resource_refs[] “查看资源审计” resource_type/resource_id 均非空 GET /api/admin/audit/resources/{resource_type}/{resource_id}/timeline 只有 Key 时先精确搜索;零或多命中不自动选择
request_id “查看请求链路” 非空 GET /api/admin/audit/requests/{request_id}/timeline 空值隐藏,不扫描 Access Log 猜测
correlation_id “查看业务链路” 非空 GET /api/admin/audit/correlations/{correlation_id}/timeline 空值隐藏,不按相近时间拼链路
integration_refs[].integration_id “查看外部交互” 非空 GET /api/admin/audit/integrations/{integration_id} 空值隐藏,不使用数据库主键或相似资源猜测

actor_ref.kind 使用 account/personal_customer/openapi/system_task/scheduled_job/external_system。代理和企业活动响应不得包含 investigation_refs

八、完整调用链

HTTP 同步业务操作

  1. 前端调用现有业务写接口;可不传 X-Request-ID,服务端会生成并通过响应头返回。
  2. HTTP 中间件建立 request_id,审计上下文初始设置 correlation_id=request_id
  3. 业务变更与 Audit Event 在同一事务提交,事件写入 request_id/correlation_id 和资源快照。
  4. 前端从业务资源页用资源 ID 查看时间线,或从 EventView 的 request_id 查看该请求链路。
  5. 请求时间线只返回已经落入 Audit、Integration、Outbox 的节点Access Log 需另用 access_log_lookup_request_id 检索。

HTTP → Outbox → Asynq/Worker

  1. HTTP 操作产生 request_id,业务确定或沿用 correlation_id
  2. 创建 Outbox 时,未显式传入的 request/correlation/parent 从审计上下文继承并写入 tb_outbox_event
  3. Relay 将三个字段随 envelope 交给消费者;需要继续入 Asynq 的任务在 payload 中显式携带。
  4. Worker 恢复系统操作者并写子 Audit Event有外部调用时另写 Integration Log。
  5. 前端用 correlation 时间线查看跨进程链路;record_source 区分 Audit、Outbox、Integration 和任务引用,不能把 Outbox delivered 当作业务成功。

外部 Callback

  1. Callback 同样经过 HTTP RequestID 中间件,因此会有 request_id
  2. Integration Log 先记录入站外部交互correlation 可等于 request ID也可使用 payment_no、审批 SPNo 等更稳定业务键。
  3. Callback 实际改变本地业务事实时,以 external_system actor 写 Audit Event没有状态变化时只保留 Integration Log。
  4. 前端从 Integration detail 的 request/correlation/resource 引用继续调查。

自动轮询

  1. Scheduler/Asynq 选择卡并执行 Worker没有 HTTP request因此不生成 request_id
  2. Worker 创建 Gateway Integration Logintegration_id=trigger_series=correlation_idrequest_id=null
  3. Gateway 结果若改变内部事实Audit Event 使用同一 correlationactor 为 system_tasksource 为 worker
  4. 前端从 Integration 调查中心、资源时间线或 correlation 时间线进入;隐藏“请求链路”。

人工即时刷新与手动轮询入队

  • “人工即时刷新卡数据”在一个 HTTP 用例内直接执行 Gateway 查询:有 request_id外部尝试可继承该 request/correlation能从请求时间线串起。
  • “手动触发轮询”先记录 HTTP 触发 Audit Event因此触发命令有 request_id但当前 Redis 手动队列只保存 card ID后续 Worker 没有原 request/correlation执行阶段按新的 Integration ID 建链。
  • 因此当前不能仅凭 request_id 从“手动触发事件”自动跳到后续 Gateway 轮询尝试。前端分别展示手动任务进度、触发审计和资源/Integration 活动,不按时间拼接。若产品要求强关联,需要单独实施稳定 trigger/correlation 传播,不属于本文前端接入范围。

资产详情

  1. 调用 GET /api/admin/assets/resolve/{identifier}
  2. 平台读取 data.asset_type/asset_id:卡将 card 转为 iot_card,调用 GET /api/admin/audit/resources/iot_card/{asset_id}/timeline?page=1&page_size=20;设备调用 .../device/{asset_id}/timeline
  3. 代理读取 data.icciddata.virtual_no,调用对应 /agent/resource-activities/...
  4. 字段缺失时隐藏入口;企业不调用 resolve也不回退平台接口。

订单

  1. 调用 GET /api/admin/orders/{id},读取 data.id
  2. “审计记录”调用 GET /api/admin/audit/resources/order/{id}/timeline
  3. “资金链路”调用 GET /api/admin/audit/finance/timeline?order_id={id}&page=1&page_size=20
  4. Payment、Refund、钱包等关联由服务端解析前端不补猜。

退款

  1. 调用 GET /api/admin/refunds/{id},读取 data.id 和可选 data.approval_instance_id
  2. 审计调用 resources/refund/{id}/timeline,资金调用 finance/timeline?refund_id={id}
  3. 审批实例 ID 非零时再调用 resources/approval_instance/{approval_instance_id}/timeline
  4. 审批字段缺失只隐藏审批入口,不影响退款审计与资金链路。

钱包

  1. 调用 GET /api/admin/assets/{identifier}/wallet,读取 data.wallet_id/resource_type/resource_id
  2. “资金链路”调用 finance/timeline?wallet_id={wallet_id}
  3. “资产审计”调用 resources/{resource_type}/{resource_id}/timeline
  4. 两组稳定字段分别判断,不使用交易备注或 reference 编号前缀推断资源。

通知

  1. 点击通知后先调用 GET /api/admin/notifications/{id}/target
  2. 仅当 data.available=true 时展示跳转。
  3. data.target_type=integration_logdata.target_key 非空时,将 target key 原样作为 integration_id 调用 GET /api/admin/audit/integrations/{target_key}
  4. 其他 target type 先进入对应业务详情,再按本文业务页面矩阵进入审计;不可用时只展示通知正文。

风险节点

  1. 调用 GET /api/admin/audit/risks/overview?created_from={from}&created_to={to}
  2. 点击风险、结果、动作或来源分桶时,将相同时间范围和对应稳定编码带入 GET /api/admin/audit/risks/events
  3. 从明细 items[].investigation_refs 直接进入事件、操作者、资源、request、correlation 或 Integration 视角。
  4. 缺少的引用入口隐藏;风险中心不提供处置、封禁或恢复按钮。

九、统一降级与事实边界

  • 缺少目标接口必需的稳定 ID 或 identifier 时隐藏入口,不按名称、中文描述、时间或编号前缀猜测。
  • 平台只有 Registry Key 时先调用精确资源搜索;零命中或多命中停留在搜索结果。
  • 已删除资源只要调查节点仍有稳定资源类型和 ID就可查看事件快照时间线。
  • 代理或企业遇到越权、授权撤销或资源不存在时统一显示“活动不可用”,不回退平台调查、资源搜索或旧 operation log。
  • request/correlation 时间线的 record_source 保留 Audit Event、Integration Log、Outbox、Asynq 摘要和 Domain Ledger 引用的事实边界Outbox 投递成功不等于业务成功。
  • 资金金额和余额以钱包流水及对应业务表为权威Audit Event 仅用于解释谁做了什么,不用于资金重算。
  • 旧 operation log 仅由平台独立历史入口访问,不拼接到新 /api/admin/audit/*