[优化] 重构数据库迁移逻辑,添加版本管理和验证功能

This commit is contained in:
ryan
2026-05-31 14:39:37 +08:00
parent f365b3d331
commit 46f49cc349
10 changed files with 38 additions and 0 deletions
+11
View File
@@ -183,6 +183,17 @@ tests/
v1-v7 视为历史初始基线,不再维护逐版本升级文件。从 v8 起,数据库迁移必须放在 `openflare_server/model/migrate` 目录中,并以目标版本命名文件,例如 `v16.go`。每个版本文件通过 `init()` 注册自己的迁移,当前数据库版本取已注册迁移的最大目标版本。不得为了整理文件而改变已发布 v8+ 迁移的语义。
执行数据库升级时必须按以下步骤完成:
1. 判断是否需要升级数据库版本:凡是新增/删除/重命名表、字段、索引、约束、列类型、分表规则,或改变持久化数据语义,都必须升级。
2. 新增 `openflare_server/model/migrate/vN.go`,其中 `N` 为目标版本号。文件头部必须包含注释,说明本次升级了什么内容,以及为什么需要升级。
3. 在 `vN.go` 中实现 `VN()`,并在 `init()` 中调用 `Register(VN())`。`FromVersion` 必须等于 `N-1`,`ToVersion` 必须等于 `N`。
4. 在 `migrateVN` 中写入升级逻辑。可通过 `Context` 调用 `ApplyCurrentSchema`、历史 backfill、默认数据初始化等公共能力;复杂数据修复必须显式处理,不得只依赖 `AutoMigrate`。
5. 在 `validateVN` 中写入升级后的校验逻辑。校验至少要覆盖新增表/字段/索引是否存在、关键默认数据是否存在、必要的数据回填是否成功。
6. 如果新迁移需要新的公共 backfill 或校验辅助函数,将其放在 `openflare_server/model/migrations.go` 或更合适的 model 文件中,并通过 `Context` 暴露给 `model/migrate`,避免子包反向 import `model` 造成循环依赖。
7. 补充迁移测试:至少覆盖从 `N-1` 老库升级到 `N` 后 schema version、字段/表结构、关键数据回填和校验结果。注册表连续性由 `model/migrate` 测试兜底,但具体业务迁移仍必须有测试。
8. 同步更新设计/开发文档;如果管理端 API、配置项或用户可见行为变化,还要同步更新对应指南、配置参考和 Swagger 文档。
新包启动后必须先检查数据库当前版本,再按顺序逐步升级到目标版本;禁止跳过中间升级步骤直接写目标版本。
空库初始化可以直接建立当前版本结构,但初始化完成后仍必须执行同版本校验,并落库当前数据库版本。
+11
View File
@@ -183,6 +183,17 @@ Every time the database version number is upgraded, an explicit migration method
Versions 1 through 7 are treated as the historical initial baseline and no longer keep per-version upgrade files. Starting from v8, database migrations must be placed under `openflare_server/model/migrate` and named after the target version, such as `v16.go`. Each version file registers its migration through `init()`, and the current database version is derived from the highest registered target version. Do not change the semantics of released v8+ migrations merely to reorganize files.
When performing a database upgrade, complete the following steps:
1. Decide whether a schema version bump is required: any addition, removal, or rename of tables, columns, indexes, constraints, column types, sharding rules, or persisted-data semantics must upgrade the version.
2. Add `openflare_server/model/migrate/vN.go`, where `N` is the target version. The file header must include a comment explaining what this upgrade changes and why it is needed.
3. Implement `VN()` in `vN.go`, and call `Register(VN())` from `init()`. `FromVersion` must be `N-1`, and `ToVersion` must be `N`.
4. Implement the upgrade logic in `migrateVN`. Use `Context` to call shared capabilities such as `ApplyCurrentSchema`, historical backfills, and default-data initialization; complex data repairs must be explicit and must not rely on `AutoMigrate` alone.
5. Implement post-upgrade validation in `validateVN`. Validation must cover at least the existence of new tables/columns/indexes, required default data, and required data backfills.
6. If the migration needs new shared backfill or validation helpers, place them in `openflare_server/model/migrations.go` or another suitable model file, and expose them through `Context` to `model/migrate`; avoid reverse-importing `model` from the subpackage and creating an import cycle.
7. Add migration tests covering at least upgrade from the `N-1` old database to `N`, including schema version, table/column structure, key data backfills, and validation results. The `model/migrate` registry test checks version continuity, but business-specific migrations still require tests.
8. Update design/development docs; if management APIs, configuration fields, or user-visible behavior change, also update the relevant guides, configuration reference, and Swagger documents.
After starting the new package, the database's current version must be checked first, and then upgraded step by step in order to the target version; skipping intermediate upgrade steps to directly write the target version is prohibited.
An empty database initialization can directly establish the current version structure, but the same-version validation must still be executed after the initialization is completed, and the current database version must be persisted.
+2
View File
@@ -1,3 +1,5 @@
// v10 升级内容:新增可配置认证源与第三方账号绑定,并迁移旧 GitHub 登录配置。
// 背景说明:登录体系从固定 GitHub OAuth 字段演进为通用认证源模型,需要创建 auth_sources、external_accounts,并把旧用户 GitHub 绑定迁移到新表。
package migrate
import "gorm.io/gorm"
+2
View File
@@ -1,3 +1,5 @@
// v11 升级内容:新增 ACME 账户、DNS 账户,并扩展证书 provider 字段。
// 背景说明:证书申请能力从单一手工导入扩展到自动签发,需要持久化 ACME/DNS 凭据,并标记证书来源。
package migrate
import "gorm.io/gorm"
+2
View File
@@ -1,3 +1,5 @@
// v12 升级内容:为 proxy_routes 增加 Basic Auth 相关字段。
// 背景说明:站点级访问控制需要支持基础认证,因此在代理路由配置中持久化 Basic Auth 开关与凭据配置。
package migrate
import "gorm.io/gorm"
+2
View File
@@ -1,3 +1,5 @@
// v13 升级内容:新增 WAF 规则组与站点绑定表,并创建默认全局规则组。
// 背景说明:WAF 配置从零散站点字段演进为可复用规则组,需要全局规则组作为默认入口,并支持站点与规则组绑定。
package migrate
import "gorm.io/gorm"
+2
View File
@@ -1,3 +1,5 @@
// v14 升级内容:为 WAF 规则组增加 PoW 策略字段。
// 背景说明:PoW 能力从站点路由侧沉淀到 WAF 规则组中,便于统一按规则组管理人机挑战策略。
package migrate
import "gorm.io/gorm"
+2
View File
@@ -1,3 +1,5 @@
// v15 升级内容:为 nodes 增加 ip_manual_override 字段。
// 背景说明:管理端手动指定节点 IP 后,Agent 心跳不应继续覆盖该值,因此需要在节点表中记录 IP 是否由管理端锁定。
package migrate
import (
+2
View File
@@ -1,3 +1,5 @@
// v8 升级内容:为 proxy_routes 增加域名级证书绑定字段 domain_cert_ids,并回填已有站点的证书映射。
// 背景说明:v1-v7 已作为历史初始基线合并;v8 是当前保留逐版本升级链的起点,用于把早期站点级证书列表扩展为每个域名可独立绑定证书。
package migrate
import "gorm.io/gorm"
+2
View File
@@ -1,3 +1,5 @@
// v9 升级内容:为 proxy_routes 增加 PoW 防护配置字段。
// 背景说明:反向代理站点需要支持 Proof-of-Work 抗机器人能力,因此在路由配置中持久化 PoW 开关与策略,并沿用 v8 的证书与站点字段回填。
package migrate
import "gorm.io/gorm"