# OpenFlare 开发规范 本文档描述 OpenFlare `1.0.0` 正式版之后的开发基线。 超出 [docs/design.md](./design.md) 边界的需求,必须先更新设计文档。 ## 1. 技术基线 ### 1.1 Server `openflare_server` 继续作为单体控制面: * Go 1.24+ * Gin * GORM * SQLite / PostgreSQL * 现有登录体系 ### 1.2 Agent `openflare_agent` 继续作为 Go 单体程序: * Go 1.24+ * 单二进制 * 节点本地执行 * `openresty_path` 优先 * 无 `openresty_path` 时默认 Docker OpenResty ### 1.3 Frontend 前端基线以 `openflare_server/web` 为准: * Next.js 15 App Router * React 19 * TypeScript * Tailwind CSS 4 * TanStack Query * React Hook Form + Zod * Zustand 仅用于轻量客户端状态 前端细则见 [docs/frontend-development-guidelines.md](./frontend-development-guidelines.md)。 ## 2. 分层与目录约束 ### 2.1 Server * `controller/`:参数解析、调用 service、返回响应 * `service/`:业务逻辑、校验、事务编排、渲染 * `model/`:模型定义与持久化 * `router/`:路由注册 * `middleware/`:认证、鉴权、限流等横切逻辑 * `common/`:配置、全局状态与初始化入口 * `utils/`:纯工具函数与通用 helper 禁止: * 在 `controller/` 堆积业务逻辑 * 在 `middleware/` 实现业务流程 * 为简单需求新增平台层抽象 ### 2.2 Agent 保持现有模块边界: * `config` * `heartbeat` * `sync` * `openresty` * `state` * `httpclient` * `protocol` * `internal/updater` 要求: * 每个模块职责单一 * 外部命令调用集中封装 * 状态落盘与配置落盘分离 ### 2.3 Frontend 前端分层保持: * `app/` * `features/` * `components/` * `lib/` * `store/` * `types/` 要求: * 页面路由与布局放在 `app/` * API 请求统一收敛到 `lib/api/` * 业务逻辑优先放在 `features/` ## 3. 数据模型规范 当前有效实体: * `proxy_routes` * `origins` * `config_versions` * `nodes` * `node_system_profiles` * `apply_logs` * `tls_certificates` * `managed_domains` * `node_request_reports` * `node_access_logs` * `node_metric_snapshots` * `traffic_analytics_rollups` * `node_health_events` * `options` 通用约束: * 不新增平台化对象,除非设计文档明确要求 * `origins` 仅作为可复用源站地址目录,字段保持轻量;协议、端口、路径与查询参数继续归属具体 `proxy_routes` * `proxy_routes` 以“网站配置”作为聚合边界,必须包含唯一 `site_name` 与非空 `domains` 列表;数据库内部 `id` 可继续作为技术主键,但不能替代 `site_name` 的业务唯一性 * `proxy_routes.domains` 中的每个域名都必须全局唯一;列表第一项视为主域名,创建时若未显式填写 `site_name`,则默认使用主域名 * `proxy_routes` 继续允许保存一个或多个上游地址用于负载均衡,但不引入独立 `origin_pool` * 迁移期如保留遗留 `domain` 字段,只能作为 `domains[0]` 的兼容镜像;新代码不得继续以该字段作为唯一业务输入 * `proxy_routes` 如关联 `origins`,必须同时保存可直接渲染的 `origin_url`;源站地址变更时,由 service 负责同步更新引用该源站的规则快照 * `proxy_routes` 的上游统一使用 named `upstream` + keepalive;单上游如带 base path 或 query,应在 `proxy_pass` 上补回 URI,多上游仅允许纯 `scheme://host[:port]` * `proxy_routes.origin_host` 为可选字段,仅用于覆盖回源 `Host` 请求头,不引入新的平台化对象 * 流量限制、反向代理与缓存配置当前都归属站点级 `proxy_routes`,同一网站内不拆分域名级差异配置 * HTTPS 的启停仍由站点级 `proxy_routes` 控制,但证书绑定必须通过与 `domains` 平行的 `domain_cert_ids` 记录逐域名保存;未绑定证书的域名不得参与 HTTPS 渲染 * `proxy_routes.cert_ids` 仅作为站点级证书集合与兼容镜像,必须由 `domain_cert_ids` 推导生成;`cert_id` 继续作为首个已使用证书的兼容镜像 * `config_versions` 必须保存完整快照与渲染结果 * 全局同时只能有一个激活版本 * 回滚通过重新激活旧版本实现 * `nodes` 只保留控制面状态与低频摘要 * 观测数据必须按节点与时间窗口关联 * 快照与聚合结果采用追加式模型,不覆盖历史 * 原始访问明细必须有受控保留策略 ### 3.1 数据库版本与迁移 * 任何涉及表结构、索引、列类型、分表规则或内部持久化元数据的修改,都必须同步提升数据库版本号 * 数据库版本号定义在 `openflare_server/model`,不得只依赖 `AutoMigrate` 隐式升级存量数据库 * 每次提升数据库版本号时,必须补充从上一版本升级到新版本的显式迁移方法 * 迁移方法必须包含升级后的校验逻辑;只有校验通过,才能写入新的数据库版本记录 * 新包启动后必须先检查数据库当前版本,再按顺序逐步升级到目标版本;禁止跳过中间升级步骤直接写目标版本 * 空库初始化可以直接建立当前版本结构,但初始化完成后仍必须执行同版本校验,并落库当前数据库版本 * 数据库版本元数据属于内部控制信息,必须保存在独立内部表中,不能混入业务配置表 * 如果迁移失败或校验失败,启动流程必须中止,且不得提升数据库版本记录 * 涉及数据库版本变更的提交,必须补充对应的迁移测试或等效回归测试 ## 4. API 与鉴权规范 ### 4.1 API * 管理端与 Agent API 统一使用 JSON * 成功与失败都必须返回清晰 `message` * Agent API 固定放在 `/api/agent/*` * 总览与节点详情优先使用专用聚合接口 * 管理端变更类接口统一使用 `POST`;只读接口使用 `GET` 统一响应结构: ```json { "success": true, "message": "", "data": {} } ``` ### 4.2 鉴权 管理端: * 继续复用现有登录、角色与 Session Agent: * 正式请求统一使用节点专属 `agent_token` * 首次接入可使用全局 `discovery_token` * 请求头统一使用 `X-Agent-Token` 禁止: * 暴露远程 shell 或任意命令执行入口 * 在日志中打印完整 Token * 允许绕过占位符约束保存不可渲染的主配置模板 ## 5. 发布与运行规范 发布逻辑必须保持以下事实: * 发布时读取全部启用的 `proxy_routes` * 同时读取 OpenResty 主配置参数、反代性能参数与缓存参数 * 生成完整 OpenResty 配置 * 计算 `checksum` * 写入 `config_versions` * 通过切换 `is_active` 激活版本 版本约束: * 版本号格式固定为 `YYYYMMDD-NNN` * 不在线修改历史版本 * 不做按节点分组的差异化版本 * 预览与 diff 是只读能力,不产生发布记录 Agent 必须满足: * 启动后读取或生成本地 `node_id` * 周期性心跳与同步 * 常规同步优先依据 heartbeat 返回的版本摘要判断 * 发现新版本时先备份旧文件 * 写入主配置、路由配置与必要证书文件 * 写入新配置后以运行态恢复为目标执行激活,Docker 模式优先重建容器并确认容器保持运行 * 新配置激活失败时必须先尝试用目标配置恢复运行,再回滚到旧配置并重新拉起 OpenResty * 回滚后 OpenResty 恢复正常时上报警告;回滚后仍无法恢复运行时上报失败 * 某个目标 `version + checksum` 一旦应用失败并回退,Agent 必须在本地状态中阻断该目标的重复应用;只有远端激活版本或 checksum 发生变化时,才允许再次尝试 ## 6. 测试与交付要求 * 关键业务逻辑必须有单元测试或等效回归测试 * Agent 主链路修改必须验证同步、应用与回滚 * 前端页面至少覆盖加载态、空态、错误态与成功反馈 * Go 版本调整时,同步检查 `go.mod`、Dockerfile 与 CI 工作流 ## 7. 文档维护要求 当以下内容变化时,必须同步更新对应文档: * 产品范围或系统边界变化:更新 `docs/design.md` * 开发约束、接口约定、测试基线变化:更新本文档 * 前端工程约束变化:更新 `docs/frontend-development-guidelines.md` * 配置项或部署方式变化:更新 `docs/app-config.md`、`docs/deployment.md` 与 `README.md`