Agent Policy 后台展示与编辑入口实施计划
Agent Policy 后台展示与编辑入口实施计划
目标
在管理后台的 Agent 详情页展示当前 Agent 的访问策略,并为管理员提供创建和编辑入口。页面必须能直观表达以下语义:
targetHost: "*"表示任意目标主机;targetPort: 0表示任意目标端口;allowedCIDRs和allowedPorts为空数组表示不限制;- Agent Policy 是服务端最终授权策略,Token scope 只能在其基础上进一步缩小权限。
架构决策
- 不修改后端 API、数据库 Schema、认证授权逻辑或 Agent Policy 判定逻辑;现有
/api/v1/agents/{agentId}/policies已满足需求。 - 策略入口放在 Agent 详情页,而不是 Tokens 页面或 Routes 页面,因为 Agent Policy 的权威归属是 Agent,避免与 Token scope、托管路由目标混淆。
- 管理员可以看到“添加策略”和“编辑”;普通用户如果拥有该 Agent,只读展示策略,不显示写操作按钮,保持后端 RBAC 与 UI 一致。
- 创建使用
Idempotency-Key;编辑使用 PATCH 并提交完整策略字段,避免省略 allowlist 字段造成语义歧义。 - 不实现删除策略入口;当前需求只要求显示和编辑,避免扩大授权管理风险。
技术栈
- Vue 3 + TypeScript + Pinia + Vue I18n + Element Plus。
- 组件遵循现有浅色 SaaS 管理台风格:
tm-card、DataState、el-table、el-dialog、el-form。 - 前端测试使用 Vitest + jsdom,生产包由 Vite 构建并同步到
internal/server/web_dist。
规格引用
docs/api/openapi.yaml中PolicyRequest与/api/v1/agents/{agentId}/policies。docs/user-guide/client.md中 SOCKS5 通配 Agent Policy 示例。internal/server/api.go中 Agent Policy 创建、更新和管理员校验行为。
全局约束
- 不提交或展示 Token、密码、私钥和生产 DSN。
- 策略表单必须在客户端做基础校验,但服务端仍是权威校验边界。
- 中文和英文文案必须同时维护,不能出现只存在于一种语言下的 UI 文案。
- 保持现有 Element Plus 视觉体系,不引入新的 UI 库或全局样式体系。
- 现有工作区中已有未提交的 Agent Policy 通配后端改动;本计划只在其上追加前端能力,不回退或重写后端改动。
精确文件清单
web/src/api/client.ts- 新增
AgentPolicy、AgentPolicyInput、AgentPolicyPage类型。 - 新增
listAgentPolicies(agentId)。 - 新增
createAgentPolicy(agentId, input, idempotencyKey)。 - 新增
updateAgentPolicy(agentId, policyId, input)。
- 新增
web/src/views/AgentDetail.vue- 新增独立的“访问策略”卡片和加载、错误、空态。
- 新增策略表格,展示协议、目标主机、目标端口、允许 CIDR、允许端口、更新时间和操作。
*、0、空数组在表格中显示为“任意主机”“任意端口”“不限制”。- 管理员显示“添加策略”和“编辑”,普通用户只读。
- 新增创建/编辑共用弹窗,字段包含协议、目标主机、目标端口、允许 CIDR、允许端口。
- 创建成功后刷新策略列表;编辑成功后更新列表数据。
web/src/i18n/messages/zh-CN.ts- 新增访问策略相关中文文案。
web/src/i18n/messages/en-US.ts- 新增访问策略相关英文文案。
web/src/tests/agent-detail.spec.ts- 补充 API mock 与 Pinia 初始化。
- 覆盖策略展示、通配语义、管理员入口、普通用户只读、创建和编辑行为。
web/src/tests/agent-policy-api.spec.ts- 验证策略 API client 的 URL、方法、请求体和
Idempotency-Key。
- 验证策略 API client 的 URL、方法、请求体和
docs/user-guide/client.md- 将“通过 API 创建通配策略”的说明补充为“可在后台 Agent 详情页管理,也可通过 API 管理”。
internal/server/web_dist/*- 前端构建成功后同步新的生产产物。
internal/server/web_test.go- 嵌入资源冒烟关键词增加“访问策略”或对应英文产物关键词,确保新 UI 进入 Go embed 包。
任务间接口
API 类型
export type AgentPolicy = {
id: string
agentId: string
protocol: string
targetHost: string
targetPort: number
allowedCIDRs: string[]
allowedPorts: number[]
createdAt: string
updatedAt: string
}
export type AgentPolicyInput = {
protocol: string
targetHost: string
targetPort: number
allowedCIDRs: string[]
allowedPorts: number[]
}
UI 状态
policies:当前页策略数组。policiesLoading、policiesError:独立于 metadata 的加载和错误状态。policyDialogVisible、policySaving、editingPolicy:共用弹窗状态。policyForm:协议、目标主机、目标端口、CIDR 文本、端口文本。- CIDR 和端口输入使用逗号分隔文本框,提交前转换为数组;空文本转换为空数组。
TDD 步骤
1. API client 测试先行
新增 web/src/tests/agent-policy-api.spec.ts,先断言:
listAgentPolicies('agent-1')请求GET /agents/agent-1/policies;createAgentPolicy请求POST /agents/agent-1/policies,带Idempotency-Key和完整 JSON;updateAgentPolicy请求PATCH /agents/agent-1/policies/policy-1,提交完整 JSON。
预期失败结果:函数和类型不存在,TypeScript/Vitest 编译失败。
2. 实现 API client 最小变更
在 web/src/api/client.ts 增加类型和三个函数,只做请求封装,不加入 UI 逻辑。
预期通过结果:API client 测试全部通过。
3. Agent 详情页测试先行
扩展 web/src/tests/agent-detail.spec.ts:
- mock 策略列表包含
targetHost: "*"、targetPort: 0、空 allowlist; - 断言页面显示“任意主机”“任意端口”“不限制”;
- 管理员状态下显示添加和编辑入口;
- 普通用户状态下不显示写入口;
- 打开编辑弹窗后表单回填原值;
- 保存编辑时调用
updateAgentPolicy并刷新或更新列表; - 打开创建弹窗后保存时调用
createAgentPolicy,请求体包含空数组和targetPort: 0。
预期失败结果:组件缺少策略区块和弹窗,相关断言找不到元素或函数调用。
4. 实现 Agent 详情页最小 UI
在 AgentDetail.vue 增加独立策略卡片、表格、共用弹窗和状态管理。只实现计划内字段和操作,不做删除、批量编辑或高级表达式解析。
预期通过结果:Agent 详情页新增测试全部通过,原有 metadata、连接列表和关闭连接测试保持通过。
5. i18n 与用户文档
- 补充中英文文案。
- 更新
docs/user-guide/client.md,说明后台入口与 API 管理方式等价。
预期失败结果:测试中出现缺失文案或文档检查不满足时失败;实现后通过。
6. 构建并同步嵌入资源
- 执行前端测试和构建。
- 将
web/dist同步到internal/server/web_dist。 - 更新 Go embed 冒烟测试关键词。
预期通过结果:前端测试、前端构建、Go embed 测试全部通过。
最小实现
- 仅新增策略展示、创建、编辑能力。
- 协议选择限定为后端已支持的
tcp、udp、http、ws。 - 目标端口使用数字输入,允许
0到65535。 - 目标主机允许精确 IP/域名或字面量
*;不允许foo*、*.example.com等部分通配。 - CIDR 和端口分别用逗号分隔文本输入,空值表示不限制。
- 不新增删除按钮、分页加载按钮或策略复制功能。
预期通过结果
- 管理员打开 Agent 详情页可以看到访问策略卡片和当前策略。
- 通配策略显示为“任意主机”“任意端口”,空 allowlist 显示为“不限制”。
- 管理员可以创建和编辑策略,普通用户只读。
- 创建和编辑请求与现有 API 契约一致。
- 中文和英文界面均可正常显示。
- 生产构建产物包含新功能,Go embed 冒烟测试能验证。
验证命令
cd web
npm test -- --run
npm run build
cd ..
go test ./internal/server -run TestEmbeddedWebDist -count=1
go test ./... -count=1
go test -race ./...
go vet ./...
git diff --check
回滚注意事项
- 前端源码回滚后,需要重新构建并同步
internal/server/web_dist,否则 Go 二进制仍会嵌入旧 UI。 - 本功能无数据库迁移和后端行为变更,回滚不涉及数据补偿。
- 若只回滚 UI,不影响已存在的 Agent Policy 数据和现有 API 调用。