feat(admin-web,backend): F1-5b Wave B UI-3 + UI-5 admin-web sandbox 透出补强 (W1)

UI-3 AIDashboard sandbox 提示 + today_calls 分组:
- 后端 schemas/admin_ai.py DashboardResponse 加 today_live_calls / today_sandbox_calls 字段(默认 0,向后兼容)
- 后端 services/ai/admin_service.py _get_range_stats SELECT 加 2 个 FILTER COUNT 表达式
- 前端 api/adminAI.ts DashboardResponse 类型补 2 字段
- 前端 pages/AIDashboard.tsx
  - 顶部加 sandbox Alert 提示条,选中 site sandbox 模式下显示业务日 + 实例 ID
  - today_calls 卡片下方加分组 Tag(实时 X / 沙箱 Y),feature flag 控制
  - import fetchRuntimeContext + useEffect 拉 RuntimeContext
- apps/admin-web/.env.example 新建,加 VITE_AI_RUNTIME_GROUPING=false 默认值说明

UI-5 AITriggerJobs runtime 列:
- 后端 schemas/admin_ai.py TriggerJobItem 加 runtime_mode / sandbox_instance_id 可选字段
- 后端 admin_service.py list_trigger_jobs / get_trigger_job 各加 SELECT 列
- 前端 adminAI.ts TriggerJobItem 类型补 2 字段
- 前端 pages/AITriggerJobs.tsx 列表 columns 加运行模式 + 沙箱实例(同 UI-1 模式),详情 Modal 加 2 项(同 UI-2 模式)

双口径验证(Playwright + DB 直查):
- UI-3 4a live: 选中默认门店,无 Alert,today_card 仅显示总数(flag off)
- UI-3 4b sandbox=4-20: Alert 显示"沙箱 + 业务日 + sbx_…",today_calls=93(sandbox 当日)
- UI-5 4a/4b: SQL INSERT 注入 walkthrough 测试行(id=9 live, id=10 sandbox),列表正确渲染 Tag + 短哈希

trend_7d 双线 / app_distribution 堆叠分布等更深入分组改造延后到 Wave C(§8.3 风险:破坏图表)。

审计:
- docs/audit/changes/2026-05-05__wave1_f1_5b_ui3_aidashboard_sandbox.md
- docs/audit/changes/2026-05-05__wave1_f1_5b_ui5_aitriggerjobs_runtime.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Neo
2026-05-05 19:16:47 +08:00
parent 87a5e3b08e
commit c43375734a
8 changed files with 309 additions and 6 deletions

View File

@@ -62,6 +62,10 @@ class DashboardResponse(BaseModel):
today_success_rate: float # 0.0 ~ 1.0
today_tokens: int
today_avg_latency_ms: float
# F1-5b UI-3: today_calls 按 runtime_mode 分组
# live + sandbox = today_calls(总计),供前端 feature flag 控制是否展示
today_live_calls: int = 0
today_sandbox_calls: int = 0
trend_7d: list[DailyTrend]
app_distribution: list[AppDistItem]
budget: BudgetInfo
@@ -84,6 +88,9 @@ class TriggerJobItem(BaseModel):
started_at: str | None
finished_at: str | None
created_at: str
# F1-5b UI-5: runtime 透出(同 RunLogItem)
runtime_mode: str | None = None
sandbox_instance_id: str | None = None
class TriggerJobListResponse(BaseModel):