From abf5ae52e525df2e38f599e048a820171b63fa25 Mon Sep 17 00:00:00 2001 From: Kris <2893855659@qq.com> Date: Sat, 11 Jul 2026 07:37:53 +0800 Subject: [PATCH] =?UTF-8?q?refactor(apis):=20=E7=AE=80=E5=8C=96=E6=97=A0?= =?UTF-8?q?=E5=8F=82API=E8=B0=83=E7=94=A8=E5=B9=B6=E6=9B=B4=E6=96=B0API?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 移除多个列表/统计API的默认空参数和buildQueryString调用,简化无参请求 2. 新增健康检查、测试通知渠道等API端点 3. 更新API注释文档,修正端点计数、废弃接口替换说明 4. 调整环境导出接口的权限为管理员权限并使用adminGet 5. 修正webhook接口的废弃端点替换和注释描述 --- .../external-systems/adapter_asset_api.js | 2 +- .../apis/external-systems/auth_plugin_api.js | 2 +- .../apis/external-systems/environment_api.js | 11 ++++----- .../notification_channel_api.js | 12 +++++++++- web/src/apis/external-systems/system_api.js | 2 +- web/src/apis/external-systems/token_api.js | 24 +++++++++++-------- web/src/apis/external-systems/tool_api.js | 8 ++++++- web/src/apis/external-systems/webhook_api.js | 15 ++++++------ 8 files changed, 48 insertions(+), 28 deletions(-) diff --git a/web/src/apis/external-systems/adapter_asset_api.js b/web/src/apis/external-systems/adapter_asset_api.js index 79927cfc..c046c31c 100644 --- a/web/src/apis/external-systems/adapter_asset_api.js +++ b/web/src/apis/external-systems/adapter_asset_api.js @@ -24,7 +24,7 @@ export const updateAssetApi = (id, data) => apiAdminPut(`${URL}/${id}`, data) export const deleteAssetApi = (id) => apiAdminDelete(`${URL}/${id}`) // ===== 统计与查询 ===== -export const getAssetStatsApi = (params = {}) => apiGet(`${URL}/stats${buildQueryString(params)}`) +export const getAssetStatsApi = () => apiGet(`${URL}/stats`) export const getAssetByChecksumApi = (checksum) => apiGet(`${URL}/by-checksum/${checksum}`) diff --git a/web/src/apis/external-systems/auth_plugin_api.js b/web/src/apis/external-systems/auth_plugin_api.js index 42152b64..7e046fac 100644 --- a/web/src/apis/external-systems/auth_plugin_api.js +++ b/web/src/apis/external-systems/auth_plugin_api.js @@ -16,7 +16,7 @@ import { buildUrl, buildQueryString, MODULE_PATHS } from './base' const URL = buildUrl(MODULE_PATHS.AUTH_PLUGIN) // ===== 列表与总览 ===== -export const getAuthPluginListApi = (params = {}) => apiGet(`${URL}${buildQueryString(params)}`) +export const getAuthPluginListApi = () => apiGet(URL) export const getAuthPluginOverviewApi = () => apiGet(`${URL}/overview`) // ===== Token 刷新策略 ===== diff --git a/web/src/apis/external-systems/environment_api.js b/web/src/apis/external-systems/environment_api.js index 6b5f908d..f1ece8d1 100644 --- a/web/src/apis/external-systems/environment_api.js +++ b/web/src/apis/external-systems/environment_api.js @@ -6,10 +6,10 @@ * - 几乎所有端点都要求 system_id 作为 query 参数(必填) * - set_default / test_connectivity 不接受请求体 * - set_enabled 请求体字段为 enabled(非 is_enabled) - * - export 返回 StreamingResponse,需用 blob 接收 - * - 查询类端点后端用 get_required_user(普通用户可访问),写操作用 get_admin_user + * - export 返回 StreamingResponse,需用 blob 接收;后端统一要求管理员权限(include_secrets 会泄露明文密钥) + * - 查询类端点后端用 get_required_user(普通用户可访问),写操作及 export 用 get_admin_user */ -import { apiGet, apiAdminPost, apiAdminPut, apiAdminDelete, apiAdminPatch } from '../base' +import { apiGet, apiAdminGet, apiAdminPost, apiAdminPut, apiAdminDelete, apiAdminPatch } from '../base' import { buildUrl, buildQueryString, MODULE_PATHS } from './base' const URL = buildUrl(MODULE_PATHS.ENVIRONMENT) @@ -61,12 +61,11 @@ export const testEnvironmentConnectivityApi = (id, systemId) => apiAdminPost(`${URL}/${id}/test-connectivity${buildQueryString({ system_id: systemId })}`) // ===== 导出与健康 ===== -// 后端 export_environment 返回 StreamingResponse(application/octet-stream) +// 后端 export_environment 返回 StreamingResponse,统一要求管理员权限(include_secrets 会泄露明文密钥) export const exportEnvironmentApi = (id, systemId, params = {}) => - apiGet( + apiAdminGet( `${URL}/${id}/export${buildQueryString({ system_id: systemId, ...params })}`, {}, - true, 'blob' ) export const getEnvironmentHealthApi = (id, systemId) => diff --git a/web/src/apis/external-systems/notification_channel_api.js b/web/src/apis/external-systems/notification_channel_api.js index 9fa1b57f..5846b9a0 100644 --- a/web/src/apis/external-systems/notification_channel_api.js +++ b/web/src/apis/external-systems/notification_channel_api.js @@ -1,5 +1,5 @@ /** - * 22-通知渠道 API(6 端点) + * 22-通知渠道 API(7 端点) * 路径前缀:/notification-channels * * 对齐后端 Router:backend/server/routers/external_systems/notification_channel_router.py @@ -7,6 +7,7 @@ * - 查询类端点(GET)后端用 get_required_user,前端用 apiGet * - 写操作(POST/PUT/DELETE)后端用 get_admin_user,前端用 apiAdmin* * - GET 列表参数通过 buildQueryString 拼接到 URL(apiGet 第二参数为 options,非 params) + * - test 端点不持久化,仅验证渠道配置是否正确 * * 响应字段契约(对齐 NotificationChannelOutput / NotificationChannelStatsOutput DTO): * - 列表项 / 详情:{ id, channel_type, name, config, enabled, description, @@ -61,3 +62,12 @@ export const updateNotificationChannelApi = (id, data) => apiAdminPut(`${URL}/${ * @param {number} id - 渠道主键 */ export const deleteNotificationChannelApi = (id) => apiAdminDelete(`${URL}/${id}`) + +// ===== 测试 ===== +/** + * 测试通知渠道连通性(不持久化,仅验证配置是否正确) + * @param {number} id - 渠道主键 + * @param {Object} [data] - { message? } 自定义测试消息内容 + */ +export const testNotificationChannelApi = (id, data = {}) => + apiAdminPost(`${URL}/${id}/test`, data) diff --git a/web/src/apis/external-systems/system_api.js b/web/src/apis/external-systems/system_api.js index 039473e1..65797ea6 100644 --- a/web/src/apis/external-systems/system_api.js +++ b/web/src/apis/external-systems/system_api.js @@ -26,7 +26,7 @@ export const deleteSystemApi = (id, cascade = false) => // ===== 导出与统计 ===== export const exportSystemsApi = (params = {}) => apiGet(`${URL}/export${buildQueryString(params)}`, {}, true, 'blob') -export const getSystemStatsApi = (params = {}) => apiGet(`${URL}/stats${buildQueryString(params)}`) +export const getSystemStatsApi = () => apiGet(`${URL}/stats`) // ===== 批量操作 ===== export const batchEnabledSystemsApi = (data) => apiAdminPost(`${URL}/batch-enabled`, data) diff --git a/web/src/apis/external-systems/token_api.js b/web/src/apis/external-systems/token_api.js index 1b6334dc..ff007e89 100644 --- a/web/src/apis/external-systems/token_api.js +++ b/web/src/apis/external-systems/token_api.js @@ -9,7 +9,11 @@ * - 静态路径(/stats、/history、/invalidate-environment、/expiring)必须在动态路径 /{token_id} 之前声明 * - access_token / refresh_token 后端默认脱敏为 "***",前端无需额外处理 * - history 端点按 system_id 查询审计日志,返回 list[TokenHistoryItem](Token 字段 + 审计元数据,非审计日志原始对象) - * - usage 端点当前返回空列表占位(list[dict],未实现使用记录采集) + * - usage 端点基于 ExternalToolExecution 表按 (system_id, env_key) 关联查询,返回工具执行记录摘要 + * - stats 端点支持 expiring_days 参数控制 expiring_soon 阈值;返回字段含 expired(已过期未失效) + * - detail 端点返回 system_name/system_slug 关联系统上下文 + * - rotation-preview 端点返回 token_status + affected_policies(密钥轮换策略) + * - invalidate 端点幂等:已失效的 Token 返回 409 ConflictError */ import { apiGet, apiAdminPost } from '../base' import { buildUrl, buildQueryString, MODULE_PATHS } from './base' @@ -17,30 +21,30 @@ import { buildUrl, buildQueryString, MODULE_PATHS } from './base' const URL = buildUrl(MODULE_PATHS.TOKEN) // ===== 列表与详情 ===== -/** 分页列出 Token(支持 system_id/env_key/token_type/is_invalidated 过滤) */ +/** 分页列出 Token(支持 system_id/env_key/token_type/is_invalidated 过滤,DB 层下推) */ export const getTokenListApi = (params = {}) => apiGet(`${URL}${buildQueryString(params)}`) -/** 获取 Token 详情(access_token/refresh_token 脱敏) */ +/** 获取 Token 详情(access_token/refresh_token 脱敏,含 system_name/system_slug 上下文) */ export const getTokenDetailApi = (id) => apiGet(`${URL}/${id}`) // ===== 失效管理 ===== -/** 失效单条 Token(admin 权限,无 Body) */ +/** 失效单条 Token(admin 权限,幂等,已失效返回 409) */ export const invalidateTokenApi = (id) => apiAdminPost(`${URL}/${id}/invalidate`) -/** 按环境失效 Token(admin 权限,Body: {system_id, env_key}) */ +/** 按环境失效 Token(admin 权限,幂等,Body: {system_id, env_key}) */ export const invalidateEnvironmentTokensApi = (data) => apiAdminPost(`${URL}/invalidate-environment`, data) // ===== 使用与轮换预览 ===== -/** 查询 Token 使用记录(当前返回空列表占位) */ +/** 查询 Token 使用记录(基于 ExternalToolExecution 关联查询) */ export const getTokenUsageApi = (id, params = {}) => apiGet(`${URL}/${id}/usage${buildQueryString(params)}`) -/** 轮换影响范围预览(只读,返回受影响的系统/环境/工具) */ +/** 轮换影响范围预览(只读,返回 token_status + 受影响的系统/环境/工具/密钥轮换策略) */ export const getTokenRotationPreviewApi = (id) => apiGet(`${URL}/${id}/rotation-preview`) // ===== 统计与历史 ===== -/** 查询 Token 统计(4 状态分组计数:active/expiring_soon/invalidated/total) */ +/** 查询 Token 统计(5 状态分组:total/active/invalidated/expired/expiring_soon,支持 expiring_days 阈值) */ export const getTokenStatsApi = (params = {}) => apiGet(`${URL}/stats${buildQueryString(params)}`) -/** 查询 Token 变更历史(system_id 必填,基于审计日志) */ +/** 查询 Token 变更历史(system_id 必填,基于审计日志,含刷新成功/失败事件) */ export const getTokenHistoryApi = (params = {}) => apiGet(`${URL}/history${buildQueryString(params)}`) // ===== 过期预警 ===== -/** 查询即将过期的 Token(days 默认 7,范围 1-90) */ +/** 查询即将过期的 Token(days 默认 7,范围 1-90,system_id 透传 DB 层过滤) */ export const getExpiringTokensApi = (params = {}) => apiGet(`${URL}/expiring${buildQueryString(params)}`) diff --git a/web/src/apis/external-systems/tool_api.js b/web/src/apis/external-systems/tool_api.js index b3887975..1a2de2e6 100644 --- a/web/src/apis/external-systems/tool_api.js +++ b/web/src/apis/external-systems/tool_api.js @@ -1,5 +1,5 @@ /** - * 02-工具管理 API(21 端点) + * 02-工具管理 API(22 端点) * 路径前缀:/tools * * 对齐 backend/server/routers/external_systems/tool_router.py: @@ -8,6 +8,7 @@ * - get_tool / delete_tool 接受可选 system_id query * - export-wsdl 后端返回普通 JSON(非 StreamingResponse),system_id 必填 * - export 后端返回 StreamingResponse,需用 blob 接收 + * - health-check 后端用 get_admin_user,请求体可选 env_key */ import { apiGet, apiPost, apiAdminPost, apiAdminPut, apiAdminDelete } from '../base' import { buildUrl, buildQueryString, MODULE_PATHS } from './base' @@ -43,6 +44,11 @@ export const importToolsFromWsdlApi = (data) => apiAdminPost(`${URL}/import-from export const executeToolApi = (data) => apiPost(`${URL}/execute`, data) export const batchExecuteToolsApi = (data) => apiPost(`${URL}/batch-execute`, data) +// ===== 健康检查 ===== +// 后端 health_check_external_tool 用 get_admin_user,请求体可选 env_key +export const healthCheckToolApi = (id, data = {}) => + apiAdminPost(`${URL}/${id}/health-check`, data) + // ===== 批量克隆 ===== export const batchCloneToolsApi = (data) => apiAdminPost(`${URL}/batch-clone`, data) diff --git a/web/src/apis/external-systems/webhook_api.js b/web/src/apis/external-systems/webhook_api.js index 2f3473c0..f6bc994f 100644 --- a/web/src/apis/external-systems/webhook_api.js +++ b/web/src/apis/external-systems/webhook_api.js @@ -1,15 +1,16 @@ /** - * 12-Webhook 管理 API(20 端点) + * 12-Webhook 管理 API(19 端点) * 路径前缀:/webhooks * * 对齐后端 Router:backend/server/routers/external_systems/webhook_router.py + * 后端共 21 个端点,前端导出 19 个:排除无认证回调 POST /events 和已废弃的 GET /events/{id}/deliveries * * 关键对齐点: * - GET 端点(subscriptions / events / failed / expiring / renewal-failures / - * detail / deliveries / filter-rules / transform-rules)均用 get_required_user → apiGet + * detail / processing-status / filter-rules / transform-rules)均用 get_required_user → apiGet * - POST / PUT / DELETE 端点均用 get_admin_user → apiAdminPost / apiAdminPut / apiAdminDelete * - 带 params 的 GET 请求通过 buildQueryString 拼接(apiGet 第二参数是 fetch options) - * - POST /events 为外部系统回调入口(无认证),前端不调用,故本文件导出 19 个前端可用端点 + * - 后端 /events/{id}/deliveries 已废弃,统一使用 /events/{id}/processing-status * - 后端响应均为 dict(JSON),无 StreamingResponse,无需 'blob' */ import { apiGet, apiAdminPost, apiAdminPut, apiAdminDelete } from '../base' @@ -67,16 +68,16 @@ export const testWebhookSubscriptionApi = (id, data) => export const verifyWebhookSignatureApi = (id, data) => apiAdminPost(`${URL}/subscriptions/${id}/verify-signature`, data) -// ===== 事件列表 / 失败事件 / 投递历史 ===== +// ===== 事件列表 / 失败事件 / 处理状态 ===== /** 分页列出 Webhook 事件 */ export const getWebhookEventListApi = (params = {}) => apiGet(`${URL}/events${buildQueryString(params)}`) /** 列出处理失败的 Webhook 事件 */ export const getFailedWebhookEventsApi = (params = {}) => apiGet(`${URL}/events/failed${buildQueryString(params)}`) -/** 查询 Webhook 事件投递历史 */ -export const getWebhookEventDeliveriesApi = (id) => - apiGet(`${URL}/events/${id}/deliveries`) +/** 查询 Webhook 事件处理状态(替代已废弃的 /deliveries 端点) */ +export const getWebhookEventProcessingStatusApi = (id) => + apiGet(`${URL}/events/${id}/processing-status`) // ===== 事件重放 ===== /** 重放 Webhook 事件 */