From d1b31dac15f3bef239194b268992a7cb7d2566f0 Mon Sep 17 00:00:00 2001 From: hmo Date: Thu, 16 Jul 2026 22:10:34 +0800 Subject: [PATCH] feat: add module spec files for agents, kanban, infra tabs --- gateway/scripts/specs/agents.json | 55 +++++++++++++++++++++++ gateway/scripts/specs/infra.json | 73 +++++++++++++++++++++++++++++++ gateway/scripts/specs/kanban.json | 49 +++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 gateway/scripts/specs/agents.json create mode 100644 gateway/scripts/specs/infra.json create mode 100644 gateway/scripts/specs/kanban.json diff --git a/gateway/scripts/specs/agents.json b/gateway/scripts/specs/agents.json new file mode 100644 index 0000000..ea43159 --- /dev/null +++ b/gateway/scripts/specs/agents.json @@ -0,0 +1,55 @@ +{ + "module": "agents", + "version": "1.0", + "purpose": "Dashboard 'Agents' tab 展示所有注册 Agent 的在线状态、消息流量、服务列表和实时日志,支持远程启停操作。", + "ui_location": "主菜单 → Agents tab", + + "human_help": { + "title": "Agents 总览", + "description": [ + "本页面展示系统中所有注册 Agent 的实时状态。每个 Agent 卡片包含在线状态、消息速率(msg/5m)、运行平台,以及 Start/Stop/Restart 操作按钮。", + "Agent 卡片展开后可以查看其运行的服务列表和实时日志。", + "顶部概要卡片显示在线数/错误数/总数。" + ], + "usage": [ + "1. 查看顶部概要卡片了解整体运行状态", + "2. 点击 Agent 卡片展开/收起服务和日志区域", + "3. 使用 Start/Stop/Restart 按钮管理 Agent 进程", + "4. 点击 Logs 查看实时日志(最近 50 行)" + ], + "troubleshooting": [ + "如果 Agent 状态刷新慢:页面每 10s 自动刷新一次", + "如果 Start 按钮不可用:该 Agent 可能不支持远程启动,或已在运行中", + "如果 Agent 掉线:检查对应机器的网络和进程状态" + ], + "related": "F 健康 tab 查看系统整体服务健康状态,K 测试 tab 有各模块的细化测试" + }, + + "ai_spec": { + "apis": [ + {"method": "GET", "path": "/api/agents", "returns": "[{id,name,display_name,jid,status,platform,host,message_count_5min,errors,restartable,services}] — 所有 Agent 详细状态"}, + {"method": "POST", "path": "/api/agents/{id}/{action}", "params": "action=start|stop|restart", "returns": "{ok}"}, + {"method": "GET", "path": "/api/agents/{id}/logs", "params": "lines=N", "returns": "{ok, lines[]}"} + ], + "dependencies": [ + "dashboard.py 通过 /api/agents 端点聚合各 Agent 状态", + "Agent 启停操作依赖远程 SSH 或 systemd 权限", + "日志功能依赖 Agent 所在机器的日志文件访问" + ], + "constraints": [ + "message_count_5min 是滑动窗口计数,页面每 5s 轮询刷新", + "agent 卡片使用 create-once/update-state pattern — 首渲染后只更新 class 和文本", + "日志区域使用 tgL() 切换展开/收起,fL() 加载内容" + ], + "tests": [ + {"id": "AG01", "name": "/api/agents 返回所有 Agent 列表", "endpoint": "GET /api/agents"}, + {"id": "AG02", "name": "Agent 启停操作返回正确状态", "endpoint": "POST /api/agents/{id}/start|stop|restart"}, + {"id": "AG03", "name": "Agent 日志加载正常", "endpoint": "GET /api/agents/{id}/logs?lines=50"} + ], + "related_files": [ + "gateway/scripts/templates/dashboard.html — fa() 渲染函数", + "gateway/scripts/dashboard.py — /api/agents 端点", + "gateway/scripts/specs/agents.json — 本 spec 文件" + ] + } +} diff --git a/gateway/scripts/specs/infra.json b/gateway/scripts/specs/infra.json new file mode 100644 index 0000000..082fa93 --- /dev/null +++ b/gateway/scripts/specs/infra.json @@ -0,0 +1,73 @@ +{ + "module": "infra", + "version": "1.0", + "purpose": "Dashboard 'Infrastructure' tab 展示基础设施状态:Platform 进程、Ejabberd XMPP 服务、EasyTier VPN、RDP 远程桌面隧道、OpenCode Go 用量监控。", + "ui_location": "主菜单 → Infrastructure tab", + + "human_help": { + "title": "Infrastructure 总览", + "description": [ + "本页面展示系统基础设施的运行状态,分为多个区域:", + "• Platform — Windows/Linux 平台基础进程状态", + "• Ejabberd — XMPP 服务器心跳", + "• EasyTier VPN — P2P VPN 内网开关(连接两台机器)", + "• RDP Remote Desktop — SSH 反向隧道远程桌面", + "• OpenCode Go Usage — 四个订阅账号的 API 用量监控" + ], + "usage": [ + "1. 检查 Platform 和 Ejabberd 的基础运行状态", + "2. EasyTier: 先 Turn On 建立 VPN 连接,确认 Connected 后再操作 RDP", + "3. RDP: Enable 启动 SSH 反向隧道,Disable 关闭", + "4. Usage: 查看各账号用量,点击 Refresh Now 手动采集最新数据" + ], + "troubleshooting": [ + "EasyTier 和 RDP 有依赖关系 — RDP 需 EasyTier 先 Connected", + "Usage 数据自动每 30min 采集一次,也可手动 Refresh", + "如果某个区域一直 loading:检查对应后端 API 是否正常" + ], + "related": "F 健康 tab 查看服务级健康状态" + }, + + "ai_spec": { + "apis": [ + {"method": "GET", "path": "/api/platform", "returns": "[{name,status}] — 平台进程状态"}, + {"method": "GET", "path": "/api/ejabberd", "returns": "{alive, xmpp_bot_connected} — XMPP 服务器心跳"}, + {"method": "GET", "path": "/api/easytier", "returns": "{status:{windows,246}, virtual_ips:{windows,246}}"}, + {"method": "POST", "path": "/api/easytier/toggle", "body": "{action:start|stop}"}, + {"method": "GET", "path": "/api/rdp", "returns": "{rdp_enabled, tunnel_running, public_endpoint}"}, + {"method": "POST", "path": "/api/rdp/toggle", "body": "{action:start|stop}"}, + {"method": "GET", "path": "/api/usage", "returns": "{ok, accounts[{name,usage,limit}], last_refresh}"}, + {"method": "POST", "path": "/api/usage/refresh", "returns": "{ok}"} + ], + "dependencies": [ + "EasyTier/RDP 依赖 xmpp_bot 的 HTTP bridge (Windows:5807)", + "Usage 依赖 CDP proxy 在 Chrome tab 内执行 fetch", + "Platform 状态通过 subprocess 本地检测" + ], + "constraints": [ + "fI() 使用 create-once/update-state pattern — DOM 元素只创建一次,后续只更新 class/text", + "Platform 和 Ejabberd 部分在 stable wrapper (
) 中全量重渲染", + "EasyTier/RDP/Usage section 各自独立创建,互不影响", + "Usage 数据采集后 10-15s 自动刷新" + ], + "must_not": [ + "不要把 fI() 改成全量重渲染 — 会破坏 create-once pattern 导致 EasyTier/RDP 元素闪烁", + "不要删除 infra-pe wrapper — Platform 和 Ejabberd 内容全量重渲染,其他 section 增量更新" + ], + "tests": [ + {"id": "IN01", "name": "Platform 状态正常返回", "endpoint": "GET /api/platform"}, + {"id": "IN02", "name": "Ejabberd 心跳正常", "endpoint": "GET /api/ejabberd"}, + {"id": "IN03", "name": "EasyTier toggle 操作正常", "endpoint": "POST /api/easytier/toggle"}, + {"id": "IN04", "name": "RDP toggle 操作正常", "endpoint": "POST /api/rdp/toggle"}, + {"id": "IN05", "name": "Usage 数据正常采集和展示", "endpoint": "GET /api/usage"} + ], + "related_files": [ + "gateway/scripts/templates/dashboard.html — fI() 渲染函数", + "gateway/scripts/dashboard.py — 所有 /api/infra* 端点", + "gateway/scripts/specs/infra.json — 本 spec 文件", + "gateway/scripts/specs/easytier.json — EasyTier 详细 spec", + "gateway/scripts/specs/rdp.json — RDP 详细 spec", + "gateway/scripts/specs/usage_monitor.json — Usage monitor 详细 spec" + ] + } +} diff --git a/gateway/scripts/specs/kanban.json b/gateway/scripts/specs/kanban.json new file mode 100644 index 0000000..5b91eda --- /dev/null +++ b/gateway/scripts/specs/kanban.json @@ -0,0 +1,49 @@ +{ + "module": "kanban", + "version": "1.0", + "purpose": "Dashboard 'Kanban' tab 展示看板任务列表,支持按状态(Ready/In Progress/Blocked/Done)和负责人筛选,实时刷新。", + "ui_location": "主菜单 → Kanban tab", + + "human_help": { + "title": "Kanban 看板", + "description": [ + "本页面展示系统中的看板任务卡片,每个任务包含标题、状态标签、负责人和创建日期。", + "顶部筛选器可按状态和负责人过滤任务列表。", + "任务卡片可点击展开/收起详细描述。" + ], + "usage": [ + "1. 使用顶部筛选器(All Status / All)缩小任务范围", + "2. 点击任务卡片展开详情(支持 multi-line 描述)", + "3. 状态颜色标识:绿色=Ready、黄色=In Progress、红色=Blocked、灰色=Done", + "4. 页面每 15s 自动刷新任务列表" + ], + "troubleshooting": [ + "如果任务列表为空:检查 Kanban API 是否正常运行", + "如果筛选器无反应:页面自动刷新后会重置筛选状态 — 请确保在刷新间隔内操作" + ], + "related": "G 规范定义开发流程和任务管理规范" + }, + + "ai_spec": { + "apis": [ + {"method": "GET", "path": "/api/kanban", "returns": "{ok, tasks[{id,title,body,status,assignee,created_at}]}"} + ], + "dependencies": [ + "看板数据由 dashboard.py 从后端 Kanban 服务/数据库获取" + ], + "constraints": [ + "页面每 15s 轮询刷新 (setInterval(fK,15000))", + "筛选器状态通过 DOM 直接读取 (document.getElementById)", + "任务卡片展开使用 onclick 切换 expanded class — max-height 从 60px ↔ none 切换" + ], + "tests": [ + {"id": "KB01", "name": "/api/kanban 返回任务列表", "endpoint": "GET /api/kanban"}, + {"id": "KB02", "name": "筛选器过滤正确", "endpoint": "n/a (frontend)"} + ], + "related_files": [ + "gateway/scripts/templates/dashboard.html — fK() 渲染函数", + "gateway/scripts/dashboard.py — /api/kanban 端点", + "gateway/scripts/specs/kanban.json — 本 spec 文件" + ] + } +}