safesight-control/docs/superpowers/specs/2026-04-29-third-party-services-design.md

367 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 第三方服务结构化设计
## 背景
当前后台已经将配置相关能力拆分为两层:
- `场景配置`:定义一个最终要运行的业务场景
- `基础配置`:承载场景配置引用的公共配置
在现有项目中,第三方服务相关配置仍然散落在模板参数中,没有独立的结构和复用关系。当前已确认存在的第三方服务参数包括:
- 对象存储:`minio_endpoint`、`minio_bucket`、`minio_access_key`、`minio_secret_key`
- 认证服务:`external_get_token_url`
- 告警服务:`external_put_message_url`
- 租户字段:`tenant_code`
这些配置本质上不是某个单独场景私有的内容,而是会被多个场景反复引用的基础服务配置。继续把它们直接放在模板或场景参数里,会带来几个问题:
- 相同服务地址和密钥在多个场景中重复填写
- 修改服务地址或凭据时,需要逐个场景同步修改
- 难以判断某个第三方服务被哪些场景使用
- 服务配置与识别模板逻辑混在一起,页面职责不清楚
因此,这一轮设计的目标是把“第三方服务”独立为一类可复用的基础配置。
## 目标
本次设计只解决下面这些问题:
1. 为第三方服务建立统一、结构化的数据模型
2.`基础配置` 中提供独立的 `第三方服务` 管理入口
3.`场景配置` 通过引用第三方服务完成配置,而不是直接填写服务参数
4. 在生成最终 agent 配置时,将服务引用展开为现有模板参数
## 非目标
本次不包含以下内容:
- 不引入多环境字段,如 `prod / test`
- 不引入适用范围字段,如客户 / 项目 / 站点
- 不做复杂权限模型
- 不做服务连通性探测
- 不做密码加密存储方案升级
- 不支持自定义服务类型
第一版只覆盖项目中已经真实存在的三类第三方服务。
## 服务类型
第一版支持以下三种服务类型:
1. `object_storage`:对象存储
2. `token_service`:认证服务
3. `alarm_service`:告警服务
页面文案使用中文:
- 对象存储
- 认证服务
- 告警服务
## 数据模型
### 顶层公共字段
所有第三方服务共享以下字段:
- `name`:服务名称,唯一标识
- `type`:服务类型
- `description`:描述
- `enabled`:是否启用
- `config`:按服务类型存储的结构化字段
推荐的数据结构如下:
```json
{
"name": "minio_prod_main",
"type": "object_storage",
"description": "主对象存储",
"enabled": true,
"config": {
"endpoint": "http://10.0.0.49:9000",
"bucket": "myminio",
"access_key": "admin",
"secret_key": "password"
}
}
```
这种设计的关键点是:
- 顶层字段保持简单,便于列表展示和统一管理
- 类型差异收纳在 `config` 中,避免一张平表容纳所有服务字段
- 后续增加新服务类型时,不需要推翻已有结构
### 类型字段
#### 对象存储
字段:
- `endpoint`
- `bucket`
- `access_key`
- `secret_key`
#### 认证服务
字段:
- `get_token_url`
- `username`
- `password`
- `tenant_code`
#### 告警服务
字段:
- `put_message_url`
- `username`
- `password`
- `tenant_code`
## 与现有模板参数的映射
为了兼容当前 agent 模板,第三方服务字段需要在预览和下发阶段映射回模板参数。
映射关系如下:
### 对象存储
- `config.endpoint` -> `minio_endpoint`
- `config.bucket` -> `minio_bucket`
- `config.access_key` -> `minio_access_key`
- `config.secret_key` -> `minio_secret_key`
### 认证服务
- `config.get_token_url` -> `external_get_token_url`
- `config.tenant_code` -> `tenant_code`
### 告警服务
- `config.put_message_url` -> `external_put_message_url`
- `config.tenant_code` -> `tenant_code`
说明:
- `username``password` 在第一版中先作为结构化存储字段保留
- 是否映射到模板参数,取决于具体模板是否已经定义对应参数
- 如果当前模板没有用到用户名和密码,这两个字段暂时只在后台维护,不强制写入模板参数
## 场景配置中的引用方式
场景配置不再直接保存第三方服务的 URL、密钥和租户字段而是保存服务引用。
建议增加以下引用字段:
- `object_storage_ref`
- `token_service_ref`
- `alarm_service_ref`
示例:
```json
{
"object_storage_ref": "minio_prod_main",
"token_service_ref": "token_service_prod",
"alarm_service_ref": "alarm_center_prod"
}
```
这样做的好处是:
- 多个场景可以复用同一组基础服务
- 修改服务地址或凭据时,无需逐个调整场景
- 后台可以反查“某个服务被哪些场景引用”
- 场景配置页面更聚焦于业务场景本身,而不是堆满连接参数
## 预览与下发的数据流
生成最终 agent 配置时,数据流按以下顺序处理:
1. 读取场景配置
2. 解析场景中引用的第三方服务名称
3. 加载对应第三方服务配置
4. 按服务类型展开为模板参数
5. 合并模板默认参数、场景参数、调试参数和第三方服务参数
6. 生成最终配置预览或下发内容
参数优先级建议保持清晰:
1. 模板默认参数
2. 场景配置显式参数
3. 第三方服务展开参数
4. 调试参数覆盖
如果同名字段冲突,后面的层级覆盖前面的层级。
## 存储设计
后台当前 `assets_repo` 已经持久化模板、场景配置和调试参数。第一版建议延续这个模式,为第三方服务新增独立存储。
建议新增一类持久化对象:
- 表名可使用 `integration_services`
每条记录至少包含:
- `name`
- `type`
- `description`
- `enabled`
- `config_json`
- `created_at`
- `updated_at`
其中 `config_json` 保存类型字段。
这样可以避免在数据库层为三类服务各建一张表,保持实现简单,同时保留后续扩展空间。
## 后端结构建议
建议在服务层新增一个明确模型,例如:
```go
type ThirdPartyServiceAsset struct {
Name string
Type string
Description string
Enabled bool
Config map[string]any
}
```
如果后续需要更强约束,可以进一步拆出按类型的辅助结构,但第一版不必过度设计。
建议新增以下能力:
- 列表读取
- 单项读取
- 新建 / 编辑 / 删除
- 引用计数查询
- 按场景展开为模板参数
## UI 设计
### 入口位置
主入口保持在:
- `基础配置 -> 第三方服务`
### 列表页
列表页先展示最重要的信息,字段建议如下:
- 服务名称
- 服务类型
- 描述
- 地址摘要
- 启用状态
- 引用数量
地址摘要按类型生成:
- 对象存储:显示 `endpoint / bucket`
- 认证服务:显示 `get_token_url`
- 告警服务:显示 `put_message_url`
这样用户可以快速判断服务是做什么的,以及是否大致配置正确。
### 详情 / 编辑页
详情和编辑页分为两块:
1. 基本信息
- 名称
- 类型
- 描述
- 启用状态
2. 服务配置
- 根据服务类型显示不同字段
字段展示规则:
- 密码和 `secret_key` 默认掩码显示
- 列表页不展示敏感字段
- 类型切换时动态切换表单字段
## 校验规则
### 通用校验
- 名称不能为空
- 名称必须唯一
- 类型不能为空
### 对象存储校验
- `endpoint` 必填
- `bucket` 必填
- `access_key` 必填
- `secret_key` 必填
### 认证服务校验
- `get_token_url` 必填
- `tenant_code` 可选
- `username`、`password` 可选
### 告警服务校验
- `put_message_url` 必填
- `tenant_code` 可选
- `username`、`password` 可选
## 删除与引用约束
第三方服务被场景配置引用时,不应允许直接删除。
删除前需要检查:
- 是否有场景配置正在引用该服务
如果存在引用,应提示:
- 当前服务已被某些场景配置使用,不能删除
这与模板删除前检查引用的现有交互保持一致。
## 第一阶段实施范围
第一阶段只实现以下能力:
1. 第三方服务的数据结构和存储
2. `基础配置 -> 第三方服务` 列表与详情编辑
3. 场景配置对第三方服务的引用
4. 配置预览与下发时的参数展开
5. 删除前引用检查
## 后续扩展方向
本设计为后续扩展保留空间,但不在第一阶段实现:
- 新增更多服务类型,如 MQTT、Kafka、Webhook
- 服务连通性测试按钮
- 敏感字段加密存储
- 按客户或项目进行服务分组
- 服务变更审计
## 结论
第三方服务应当被视为一类可复用的基础配置,而不是模板参数的零散集合。
通过引入独立的第三方服务结构:
- 可以降低场景配置的重复录入
- 可以集中管理 URL、租户和凭据
- 可以让模板、场景和服务的职责分离
- 可以为后续更完整的配置治理打下基础
第一版只支持对象存储、认证服务、告警服务三类,已经足够覆盖当前项目里的真实需求,并且能与现有 agent 模板参数平滑兼容。