From 077777471a4bdc0d594561bbb887d7f555e99933 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 00:26:47 +0000 Subject: [PATCH 1/2] Initial plan From 104801f531f6386273d415fb26e2b1cf7552c1b7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 00:38:21 +0000 Subject: [PATCH 2/2] docs: plan V2 development - HTTPS, token mgmt, node groups, custom headers, config preview Co-authored-by: Rain-kl <63696351+Rain-kl@users.noreply.github.com> --- docs/design.md | 325 +++++++++++++++++++++++++-------- docs/development-guidelines.md | 80 ++++++-- docs/development-plan.md | 248 +++++++++++++++---------- 3 files changed, 465 insertions(+), 188 deletions(-) diff --git a/docs/design.md b/docs/design.md index 6d188ab6..a8b1962c 100644 --- a/docs/design.md +++ b/docs/design.md @@ -12,9 +12,9 @@ --- -## 2. 第一版范围 +## 2. 第一版范围(已完成) -### 要做 +### 已做 * Web 管理端维护反代规则 * 配置发布生成版本 @@ -23,7 +23,7 @@ * 节点注册、心跳、在线状态展示 * 展示每个节点当前生效版本和最近一次应用结果 -### 不做 +### 不做(第一版) * 多租户 * WAF、限流、Bot、防刷 @@ -38,6 +38,56 @@ --- +## 2.5 第二版范围 + +在 MVP 闭环稳定运行的基础上,第二版聚焦以下增量能力。 + +### 要做 + +**2.5.1 HTTPS/TLS 支持** + +* `proxy_routes` 增加 HTTPS 相关字段:`enable_https`、`ssl_cert_path`、`ssl_key_path` +* 渲染器根据字段生成 HTTPS `server` 块(443 端口),并可选生成 HTTP → HTTPS 重定向块 +* 证书文件仍由节点本地预先准备,控制面只记录路径,不托管证书 + +**2.5.2 节点分组与差异化下发** + +* 新增 `node_groups` 表:管理分组(如 staging、production) +* `nodes` 增加 `group_id` 字段,节点可归属某个分组 +* 发布时可选择目标分组,生成面向该分组的版本 +* 不指定分组时,默认行为与第一版相同(全量下发) +* Agent 在心跳时携带自身分组信息,Server 按分组返回对应激活版本 + +**2.5.3 Agent Token 管理** + +* 新增 `agent_tokens` 表:支持创建多个命名 Token,记录备注、创建人、过期时间 +* 认证中间件改为查表验证,不再依赖单个全局环境变量 +* 提供 Token CRUD 管理 API 及前端页面 +* 旧的全局 Token 环境变量作为引导 Token,仅在数据库无 Token 记录时生效(bootstrap 模式) + +**2.5.4 路由增强** + +* `proxy_routes` 增加 `custom_headers` 字段(JSON 格式),支持每条路由追加自定义 `proxy_set_header` 指令 +* 渲染器按 `custom_headers` 内容注入到对应 `server` 块 + +**2.5.5 配置预览与变更摘要** + +* 新增"配置预览"接口:在不实际发布的情况下,返回基于当前启用规则渲染的 Nginx 配置 +* 新增"变更摘要"接口:对比当前激活版本与新渲染结果,返回新增、删除、修改的域名列表 +* 前端发布页接入预览与变更摘要,让管理员在点击发布前确认变化 + +### 仍不做(第二版) + +* 多租户 +* WAF、限流、Bot、防刷 +* 对象存储、消息队列、Redis、Prometheus +* 证书托管与自动签发 +* Purge、中台审计、审批流 +* mid-tier / 分层缓存 +* 复杂缓存策略配置 + +--- + ## 3. 技术约束 ### Server @@ -120,9 +170,7 @@ Agent 使用 Go 单体程序: ## 5. 核心对象 -第一版只保留最少的数据模型。 - -### 5.1 proxy_routes +### 5.1 proxy_routes(第一版) 反代规则表,控制 `Host -> Origin` 映射。 @@ -142,7 +190,15 @@ Agent 使用 Go 单体程序: * `origin_url` 必须是合法的 `http://` 或 `https://` * 第一版一条域名只对应一个源站,不做源站池 -### 5.2 config_versions +第二版新增字段: + +* `enable_https` — 是否启用 HTTPS(bool,默认 false) +* `ssl_cert_path` — 节点本地证书文件路径(string) +* `ssl_key_path` — 节点本地私钥文件路径(string) +* `redirect_http` — 是否将 HTTP 重定向到 HTTPS(bool,默认 false) +* `custom_headers` — 自定义 `proxy_set_header` 指令(JSON 格式,存字符串) + +### 5.2 config_versions(第一版) 发布版本表,保存不可变快照。 @@ -163,7 +219,11 @@ Agent 使用 Go 单体程序: * `rendered_config` 保存渲染后的 Nginx 路由配置 * 第一版直接存 SQLite,不单独上对象存储 -### 5.3 nodes +第二版新增字段: + +* `group_id` — 关联目标分组(nullable,null 表示全量发布) + +### 5.3 nodes(第一版) 节点表,保存当前状态。 @@ -182,7 +242,11 @@ Agent 使用 Go 单体程序: * `created_at` * `updated_at` -### 5.4 apply_logs +第二版新增字段: + +* `group_id` — 所属节点分组(nullable,无分组时为 null) + +### 5.4 apply_logs(第一版) 节点应用记录。 @@ -195,6 +259,33 @@ Agent 使用 Go 单体程序: * `message` * `created_at` +### 5.5 node_groups(第二版新增) + +节点分组表,用于差异化下发。 + +建议字段: + +* `id` +* `name` — 分组名称,唯一(如 `staging`、`production`) +* `remark` — 备注 +* `created_at` +* `updated_at` + +### 5.6 agent_tokens(第二版新增) + +Agent Token 管理表,替代全局单一 Token。 + +建议字段: + +* `id` +* `token` — Token 值,唯一,不可变 +* `name` — Token 备注名称 +* `created_by` — 创建人 +* `expires_at` — 过期时间(nullable,null 表示永不过期) +* `is_active` — 是否有效 +* `created_at` +* `updated_at` + --- ## 6. 配置发布模型 @@ -399,49 +490,63 @@ Agent 每次上报: ## 11. API 设计 -### 11.1 管理端 API +### 11.1 管理端 API(第一版,已实现) -* `GET /api/routes` -* `POST /api/routes` -* `PUT /api/routes/:id` -* `DELETE /api/routes/:id` -* `GET /api/versions` -* `POST /api/versions/publish` -* `POST /api/versions/:id/activate` -* `GET /api/nodes` -* `GET /api/apply-logs` +* `GET /api/proxy-routes/` +* `POST /api/proxy-routes/` +* `PUT /api/proxy-routes/:id` +* `DELETE /api/proxy-routes/:id` +* `GET /api/config-versions/` +* `GET /api/config-versions/active` +* `POST /api/config-versions/publish` +* `PUT /api/config-versions/:id/activate` +* `GET /api/nodes/` +* `GET /api/apply-logs/` -### 11.2 Agent API +### 11.2 Agent API(第一版,已实现) -* `POST /api/agent/register` -* `POST /api/agent/heartbeat` -* `GET /api/agent/version/active` -* `GET /api/agent/versions/:version` -* `POST /api/agent/apply-result` +* `POST /api/agent/nodes/register` +* `POST /api/agent/nodes/heartbeat` +* `GET /api/agent/config-versions/active` +* `POST /api/agent/apply-logs` -### 11.3 鉴权方案 +### 11.3 第二版新增管理端 API + +* `GET /api/node-groups/` — 分组列表 +* `POST /api/node-groups/` — 创建分组 +* `PUT /api/node-groups/:id` — 更新分组 +* `DELETE /api/node-groups/:id` — 删除分组 +* `GET /api/agent-tokens/` — Token 列表 +* `POST /api/agent-tokens/` — 创建 Token +* `DELETE /api/agent-tokens/:id` — 撤销 Token +* `GET /api/config-versions/preview` — 预览当前启用规则的渲染结果(不写库) +* `GET /api/config-versions/diff` — 对比当前激活版本与待发布的变更摘要 + +### 11.4 鉴权方案 管理端: * 直接沿用 gin-template 的登录态 -Agent: +Agent(第一版): -* 第一版使用预共享 Token -* 例如请求头 `X-Agent-Token` -* 后续再升级 mTLS +* 预共享 Token,请求头 `X-Agent-Token`,Token 值来自环境变量 + +Agent(第二版): + +* Token 改为查 `agent_tokens` 表验证 +* 环境变量 Token 仅作 bootstrap 引导 Token,数据库有记录时不再使用 +* 后续可升级 mTLS --- ## 12. 页面设计 -第一版只保留最少页面。 - ### 12.1 登录页 沿用 gin-template 现有登录。 -### 12.2 反代规则页 +### 12.2 反代规则页(第一版,已实现) 展示和编辑: @@ -450,7 +555,15 @@ Agent: * 是否启用 * 备注 -### 12.3 发布版本页 +第二版新增字段: + +* 是否启用 HTTPS +* SSL 证书路径 +* SSL 私钥路径 +* 是否 HTTP → HTTPS 重定向 +* 自定义请求头(JSON 编辑器) + +### 12.3 发布版本页(第一版,已实现) 展示: @@ -464,7 +577,12 @@ Agent: * 立即发布 * 激活旧版本 -### 12.4 节点页 +第二版新增: + +* 发布目标分组选择(可选,不选则全量) +* 发布前展示配置预览与变更摘要 + +### 12.4 节点页(第一版,已实现) 展示: @@ -475,7 +593,11 @@ Agent: * 最后心跳时间 * 最近错误 -### 12.5 应用记录页 +第二版新增: + +* 所属分组 + +### 12.5 应用记录页(第一版,已实现) 展示: @@ -485,19 +607,45 @@ Agent: * 错误信息 * 时间 +### 12.6 Token 管理页(第二版新增) + +展示: + +* Token 名称 +* 创建人 +* 过期时间 +* 是否有效 + +动作: + +* 创建 Token +* 撤销 Token + +### 12.7 节点分组页(第二版新增) + +展示: + +* 分组名称 +* 备注 +* 该分组下节点数 + +动作: + +* 创建分组 +* 编辑分组 +* 删除分组 + --- ## 13. 代码组织建议 -### Server - -建议直接在现有 `atsf_server` 下新增以下内容: +### Server(第一版,已实现) ```text atsf_server/ controller/ - route.go - version.go + proxy_route.go + config_version.go node.go agent.go model/ @@ -508,58 +656,73 @@ atsf_server/ router/ api-router.go service/ - publisher.go - renderer.go + proxy_route.go + config_version.go + agent.go ``` -### Agent +### Server(第二版新增) -建议新建独立目录: +```text +atsf_server/ + controller/ + node_group.go # 节点分组 CRUD + agent_token.go # Token 管理 + model/ + node_group.go # NodeGroup 模型 + agent_token.go # AgentToken 模型 + service/ + node_group.go # 分组逻辑 + agent_token.go # Token 创建与验证 + renderer.go # 抽离渲染逻辑(HTTPS 支持扩展) + middleware/ + agent-auth.go # 改为查表验证 +``` + +### Agent(第一版,已实现) ```text atsf_agent/ cmd/agent/main.go internal/config/config.go - internal/heartbeat/heartbeat.go - internal/sync/sync.go - internal/nginx/nginx.go + internal/heartbeat/service.go + internal/sync/service.go + internal/nginx/manager.go internal/state/state.go + internal/httpclient/client.go + internal/protocol/agent_api.go ``` +### Agent(第二版) + +第二版 Agent 无需新增模块,只需在现有模块内扩展: + +* `config`: 新增 `group_id` 配置项 +* `heartbeat`: 心跳请求中携带 `group_id` +* `sync`: 按分组获取对应激活版本(Server 端路由区分) + --- ## 14. 开发顺序 -按下面的顺序最稳。 +### 第一版(已完成) -### 第一阶段 +1. Server 建表、AutoMigrate +2. 反代规则 CRUD 与发布逻辑 +3. Agent API 与节点状态表 +4. Agent 同步、落盘、reload、回滚 +5. 管理端页面 +6. 联调和部署文档 -先把 Server 跑通: +### 第二版(当前阶段) -* 建表 -* 反代规则 CRUD -* 发布版本表 -* 版本渲染逻辑 +按以下顺序执行,前项完成后再推进下一项: -### 第二阶段 - -做 Agent 最小闭环: - -* 注册 -* 心跳 -* 拉取激活版本 -* 写入 Nginx 路由配置 -* `nginx -t && nginx -s reload` -* 应用结果上报 - -### 第三阶段 - -补管理端页面: - -* 规则页 -* 版本页 -* 节点页 -* 应用日志页 +1. HTTPS/TLS 支持(ProxyRoute 扩展字段 + 渲染器 + 前端表单) +2. Agent Token 管理(agent_tokens 表 + 中间件改造 + 前端 Token 管理页) +3. 节点分组与差异化下发(node_groups 表 + 发布分组逻辑 + Agent 携带 group_id) +4. 路由增强(custom_headers 字段 + 渲染器注入 + 前端表单) +5. 配置预览与变更摘要(preview 接口 + diff 接口 + 前端发布确认弹窗) --- @@ -580,3 +743,17 @@ atsf_agent/ ``` 这就是当前阶段最需要的 MVP。 + +### 第二版取舍 + +* HTTPS 支持不托管证书,只记录本地路径,避免引入证书存储和签发复杂度 +* 节点分组不做跨分组继承,每个分组独立一套激活版本,降低理解负担 +* Token 管理不做细粒度权限(如只读 Token),第二版所有 Token 权限一致 +* 路由自定义头不做模板变量,只支持静态 key-value,避免过早引入 DSL +* 配置预览只展示渲染结果,不实际验证 Nginx 语法,真实校验仍由 Agent 完成 + +第二版成功标准: + +```text +HTTPS 路由可生效 + 节点可按分组差异化下发 + Token 可在界面管理 + 发布前可预览变更 +``` diff --git a/docs/development-guidelines.md b/docs/development-guidelines.md index 6eec653a..9eaa34d9 100644 --- a/docs/development-guidelines.md +++ b/docs/development-guidelines.md @@ -2,19 +2,27 @@ ## 1. 适用范围 -本规范适用于 ATSFlare 当前 MVP 阶段。 +本规范适用于 ATSFlare 第一版与第二版阶段。 -项目当前只做以下能力: +项目第一版已完成以下能力: * 配置发布与同步 * 节点心跳检测 * Nginx 反向代理配置下发 -当前明确不做: +第二版在此基础上新增以下能力: + +* HTTPS/TLS 路由支持 +* Agent Token 管理 +* 节点分组与差异化下发 +* 路由自定义请求头 +* 配置预览与变更摘要 + +当前明确仍不做: * 多租户 * WAF、限流、Bot、防刷 -* 灰度发布、分组发布、百分比发布 +* 百分比灰度发布 * Redis、MQ、对象存储、Prometheus * 复杂缓存策略、证书托管、Purge、审批流 * mid-tier、分层缓存、复杂策略编排 @@ -107,32 +115,38 @@ Agent 放在 `atsf_agent`,使用 Go 单体程序开发。 所有实现都必须遵守以下原则: * 先完成闭环,再做抽象。 -* 不为了“以后可能会支持”提前引入复杂模型。 +* 不为了"以后可能会支持"提前引入复杂模型。 * Server 只管状态和配置,不直接 SSH 改节点。 * Agent 是唯一落地入口。 -* 所有发布都是“新版本激活”,不是在线覆盖编辑。 -* 所有节点默认拉同一份全量配置,不做差异化编排。 +* 所有发布都是"新版本激活",不是在线覆盖编辑。 +* 第一版:所有节点默认拉同一份全量配置;第二版:可按节点分组差异化下发。 * 能用 SQLite 解决的问题,不引入额外中间件。 * 新功能优先复用现有 gin-template 结构,不平行造第二套框架。 ## 5. 数据模型规范 -第一版只允许引入以下核心实体: +第一版核心实体(已实现): * `proxy_routes` * `config_versions` * `nodes` * `apply_logs` -约束: +第二版新增实体: + +* `node_groups` — 节点分组 +* `agent_tokens` — Agent Token 管理 + +约束(全版本): * 不新增 `zone`、`origin_pool`、`policy`、`deployment` 这类平台化对象 * `proxy_routes` 一条域名只对应一个 `origin_url` * `config_versions` 必须保存完整快照和渲染后的 Nginx 路由配置 -* 激活版本全局只能有一个 -* 回滚通过“激活旧版本”实现,不直接修改历史记录 +* 同一分组内激活版本只能有一个;全量版本(group_id = null)全局只能有一个 +* 回滚通过"激活旧版本"实现,不直接修改历史记录 +* `agent_tokens` 中的 Token 值不可更新,只能创建或撤销 -如需新增表,必须先证明它服务于 MVP 主链路。 +如需新增表,必须先证明它服务于当前迭代版本的主链路。 ## 6. Server 开发规范 @@ -181,12 +195,19 @@ Server 代码按以下职责拆分: * 继续复用 gin-template 的登录、角色和 session 体系 -Agent: +Agent(第一版): -* 第一版使用预共享 Token +* 预共享单 Token,来自环境变量 * 请求头统一使用 `X-Agent-Token` * Agent 与管理端认证逻辑必须分开 +Agent(第二版): + +* Token 改为查 `agent_tokens` 表验证 +* 环境变量 Token 降级为 bootstrap 模式:数据库存在有效 Token 记录时,环境变量 Token 不再有效 +* Token 创建时生成随机值,不允许外部传入 +* Token 值不可更新,仅支持撤销(设 `is_active=false`) + 注意: * 不要让 Agent 接口走用户登录态 @@ -339,7 +360,7 @@ MVP 前端只做最小管理界面,不重做整套后台。 ## 10. 测试与验收规范 -### 10.1 最低测试要求 +### 10.1 第一版最低测试要求(已完成) Server 至少覆盖: @@ -356,9 +377,21 @@ Agent 至少覆盖: * `nginx -t` 或 `nginx -s reload` 失败分支 * 本地状态文件读写 -### 10.2 联调验收标准 +### 10.2 第二版新增测试要求 -MVP 完成至少要通过以下手工验证: +Server 新增覆盖: + +* HTTPS server 块渲染正确性(`enable_https=true` 时生成 443 块,`redirect_http=true` 时生成重定向块) +* HTTP-only 路由渲染结果不受 HTTPS 字段影响 +* `custom_headers` 注入到渲染结果的正确性 +* `agent_tokens` 创建与查表验证逻辑 +* Token 撤销后验证失败 +* bootstrap Token 降级行为(数据库有 Token 时环境变量 Token 失效) +* 分组发布逻辑(group_id 筛选激活版本) +* 预览接口不写库 +* diff 接口变更摘要计算正确性 + +### 10.3 联调验收标准(第一版,已完成) 1. 管理端新增反代规则并成功发布版本 2. Agent 能检测到新版本并拉取 @@ -367,15 +400,26 @@ MVP 完成至少要通过以下手工验证: 5. 节点页能看到当前版本和最后心跳 6. 当 reload 失败时,Agent 能回滚到旧配置并上报失败 +### 10.4 联调验收标准(第二版) + +1. 创建含 HTTPS 字段的路由并发布,Nginx 能以 HTTPS 正确转发 +2. 通过管理界面创建 Token,Agent 使用新 Token 成功访问 +3. 撤销 Token 后 Agent 请求返回 401 +4. 创建分组并按分组发布,不同分组节点拉到不同版本 +5. 路由配置自定义头后,渲染结果包含对应指令 +6. 发布页预览展示正确渲染结果 +7. 变更摘要正确列出域名变化 + ## 11. 文档维护规范 出现以下情况时必须同步更新文档: -* MVP 范围变化 +* 产品版本范围变化(V1 → V2 → V3) * API 发生破坏性变更 * 数据模型新增或删除 * Agent 本地文件路径变更 * 部署方式变化 +* 新增或撤销对中间件/基础设施的依赖 优先更新: diff --git a/docs/development-plan.md b/docs/development-plan.md index 424d05a3..850af0ae 100644 --- a/docs/development-plan.md +++ b/docs/development-plan.md @@ -8,56 +8,31 @@ 后台改规则 -> 点击发布 -> Agent 拉到新版本 -> 写入 Nginx 路由配置 -> nginx 校验并 reload -> 节点状态可见 ``` -在这个闭环完成之前,不新增高级功能。 +MVP 已于第一版完成。当前进入第二版迭代。 -## 2. 里程碑 +## 2. 第一版里程碑(已完成) -### Phase 1: Server 数据层与发布闭环 - -目标: - -* 完成 `proxy_routes` -* 完成 `config_versions` -* 能从规则生成 Nginx 路由配置 -* 能激活一个全局版本 +### Phase 1: Server 数据层与发布闭环 ✅ 交付: -* 新模型 +* 新模型(proxy_routes、config_versions) * AutoMigrate * 路由 CRUD API * 发布 API * 激活版本 API * 渲染 service -完成标准: - -* 后台能维护规则 -* 可以生成并查看版本记录 - -### Phase 2: Agent API 与节点状态 - -目标: - -* 建立节点注册、心跳、版本查询、应用结果上报链路 +### Phase 2: Agent API 与节点状态 ✅ 交付: -* `nodes` -* `apply_logs` -* Agent Token 鉴权 +* `nodes`、`apply_logs` +* Agent Token 鉴权(全局单 Token) * 节点在线状态计算 * 节点与应用日志查询接口 -完成标准: - -* Server 能记录节点和最近状态 - -### Phase 3: Agent 本体 - -目标: - -* 实现最小可运行 Agent +### Phase 3: Agent 本体 ✅ 交付: @@ -70,15 +45,7 @@ * 配置校验、reload 与失败回滚 * 应用结果上报 -完成标准: - -* 单节点可跑通“发布到 Nginx 生效”的闭环 - -### Phase 4: 管理端页面 - -目标: - -* 提供 MVP 所需最小可视化界面 +### Phase 4: 管理端页面 ✅ 交付: @@ -87,91 +54,180 @@ * 节点页 * 应用记录页 -完成标准: - -* 不依赖直接查库即可完成日常操作和排障 - -### Phase 5: 联调与收尾 - -目标: - -* 完成本地或测试环境联调 -* 补齐运行说明 +### Phase 5: 联调与收尾 ✅ 交付: * 手工部署说明 * Agent 配置示例 -* 最小联调脚本或命令说明 -* 问题清单与后续迭代列表 +* 联调验证记录 + +## 3. 第二版里程碑 + +### V2 Phase 1: HTTPS/TLS 支持 + +目标: + +* 支持通过控制面配置 HTTPS 路由 +* 渲染出包含 443 端口的 `server` 块 +* 支持 HTTP → HTTPS 重定向块 + +交付: + +* `proxy_routes` 新增字段:`enable_https`、`ssl_cert_path`、`ssl_key_path`、`redirect_http` +* 渲染器支持 HTTPS server 块生成 +* 前端反代规则页增加 HTTPS 配置表单 +* AutoMigrate 覆盖新字段 完成标准: -* 新环境能按文档手工部署并跑通最小闭环 +* 创建含 HTTPS 字段的路由并发布,Agent 拉取后 Nginx 能以 HTTPS 正确转发 +* HTTP 重定向配置生效 +* 未开启 HTTPS 的路由渲染行为与第一版保持一致 -## 3. 当前建议执行顺序 +### V2 Phase 2: Agent Token 管理 + +目标: + +* 支持多个命名 Token +* Token 可通过管理界面创建和撤销 +* 中间件改为查库验证 + +交付: + +* `agent_tokens` 表与模型 +* agent-auth 中间件改造(查表验证) +* 全局 Token 环境变量降级为 bootstrap 模式 +* Token CRUD API +* 前端 Token 管理页 + +完成标准: + +* 新建 Token 后 Agent 可用该 Token 访问 Agent API +* 撤销 Token 后 Agent 请求立即返回 401 +* 全局环境变量 Token 仅在数据库无有效记录时生效 + +### V2 Phase 3: 节点分组与差异化下发 + +目标: + +* 节点可按分组管理 +* 发布时可选择目标分组,生成分组专属版本 +* Agent 按分组拉取对应激活版本 + +交付: + +* `node_groups` 表与模型 +* `nodes` 新增 `group_id` 字段 +* `config_versions` 新增 `group_id` 字段(nullable,null 表示全量) +* 发布 API 接受可选 `group_id` 参数 +* Agent API 按节点分组返回对应激活版本 +* Agent `agent.json` 新增 `group_id` 配置项 +* 前端节点分组管理页与节点页分组字段 + +完成标准: + +* 同一系统内 staging 和 production 分组各有独立激活版本 +* staging 节点拉取 staging 版本,production 节点拉取 production 版本 +* 不属于任何分组的节点拉取全量(group_id = null)版本 + +### V2 Phase 4: 路由自定义头 + +目标: + +* 每条路由支持追加自定义 `proxy_set_header` 指令 + +交付: + +* `proxy_routes` 新增 `custom_headers` 字段(JSON,`[{"key":"X-My-Header","value":"foo"}]`) +* 渲染器按 `custom_headers` 在 `location /` 块中注入额外 header 指令 +* 前端反代规则页增加自定义头编辑器 + +完成标准: + +* 路由配置自定义头后发布,渲染结果包含对应 `proxy_set_header` 指令 +* 不配置自定义头的路由渲染行为与之前保持一致 + +### V2 Phase 5: 配置预览与变更摘要 + +目标: + +* 发布前可预览渲染结果 +* 发布前可查看与当前激活版本的变更摘要 + +交付: + +* `GET /api/config-versions/preview` 接口(返回渲染后的 Nginx 配置,不写库) +* `GET /api/config-versions/diff` 接口(返回新增/删除/修改的域名列表) +* 前端发布版本页增加"预览"按钮和变更摘要展示弹窗 + +完成标准: + +* 点击预览可查看即将生成的 Nginx 配置文本 +* 变更摘要正确列出相对于当前激活版本的域名变化 +* 预览和 diff 操作不产生版本记录 + +## 4. 第二版建议执行顺序 建议严格按以下顺序开发: -1. Server 模型和 `AutoMigrate` -2. 路由 CRUD 与发布逻辑 -3. Agent API 与节点状态表 -4. Agent 同步、落盘、reload、回滚 -5. 管理端页面 -6. 联调和部署文档 +1. HTTPS/TLS 支持(对现有渲染链路影响最小,独立可测) +2. Agent Token 管理(安全性改善,早做早稳) +3. 节点分组(数据模型扩展,影响面最广,需要 Agent 配合) +4. 路由自定义头(纯增量,对现有结构影响小) +5. 配置预览与变更摘要(纯只读接口,最后补充) 不要先做以下内容: -* 权限扩展 -* 缓存策略平台化 -* 证书平台化 -* 多节点分批发布 -* 高级监控接入 +* 证书托管 +* 灰度百分比发布 +* WAF、限流 +* Redis、Prometheus +* 多租户 -## 4. 每阶段的验收检查 +## 5. 第二版每阶段验收检查 -### Phase 1 检查项 +### V2 Phase 1 检查项 -* 可以创建、编辑、删除反代规则 -* 可以基于当前规则生成版本 -* 可以查看哪个版本处于激活状态 -* 激活旧版本时不会修改历史快照 +* `enable_https=true` 的路由发布后生成 443 端口 server 块 +* `redirect_http=true` 的路由生成 80 → 443 重定向块 +* 未开启 HTTPS 的路由渲染结果不受影响 +* Agent 拉取后 Nginx reload 成功 -### Phase 2 检查项 +### V2 Phase 2 检查项 -* Agent 可以通过 Token 访问 Agent API -* 节点可以注册并重复心跳 -* 节点超过超时时间会显示为离线 -* 可以查询节点最近一次应用状态 +* 可通过管理界面创建 Token +* 新 Token 可被 Agent 使用 +* 撤销 Token 后访问立即失败 +* 全局 Token 环境变量在数据库有记录时失效 -### Phase 3 检查项 +### V2 Phase 3 检查项 -* Agent 检测到新版本后会下载配置 -* 写入前会备份旧路由配置文件 -* `nginx -t` 或 reload 失败后会回滚 -* 回滚结果会回传给 Server -* Agent 可使用独立 Nginx 路径或 Docker Nginx 容器运行 +* 可创建分组并将节点归入分组 +* 可发布面向指定分组的版本 +* 分组节点只拉取该分组的激活版本 +* 无分组节点拉取全量激活版本 -### Phase 4 检查项 +### V2 Phase 4 检查项 -* 页面可直接完成规则维护和发布 -* 页面可查看节点在线状态 -* 页面可查看应用失败原因 +* 路由可添加自定义头 +* 渲染结果中正确包含自定义 header 指令 +* 无自定义头的路由渲染结果不受影响 -### Phase 5 检查项 +### V2 Phase 5 检查项 -* 按文档可完成一次从零部署 -* 至少完成一次真实联调记录 -* 已记录当前遗留问题和下一阶段候选项 +* 预览接口返回正确的 Nginx 配置文本 +* diff 接口返回正确的域名变更列表 +* 两个接口均不产生数据库写入 -## 5. 变更控制 +## 6. 变更控制 开发中如果出现以下情况,需要先调整计划再继续编码: -* MVP 目标发生变化 -* 需要引入新的中间件 +* V2 目标发生变化 +* 需要引入新的中间件(Redis、MQ 等) * 需要新增核心数据模型 -* 需要把控制面扩展到独立生成的 Nginx 路由配置文件之外 +* 需要把控制面扩展到 Nginx 全局配置 计划更新时,应同步修改: