diff --git a/backend/server/routers/external_systems/alert_router.py b/backend/server/routers/external_systems/alert_router.py index eb1f8998..9413b6d9 100644 --- a/backend/server/routers/external_systems/alert_router.py +++ b/backend/server/routers/external_systems/alert_router.py @@ -232,7 +232,10 @@ async def fire_alert( ) -> dict[str, Any]: """触发告警事件。""" use_cases = create_use_cases_from_db(db) - input_dto = FireAlertInput(**payload.model_dump()) + input_dto = FireAlertInput( + **payload.model_dump(), + triggered_by=current_user.uid, + ) output = await use_cases.alert_service.fire_alert(input_dto) return {"success": True, "data": output.model_dump()} diff --git a/backend/server/routers/external_systems/dashboard_router.py b/backend/server/routers/external_systems/dashboard_router.py index 0080ceae..a002fc19 100644 --- a/backend/server/routers/external_systems/dashboard_router.py +++ b/backend/server/routers/external_systems/dashboard_router.py @@ -20,7 +20,7 @@ from typing import Any, Literal from fastapi import APIRouter, Depends, Query from sqlalchemy.ext.asyncio import AsyncSession -from yuxi.external_systems.infrastructure.container import create_use_cases_from_db +from yuxi.external_systems.infrastructure.container import create_dashboard_service_from_db from yuxi.external_systems.use_cases.dto.dashboard import ( GetActivitiesStatsInput, GetAlertsStatsInput, @@ -48,9 +48,9 @@ async def get_overview( current_user: User = Depends(get_required_user), ) -> dict[str, Any]: """全局总览。聚合 5 个子域的关键指标。""" - use_cases = create_use_cases_from_db(db) + dashboard_service = create_dashboard_service_from_db(db) input_dto = GetOverviewInput(start=start_time, end=end_time) - output = await use_cases.dashboard_service.get_overview(input_dto) + output = await dashboard_service.get_overview(input_dto) return {"success": True, "data": output.model_dump()} @@ -60,9 +60,9 @@ async def get_systems_stats( current_user: User = Depends(get_required_user), ) -> dict[str, Any]: """系统维度统计。含启用状态/适配器类型/分类分组 + 熔断器状态。""" - use_cases = create_use_cases_from_db(db) + dashboard_service = create_dashboard_service_from_db(db) input_dto = GetSystemsStatsInput() - output = await use_cases.dashboard_service.get_systems_stats(input_dto) + output = await dashboard_service.get_systems_stats(input_dto) return {"success": True, "data": output.model_dump()} @@ -75,13 +75,13 @@ async def get_executions_stats( current_user: User = Depends(get_required_user), ) -> dict[str, Any]: """执行维度统计。含按状态/工具分组。""" - use_cases = create_use_cases_from_db(db) + dashboard_service = create_dashboard_service_from_db(db) input_dto = GetExecutionsStatsInput( start=start_time, end=end_time, tool_limit=tool_limit, ) - output = await use_cases.dashboard_service.get_executions_stats(input_dto) + output = await dashboard_service.get_executions_stats(input_dto) return {"success": True, "data": output.model_dump()} @@ -96,12 +96,12 @@ async def get_alerts_stats( current_user: User = Depends(get_required_user), ) -> dict[str, Any]: """告警维度统计。含按状态/严重程度分组 + Top 告警去重键。""" - use_cases = create_use_cases_from_db(db) + dashboard_service = create_dashboard_service_from_db(db) input_dto = GetAlertsStatsInput( severity_status=severity_status, top_limit=top_limit, ) - output = await use_cases.dashboard_service.get_alerts_stats(input_dto) + output = await dashboard_service.get_alerts_stats(input_dto) return {"success": True, "data": output.model_dump()} @@ -113,12 +113,12 @@ async def get_quotas_stats( current_user: User = Depends(get_required_user), ) -> dict[str, Any]: """配额维度统计。含按窗口分组 + 预警/临界配额明细。""" - use_cases = create_use_cases_from_db(db) + dashboard_service = create_dashboard_service_from_db(db) input_dto = GetQuotasStatsInput( warning_limit=warning_limit, critical_limit=critical_limit, ) - output = await use_cases.dashboard_service.get_quotas_stats(input_dto) + output = await dashboard_service.get_quotas_stats(input_dto) return {"success": True, "data": output.model_dump()} @@ -128,9 +128,9 @@ async def get_health_stats( current_user: User = Depends(get_required_user), ) -> dict[str, Any]: """健康维度统计。含按健康状态分组。""" - use_cases = create_use_cases_from_db(db) + dashboard_service = create_dashboard_service_from_db(db) input_dto = GetHealthStatsInput() - output = await use_cases.dashboard_service.get_health_stats(input_dto) + output = await dashboard_service.get_health_stats(input_dto) return {"success": True, "data": output.model_dump()} @@ -142,7 +142,7 @@ async def get_activities_stats( current_user: User = Depends(get_required_user), ) -> dict[str, Any]: """活动维度统计。含按操作类型分组。""" - use_cases = create_use_cases_from_db(db) + dashboard_service = create_dashboard_service_from_db(db) input_dto = GetActivitiesStatsInput(start=start_time, end=end_time) - output = await use_cases.dashboard_service.get_activities_stats(input_dto) + output = await dashboard_service.get_activities_stats(input_dto) return {"success": True, "data": output.model_dump()} diff --git a/backend/server/routers/external_systems/environment_router.py b/backend/server/routers/external_systems/environment_router.py index 68a42969..24d2775c 100644 --- a/backend/server/routers/external_systems/environment_router.py +++ b/backend/server/routers/external_systems/environment_router.py @@ -364,7 +364,7 @@ async def delete_environment( ) -> dict[str, Any]: """删除环境。""" use_cases = create_use_cases_from_db(db) - input_dto = DeleteEnvironmentInput(id=env_id, system_id=system_id) + input_dto = DeleteEnvironmentInput(id=env_id, system_id=system_id, deleted_by=current_user.uid) output = await use_cases.environment_service.delete_environment(input_dto) return {"success": True, "data": output.model_dump()} diff --git a/backend/server/routers/external_systems/execution_router.py b/backend/server/routers/external_systems/execution_router.py index cc0b60a4..5cce02f5 100644 --- a/backend/server/routers/external_systems/execution_router.py +++ b/backend/server/routers/external_systems/execution_router.py @@ -330,7 +330,11 @@ async def retry_execution( db: AsyncSession = Depends(get_db), current_user: User = Depends(get_admin_user), ) -> dict[str, Any]: - """重试执行(管理员)。caller / caller_id 均使用当前管理员 uid。""" + """重试执行(管理员)。 + + ``caller`` / ``caller_id`` 均使用当前管理员 uid,用于审计日志。 + 执行记录的 ``caller`` 由 service 层固定为 ``retry``,确保重试语义准确。 + """ use_cases = create_use_cases_from_db(db) input_dto = RetryExecutionInput( execution_id=execution_id, diff --git a/backend/server/routers/external_systems/system_router.py b/backend/server/routers/external_systems/system_router.py index 3dc377b1..018bc367 100644 --- a/backend/server/routers/external_systems/system_router.py +++ b/backend/server/routers/external_systems/system_router.py @@ -382,7 +382,7 @@ async def delete_system( ) -> dict[str, Any]: """删除外部系统。""" use_cases = create_use_cases_from_db(db) - input_dto = DeleteSystemInput(id=system_id, cascade=cascade) + input_dto = DeleteSystemInput(id=system_id, cascade=cascade, deleted_by=current_user.uid) output = await use_cases.system_service.delete_system(input_dto) return {"success": True, "data": output.model_dump()} diff --git a/backend/server/routers/external_systems/tool_router.py b/backend/server/routers/external_systems/tool_router.py index 788ac6c4..386997eb 100644 --- a/backend/server/routers/external_systems/tool_router.py +++ b/backend/server/routers/external_systems/tool_router.py @@ -37,6 +37,7 @@ from yuxi.external_systems.use_cases.dto.tool import ( GetToolInput, GetToolParameterTemplateInput, GetToolVersionsInput, + HealthCheckToolInput, ImportWsdlInput, ListToolOptionsInput, ListToolsInput, @@ -160,6 +161,14 @@ class ExecuteToolRequest(BaseModel): tags: dict[str, Any] = Field(default_factory=dict) +class HealthCheckToolRequest(BaseModel): + """触发工具健康检查请求体。字段对齐 ``HealthCheckToolInput``。""" + + model_config = ConfigDict(frozen=True) + + env_key: str | None = Field(default=None, max_length=32) + + class BatchExecuteToolItemRequest(BaseModel): """批量执行工具项请求体。字段对齐 ``BatchExecuteToolItem``。""" @@ -336,6 +345,27 @@ async def execute_external_tool( return {"success": True, "data": output.model_dump()} +@tool_router.post("/{tool_slug}/health-check", response_model=dict) +async def health_check_external_tool( + tool_slug: str, + body: HealthCheckToolRequest | None = None, + db: AsyncSession = Depends(get_db), + current_user: User = Depends(get_required_user), +) -> dict[str, Any]: + """触发单个外部工具健康检查。 + + 仅对 system_id 不为 None 的系统级工具持久化结果到 ``ext_system_health_checks``; + 工具级工具仅返回探测结果。 + """ + use_cases = create_use_cases_from_db(db) + input_dto = HealthCheckToolInput( + tool_slug=tool_slug, + env_key=body.env_key if body is not None else None, + ) + output = await use_cases.tool_service.health_check_external_tool(input_dto) + return {"success": True, "data": output.model_dump()} + + @tool_router.post("/batch-execute", response_model=dict) async def batch_execute_tools( body: BatchExecuteToolsRequest, @@ -469,7 +499,7 @@ async def delete_tool( ) -> dict[str, Any]: """删除外部工具。""" use_cases = create_use_cases_from_db(db) - input_dto = DeleteToolInput(id=tool_id, system_id=system_id) + input_dto = DeleteToolInput(id=tool_id, system_id=system_id, deleted_by=current_user.uid) output = await use_cases.tool_service.delete_tool(input_dto) return {"success": True, "data": output.model_dump()}