实现 SourceMessage Inbox 与 AgentBus 入站闭环

This commit is contained in:
andy
2026-07-06 21:23:57 +08:00
parent 5a498635d8
commit 7e276469ef
75 changed files with 4608 additions and 27 deletions

View File

@@ -0,0 +1,36 @@
spring:
application:
name: th-hotel-server
datasource:
url: ${TH_HOTEL_DB_URL:jdbc:h2:mem:th_hotel;MODE=MySQL;DATABASE_TO_LOWER=TRUE;CASE_INSENSITIVE_IDENTIFIERS=TRUE}
username: ${TH_HOTEL_DB_USERNAME:sa}
password: ${TH_HOTEL_DB_PASSWORD:}
driver-class-name: ${TH_HOTEL_DB_DRIVER:org.h2.Driver}
flyway:
enabled: true
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
global-config:
banner: false
source-message:
original-read:
access-key: ${SOURCE_MESSAGE_ORIGINAL_READ_ACCESS_KEY:}
agentbus:
probe:
enabled: ${AGENTBUS_PROBE_ENABLED:false}
ws:
url: ${AGENTBUS_WS_URL:wss://mesh.nianxx.cn/ws}
token: ${AGENTBUS_WS_TOKEN:}
reconnect-delay: ${AGENTBUS_WS_RECONNECT_DELAY:5s}
connect-timeout: ${AGENTBUS_CONNECT_TIMEOUT:15s}
max-frame-bytes: ${AGENTBUS_MAX_FRAME_BYTES:1048576}
capture:
enabled: ${AGENTBUS_CAPTURE_ENABLED:true}
default-hotel-id: ${AGENTBUS_DEFAULT_HOTEL_ID:HOTEL-TEST}
server:
port: ${SERVER_PORT:8080}

View File

@@ -0,0 +1,68 @@
-- M001 SourceMessage Inbox来源消息索引表保存单封邮件的幂等键、状态和安全摘要。
CREATE TABLE platform_source_message_inbox (
id BIGINT NOT NULL COMMENT '本项目内部 SourceMessage ID供后续业务流程关联来源邮件',
hotel_id VARCHAR(64) NOT NULL COMMENT '酒店或业务上下文 ID避免不同酒店外部邮件 ID 冲突',
provider VARCHAR(32) NOT NULL COMMENT '来源提供方稳定代码,例如 AGENTBUS',
channel VARCHAR(32) NOT NULL COMMENT '来源渠道稳定代码,例如 EMAIL',
external_message_id VARCHAR(256) NULL COMMENT '外部邮件系统中的单封邮件唯一 ID对应 AgentBus source.external_message_id解析失败时允许为空以保留失败记录',
external_conversation_id VARCHAR(256) NULL COMMENT '外部邮件链或会话 ID对应 AgentBus source.external_conversation_id',
provider_frame_id VARCHAR(128) NULL COMMENT 'AgentBus frame ID仅用于排查推送帧不作为邮件唯一 ID',
provider_session_id VARCHAR(128) NULL COMMENT 'AgentBus session ID仅用于排查连接会话不作为邮件链 ID',
payload_sha256 CHAR(64) NOT NULL COMMENT '规范 JSON 的 SHA-256 哈希,用于排查重复投递 payload 是否变化',
capture_status VARCHAR(32) NOT NULL COMMENT '捕获状态,第一阶段使用 RECEIVED 或 FAILED',
duplicate_payload_changed TINYINT(1) NOT NULL DEFAULT 0 COMMENT '重复投递命中时 payload 是否与首次保存内容不同',
safe_error_summary VARCHAR(512) NULL COMMENT '安全错误摘要不包含正文、HTML、附件 URL、Token 或个人敏感信息',
received_at DATETIME(6) NOT NULL COMMENT '本项目接收时间,按 UTC 写入',
source_sent_at DATETIME(6) NULL COMMENT '邮件来源发送时间payload 提供时保存,按 UTC 写入',
sender_summary VARCHAR(256) NULL COMMENT '发送人安全摘要,列表可展示,不保存完整敏感展示值',
subject VARCHAR(512) NULL COMMENT '邮件主题,作为安全摘要字段展示',
safe_snippet VARCHAR(512) NULL COMMENT '邮件安全短摘要不包含完整正文、HTML、附件 URL 或敏感凭证',
created_at DATETIME(6) NOT NULL COMMENT '记录创建时间,按 UTC 写入',
updated_at DATETIME(6) NOT NULL COMMENT '记录更新时间,按 UTC 写入',
PRIMARY KEY (id),
UNIQUE KEY uk_source_message_inbox_idempotency (hotel_id, provider, channel, external_message_id),
KEY idx_source_message_inbox_conversation (hotel_id, external_conversation_id),
KEY idx_source_message_inbox_status_time (hotel_id, capture_status, received_at)
) COMMENT='SourceMessage Inbox 来源消息索引表,保存邮件来源事实的幂等键、状态和安全摘要';
-- M001 SourceMessage Inbox原始载荷表保存 AgentBus 规范 JSON用于追溯和排查。
CREATE TABLE platform_source_message_payload (
id BIGINT NOT NULL COMMENT '原始载荷记录 ID',
inbox_id BIGINT NOT NULL COMMENT '所属 SourceMessage Inbox 记录 ID',
payload_json LONGTEXT NOT NULL COMMENT 'AgentBus 规范 JSON 原始载荷,普通查询接口不得返回',
payload_sha256 CHAR(64) NOT NULL COMMENT 'payload_json 的 SHA-256 哈希',
schema_version VARCHAR(64) NULL COMMENT 'payload 结构版本AgentBus 有提供则保存,否则使用本项目捕获版本',
created_at DATETIME(6) NOT NULL COMMENT '记录创建时间,按 UTC 写入',
PRIMARY KEY (id),
UNIQUE KEY uk_source_message_payload_inbox (inbox_id),
KEY idx_source_message_payload_hash (payload_sha256)
) COMMENT='SourceMessage 原始载荷表,用于追溯、排查和后续受控重新处理';
-- M001 SourceMessage Inbox正文表正文只通过后续受控原文读取接口返回。
CREATE TABLE platform_source_message_body (
id BIGINT NOT NULL COMMENT '正文记录 ID',
inbox_id BIGINT NOT NULL COMMENT '所属 SourceMessage Inbox 记录 ID',
content_type VARCHAR(32) NOT NULL COMMENT '正文类型,例如 TEXT、HTML、MIXED',
text_body LONGTEXT NULL COMMENT '纯文本正文,用于摘要、搜索和后续 AI 处理',
html_body LONGTEXT NULL COMMENT 'HTML 原文,前端展示前必须 sanitize',
body_sha256 CHAR(64) NOT NULL COMMENT '正文内容 SHA-256 哈希,用于排查正文是否变化',
created_at DATETIME(6) NOT NULL COMMENT '记录创建时间,按 UTC 写入',
PRIMARY KEY (id),
UNIQUE KEY uk_source_message_body_inbox (inbox_id)
) COMMENT='SourceMessage 正文表,保存 text/html 正文,普通查询接口不得返回';
-- M001 SourceMessage Inbox媒体引用表只保存 AgentBus 已处理好的长期有效 URL不下载文件。
CREATE TABLE platform_source_message_media (
id BIGINT NOT NULL COMMENT '媒体引用记录 ID',
inbox_id BIGINT NOT NULL COMMENT '所属 SourceMessage Inbox 记录 ID',
media_type VARCHAR(32) NOT NULL COMMENT '媒体类型INLINE_IMAGE 表示正文图片ATTACHMENT 表示附件',
file_name VARCHAR(512) NULL COMMENT '文件名,附件通常有,正文图片可能为空',
content_type VARCHAR(128) NULL COMMENT '媒体 MIME 类型,例如 image/png 或 application/pdf',
size_bytes BIGINT NULL COMMENT '文件大小字节数AgentBus 有返回则保存,没有则为空',
external_url VARCHAR(2048) NOT NULL COMMENT 'AgentBus 返回的长期有效访问 URL只能通过受控原文读取接口返回',
external_media_id VARCHAR(256) NULL COMMENT 'AgentBus 或邮件系统中的媒体 ID用于排查和追溯',
created_at DATETIME(6) NOT NULL COMMENT '记录创建时间,按 UTC 写入',
PRIMARY KEY (id),
KEY idx_source_message_media_inbox (inbox_id),
KEY idx_source_message_media_type (inbox_id, media_type)
) COMMENT='SourceMessage 媒体引用表,保存正文图片和附件 URL 引用,不保存二进制文件';

View File

@@ -0,0 +1,13 @@
-- M001 checkpoint 2原文读取访问审计记录谁在什么场景读取了 SourceMessage 原文。
CREATE TABLE platform_source_message_original_access_audit (
id BIGINT NOT NULL COMMENT '原文读取审计记录 ID',
inbox_id BIGINT NOT NULL COMMENT '被读取的 SourceMessage Inbox ID',
actor_id VARCHAR(128) NOT NULL COMMENT '读取原文的调用方或操作者标识,初期由受控请求头传入',
access_scene VARCHAR(128) NOT NULL COMMENT '读取原文的业务或运维场景,例如 reservation-detail 或 agentbus-debug',
access_result VARCHAR(32) NOT NULL COMMENT '访问结果稳定代码,当前使用 GRANTED 表示已授权读取',
accessed_at DATETIME(6) NOT NULL COMMENT '原文读取发生时间,按 UTC 写入',
created_at DATETIME(6) NOT NULL COMMENT '审计记录创建时间,按 UTC 写入',
PRIMARY KEY (id),
KEY idx_source_message_original_access_inbox (inbox_id, accessed_at),
KEY idx_source_message_original_access_actor (actor_id, accessed_at)
) COMMENT='SourceMessage 原文读取访问审计表,记录受控原文读取行为';