From 1c1063f448d9f92909c8a674616abf6afd60d9ff Mon Sep 17 00:00:00 2001 From: ryan Date: Thu, 4 Jun 2026 10:21:07 +0800 Subject: [PATCH] =?UTF-8?q?[=E4=BC=98=E5=8C=96]=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 57 +++++++------------ ...003_drop_pages_deployment_unused_fields.go | 4 +- openflare_server/model/main_test.go | 54 ++++++++++++++++++ 3 files changed, 75 insertions(+), 40 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index b0f9901c..8fe5e7b4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,11 +2,27 @@ 本文件是 OpenFlare 的 AI 接手入口,不承载详细设计、规范和计划。接手项目时,请根据以下分层文档指引进行阅读与开发: -## 1. 核心必读文档(Level 3 & Level 4)- 必须阅读 ⚠️ + +### 面向 AI 的开发指导规范 (AI Guidelines) 必须阅读 ⚠️ 为了理解 OpenFlare 的设计理念、产品边界、核心机制以及代码编写的工程约束,**AI 在接手项目时必须首先且完整阅读以下文档**: -### Level 3: 面向贡献者的参阅文档 (Contributor References) +* **[docs/guildline/development-constraints.md](./docs/guildline/development-constraints.md)** + *作用:掌握核心后端/Agent/前端分层约束、数据模型规范、数据库迁移升级协议、API 与鉴权设计准则。* +* **[docs/guildline/Guidelines.md](./docs/guildline/Guidelines.md)** + *作用:通用的 Go 后端开发与高质量编码准则,包括架构、并发、错误处理、安全及工作流程。* +* **[docs/guildline/Project.md](./docs/guildline/Project.md)** + *作用:针对 OpenFlare 后端特定的控制器参数解析、响应处理、纯净工具类与数据库逻辑完全隔离、Go 泛型切片去重及 JSON 序列化避坑细则。* + +### 系统参阅文档 按需查阅 +* **[docs/reference/configuration.md](./docs/reference/configuration.md)** + *作用:系统启动时支持的所有环境变量、命令行参数、运行时 Option 选项和 Agent 配置文件字段。* +* **[docs/reference/cli.md](./docs/reference/cli.md)** + *作用:Server 与 Agent 可用的命令行参数、安装/卸载脚本参数等参考。* +* **[docs/reference/api.md](./docs/reference/api.md)** + *作用:管理端 API 与 Agent API 的响应结构、路径和详细鉴权约定。* + +### 面向开发者的文档 按需查阅 * **[docs/design/index.md](./docs/design/index.md)** *作用:理解当前 MVP 的产品范围、系统边界、核心对象和长期约束。* * **[docs/design/architecture.md](./docs/design/architecture.md)** @@ -18,29 +34,7 @@ * **[docs/design/repository.md](./docs/design/repository.md)** *作用:熟悉仓库的整体物理结构和各子目录的职责。* -### Level 4: 面向 AI 的开发指导规范 (AI Guidelines) -* **[docs/guildline/development-constraints.md](./docs/guildline/development-constraints.md)** - *作用:掌握核心后端/Agent/前端分层约束、数据模型规范、数据库迁移升级协议、API 与鉴权设计准则。* -* **[docs/guildline/Guidelines.md](./docs/guildline/Guidelines.md)** - *作用:通用的 Go 后端开发与高质量编码准则,包括架构、并发、错误处理、安全及工作流程。* -* **[docs/guildline/Project.md](./docs/guildline/Project.md)** - *作用:针对 OpenFlare 后端特定的控制器参数解析、响应处理、纯净工具类与数据库逻辑完全隔离、Go 泛型切片去重及 JSON 序列化避坑细则。* - ---- - -## 2. 按需查阅文档(Level 2)- 根据需求阅读 💡 - -当开发任务涉及具体的系统部署、升级、接口联调或配置字段查阅时,**AI 应当根据需求阅读相应的参考手册**: - -### Level 2: 面对高级用户/开发者的参阅文档 (Reference Manuals) -* **[docs/reference/configuration.md](./docs/reference/configuration.md)** - *作用:系统启动时支持的所有环境变量、命令行参数、运行时 Option 选项和 Agent 配置文件字段。* -* **[docs/reference/cli.md](./docs/reference/cli.md)** - *作用:Server 与 Agent 可用的命令行参数、安装/卸载脚本参数等参考。* -* **[docs/reference/api.md](./docs/reference/api.md)** - *作用:管理端 API 与 Agent API 的响应结构、路径和详细鉴权约定。* - -### Level 2: 部署与升级指南 (Deployment Guides) +### 部署与升级指南 * **[docs/deployment/deployment.md](./docs/deployment/deployment.md)** *作用:理解 Server 和 Agent 的单机、Docker 部署配置,以及 Agent 接入、升级、卸载和联调步骤。* * **[docs/deployment/server.md](./docs/deployment/server.md)** @@ -52,19 +46,6 @@ --- -## 3. 新手与业务教程(Level 1)- 体验与排障参考 📘 - -如果任务涉及优化最终用户体验、丰富业务能力或排查常见故障,可参阅面向普通用户的指南: - -### Level 1: 面向新手用户的教程文档 (Novice Tutorials) -* **[docs/guide/quick-start.md](./docs/guide/quick-start.md)**:五分钟内基于 Docker Compose 快速跑起 Server 和首个 Agent 节点的完整闭环。 -* **[docs/guide/usage.md](./docs/guide/usage.md)**:反向代理网站、源站、证书托管、配置发布与回滚的常规界面操作与观测功能使用指南。 -* **[docs/guide/sso.md](./docs/guide/sso.md)**:系统如何配置 GitHub OAuth 及标准 OIDC 第三方登录,以及绑定本地账户的流程。 -* **[docs/guide/first-site.md](./docs/guide/first-site.md)**:从零开始配置、发布并验证第一个代理网站的完整步骤。 -* **[docs/guide/troubleshooting.md](./docs/guide/troubleshooting.md)**:常见数据库迁移、节点离线、OpenResty 校验失败、SSL 证书失效等故障的表现症状及标准排障路径。 - ---- - ## 执行要求 * 如果实现内容超出 [产品边界](./docs/design/index.md),先修改设计文档,再继续编码。 diff --git a/openflare_server/model/goose/goose_202606040003_drop_pages_deployment_unused_fields.go b/openflare_server/model/goose/goose_202606040003_drop_pages_deployment_unused_fields.go index 14602877..a86e4963 100644 --- a/openflare_server/model/goose/goose_202606040003_drop_pages_deployment_unused_fields.go +++ b/openflare_server/model/goose/goose_202606040003_drop_pages_deployment_unused_fields.go @@ -23,12 +23,12 @@ func migration202606040003(backend string, ctx Context) *presslygoose.Migration func migratePagesDeploymentDropUnusedFields(ctx Context, db *gorm.DB, backend string) error { // Drop columns root_dir and entry_file from pages_deployments if db.Migrator().HasColumn("pages_deployments", "root_dir") { - if err := db.Migrator().DropColumn("pages_deployments", "root_dir"); err != nil { + if err := db.Exec("ALTER TABLE pages_deployments DROP COLUMN root_dir").Error; err != nil { return fmt.Errorf("failed to drop pages_deployments.root_dir: %w", err) } } if db.Migrator().HasColumn("pages_deployments", "entry_file") { - if err := db.Migrator().DropColumn("pages_deployments", "entry_file"); err != nil { + if err := db.Exec("ALTER TABLE pages_deployments DROP COLUMN entry_file").Error; err != nil { return fmt.Errorf("failed to drop pages_deployments.entry_file: %w", err) } } diff --git a/openflare_server/model/main_test.go b/openflare_server/model/main_test.go index 552a78ab..584b4f10 100644 --- a/openflare_server/model/main_test.go +++ b/openflare_server/model/main_test.go @@ -830,3 +830,57 @@ func TestAllGORMModelsAreRegistered(t *testing.T) { } } } + +func TestEnsureDatabaseSchemaUpToDateDropsPagesDeploymentUnusedFields(t *testing.T) { + db := openBareTestSQLiteDB(t, "drop-pages-deployment-unused-fields.db") + if err := registerSharding(db, "sqlite"); err != nil { + t.Fatalf("register sharding: %v", err) + } + + if err := ensureDatabaseSchemaUpToDate(db, "sqlite"); err != nil { + t.Fatalf("first ensureDatabaseSchemaUpToDate: %v", err) + } + + // Verify columns do not exist + if db.Migrator().HasColumn("pages_deployments", "root_dir") { + t.Fatal("expected root_dir column to be absent initially") + } + if db.Migrator().HasColumn("pages_deployments", "entry_file") { + t.Fatal("expected entry_file column to be absent initially") + } + + // Manually add columns to simulate old state + if err := db.Exec("ALTER TABLE pages_deployments ADD COLUMN root_dir TEXT").Error; err != nil { + t.Fatalf("failed to add root_dir column: %v", err) + } + if err := db.Exec("ALTER TABLE pages_deployments ADD COLUMN entry_file TEXT").Error; err != nil { + t.Fatalf("failed to add entry_file column: %v", err) + } + + // Verify columns were added + if !db.Migrator().HasColumn("pages_deployments", "root_dir") { + t.Fatal("expected root_dir column to be present after manual add") + } + if !db.Migrator().HasColumn("pages_deployments", "entry_file") { + t.Fatal("expected entry_file column to be present after manual add") + } + + // Remove the migration record from goose_db_version table + const versionToRerun = 202606040003 + if err := db.Exec("DELETE FROM goose_db_version WHERE version_id = ?", versionToRerun).Error; err != nil { + t.Fatalf("failed to delete migration record: %v", err) + } + + // Run migration again + if err := ensureDatabaseSchemaUpToDate(db, "sqlite"); err != nil { + t.Fatalf("second ensureDatabaseSchemaUpToDate: %v", err) + } + + // Verify columns were dropped successfully + if db.Migrator().HasColumn("pages_deployments", "root_dir") { + t.Fatal("expected root_dir column to be dropped after migration rerun") + } + if db.Migrator().HasColumn("pages_deployments", "entry_file") { + t.Fatal("expected entry_file column to be dropped after migration rerun") + } +}