OpenFlare 后端迁移 — AI 接手文档
状态:进行中(阶段 5 收尾)
主线:openflare-server 业务域已迁入 Wavelet/internal/apps/openflare/,阶段一通过 /api/* legacy 层联调旧前端
关联计划:实现计划
1. 当前任务状态
主线任务
将 OpenFlare 控制面后端从 openflare-server 迁移至 Wavelet 框架,保留旧前端 API 路径,复用 Wavelet 用户/OAuth/Cap 等平台能力,并完成 Agent/Relay/Flared 协议兼容。
开发分支
- 分支:
dev(相对 origin/dev 领先若干提交)
- 工作区:迁移计划文档
docs/plan/20260618-openflare-wavelet-backend-migration.md 可能仍有未提交修改
已完成(✅)
进行中(阶段 5)
- [/] B5-3 旧环境数据迁移脚本
support-files/migration/(用户 + 业务表 ETL,含 10 分片观测数据合并)
- [/] B5-4
make swagger + make code-check 全绿
- [/] B5-5 全量 API 回归(120+ 端点对照表)
待处理
2. 任务队列(委派状态)
| ID |
板块 |
状态 |
负责目录 |
| T-AUTH |
认证/用户/OAuth/Cap |
✅ |
legacy/register_auth.go, openflare/auth/, compat/auth.go |
| T-OPTION |
状态/公告/Option |
✅ |
legacy/register_option.go, openflare/option/ |
| T-ORIGIN |
源站 |
✅ |
legacy/register_origin.go, openflare/origin/ |
| T-APPLYLOG |
应用日志 |
✅ |
legacy/register_apply_log.go, openflare/apply_log/ |
| T-PROXY |
代理规则 |
✅ |
legacy/register_proxy_route.go, openflare/proxy_route/ |
| T-NODE |
节点管理 |
✅ |
legacy/register_node.go, openflare/node/ |
| T-WAF |
WAF |
✅ |
legacy/register_waf.go, openflare/waf/ |
| T-TLS |
TLS/证书/域名/DNS |
✅ |
legacy/register_tls.go, openflare/tls/ |
| T-CFGVER |
配置版本 |
✅ |
legacy/register_config_version.go, openflare/config_version/ |
| T-AGENT |
Agent API + WS |
✅ |
legacy/register_agent.go, openflare/agent/, openflare/websocket/ |
| T-PAGES |
Pages 托管 |
✅ |
legacy/register_pages.go, openflare/pages/ |
| T-RELAY |
Relay + Flared |
✅ |
legacy/register_relay_flared.go, openflare/relay/, openflare/flared/ |
| T-OBS |
仪表盘 + 可观测 |
✅ |
legacy/register_dashboard_obs.go, openflare/dashboard/, openflare/observability/ |
| T-MISC |
升级/GeoIP/UptimeKuma |
✅ |
legacy/register_misc.go, openflare/update/, openflare/geoip/, openflare/uptimekuma/ |
任务隔离规则
| 规则 |
说明 |
| 文件所有权 |
每个任务 仅修改 自己的 internal/apps/openflare/<module>/、对应 legacy/register_<module>.go、internal/model/openflare_<module>.go、goose SQL |
| 禁止修改 |
v1/user.go、v1/admin.go、model/users.go、其他任务的 register_*.go |
| 响应格式 |
旧前端兼容 API 使用 compat.OK/Fail/Unauthorized({success,message,data}) |
| 鉴权 |
管理端 compat.AdminAuth() / compat.RootAuth();用户 compat.UserAuth();全局 OpenFlare-Token 桥接见 legacy/register.go |
| Logic 层 |
logics.go 使用 context.Context,不依赖 *gin.Context |
| 数据源 |
db.DB(ctx) 获取 GORM |
| 质量门禁 |
完成后 go build ./... 并通过本模块测试 |
3. 核心文件与上下文
路由与兼容层
| 路径 |
职责 |
Wavelet/internal/router/router.go |
在 apiGroup 下调用 oflegacy.RegisterRoutes |
Wavelet/internal/apps/openflare/legacy/register.go |
汇总各 register_*.go;OpenFlare-Token 全局桥接 |
Wavelet/internal/apps/openflare/compat/auth.go |
JWT ↔ Session/AccessToken、角色 of_role 解析 |
Wavelet/internal/apps/openflare/compat/response.go |
Wavelet 信封 → 旧 {success,message,data} |
定时任务(OpenFlare cron)
| 文件 |
Job 名 |
Cron |
说明 |
tasks/database_cleanup.go |
database_auto_cleanup |
0 3 * * * |
可观测数据自动清理(受 Option 开关控制) |
tasks/waf_ip_group_sync.go |
waf_ip_group_sync |
@every 5m |
WAF IP 组周期同步 |
tasks/uptimekuma_sync.go |
uptime_kuma_sync |
* * * * * |
按 Option 间隔触发 UptimeKuma 同步 |
tasks/ssl_renew.go |
ssl_renew |
0 0 * * * |
ACME 证书自动续期 |
waf/register_tasks.go |
— |
— |
通过 RegisterCronJob 注册,避免 import cycle |
启动链路:wavelet api / wavelet all → bootstrap.RegisterAPI() → bootstrap.Init(ctx, {API:true}) → oftasks.Start(ctx)。
注意:OpenFlare cron 仅在 API 进程运行;wavelet worker / wavelet scheduler 负责 Wavelet 框架 Asynq 任务,与 OpenFlare cron 解耦。
数据库迁移
| 版本 |
内容 |
202606190001 |
of_options |
202606190002 |
of_origins |
202606190003 |
of_apply_logs |
202606190004 |
of_proxy_routes |
202606190005 |
of_nodes |
202606190006 |
of_waf_* |
202606190007 |
of_tls_* |
202606190008 |
of_config_versions |
202606190009 |
of_pages_* |
202606190010 |
可观测性单表(profiles/metrics/reports/health/openresty/frps/access_logs) |
202606190011 |
of_node_access_logs 复合索引 (node_id, logged_at) |
202606190012 |
of_node_obs_frpc |
路径:Wavelet/internal/db/migrator/goose/postgres/ 与 sqlite/ 各一份。
近期修复要点(2026-06-19)
| 问题 |
根因 |
修复位置 |
| Agent 已连接但节点显示「异常」 |
无激活 config version → openresty_status=unhealthy |
运维:发布并激活配置版本 |
| 节点详情无错误日志 |
可观测性表未迁移 |
202606190010 + agent/observability.go |
| WAF IP 组未下发 |
Agent sync 未实装 |
agent/waf_ip_group.go、waf/ip_group_sync.go |
| Pages 包下载 404 |
Agent 路由缺失 |
pages/logics.go、agent/routers.go |
| 旧前端 Token 部分路由 401 |
未全局桥接 |
legacy/register.go |
| 访问日志查询空 |
单表查询层缺失 |
model/openflare_access_log.go、202606190011 |
| Relay/Flared 观测缺失 |
heartbeat 未持久化 |
relay/observability.go、flared/observability.go、202606190012 |
依赖修复
replace github.com/rain-kl/openflare => ../ 会引入根 go.mod 的 gomodule/redigo v2.0.0+incompatible,与 gin-contrib/sessions/redistore 不兼容。已在 Wavelet/go.mod 添加 exclude 并锁定 redigo v1.9.3。
4. 集成测试
| 测试包 |
场景 |
结果 |
integration/auth_option_test.go |
登录/self/option 权限/热重载 |
✅ 5/5 |
integration/core_chain_test.go |
源站→规则→发布→节点→apply-log |
✅ 6/6 |
integration/security_test.go |
WAF/TLS/域名/DNS |
✅ 7/7 |
integration/agent_protocol_test.go |
Agent/Relay/Flared 协议 |
✅ 5/5 |
5. 本地启动(Wavelet 后端)
配置
复制 Wavelet/config.example.yaml → config.yaml,关键项:
或使用 .env / 环境变量:DB_ENABLED=true、DB_NAME=openflare、POSTGRES_DB=openflare。
启动命令
阶段一旧前端联调
- API:指向 Wavelet
:3000 的 /api/*(legacy 兼容层)
- 静态页面:阶段一仍使用
openflare-server/web/build(由旧 Server 托管或独立静态服务);Wavelet 默认嵌入的是 Wavelet/frontend,非旧 OpenFlare UI
- 鉴权:旧前端使用
OpenFlare-Token Header;登录 POST /api/user/login 由 legacy 层签发 JWT
6. 待决策与遗留问题
| 项 |
说明 |
当前处理 |
| 观测数据 10 分片 → 单表 |
旧生产环境有 node_*_XX 分片表 |
v1 单表;B5-3 ETL 脚本待建 |
| 微信登录 |
Wavelet 无内置 |
legacy 快捷路由已补;长期评估废弃或独立维护 |
| OpenFlare cron vs Asynq |
两套任务体系并存 |
阶段一 cron 在 API 进程;后续可迁入统一框架 |
| 节点「异常」展示 |
连接正常但无激活版本 |
属预期行为;需运维发布配置 |
make code-check |
全仓库静态检查 |
阶段 5 待跑通 |
7. 下一步行动指南
新接手 AI 建议按以下顺序执行:
- 确认环境:
cd Wavelet && go build ./... && go test ./internal/apps/openflare/... -count=1
- 跑质量门禁:
make code-check(修复 swagger/静态检查问题)
- 实现 B5-3:在
Wavelet/support-files/migration/ 编写 users → w_users 与业务表 ETL(含分片观测合并)
- API 回归:对照实现计划 §12 端点表,用 curl/集成测试逐项验证
- 联调验证:旧前端登录 → 创建规则 → 发布并激活 config version → Agent 心跳 → 检查节点状态与 apply-log
8. 参考文档