生成openspace任务列表

This commit is contained in:
2025-10-30 16:10:10 +08:00
parent 93f67812ae
commit 2c9b4777ae
7 changed files with 181 additions and 2018 deletions

View File

@@ -0,0 +1,78 @@
## Context
当前 API 服务基于 Gin 构建。本次任务的目标是将其完整迁移到 Echo 框架同时保持功能和接口的完全向后兼容。这包括路由、请求处理、中间件、Swagger 文档和 pprof 分析工具。
## Goals / Non-Goals
- **Goals**:
- 成功将 Web 框架从 Gin 迁移到 Echo v4。
- 保持所有现有 API 端点的路径、方法和行为不变。
- 确保所有自定义中间件(认证、审计日志)功能正常。
- 确保 Swagger UI 可以在 `/swagger/index.html` 正常访问。
- 确保 pprof 调试端点在 `/debug/pprof/*` 路径下正常工作。
- **Non-Goals**:
- 增加任何新的 API 端点或功能。
- 修改任何现有的 API 请求/响应模型。
- 在本次变更中引入新的业务逻辑。
## Decisions
以下是从 Gin 到 Echo 的关键组件映射决策:
1. **框架实例**:
- **From**: `gin.SetMode(cfg.Mode)`, `engine := gin.New()`, `engine.Use(gin.Recovery())`
- **To**: `e := echo.New()`, `e.Debug = (cfg.Mode == "debug")`, `e.Use(middleware.Recover())`
- **Rationale**: `echo.New()` 提供了干净的实例。Echo 的 `Debug` 属性控制调试模式可以根据配置设置。Echo 提供了内置的 `middleware.Recover()` 来替代 Gin 的 Recovery 中间件。
- **Implementation**:
-`internal/app/api/api.go` 中,将 `engine *gin.Engine` 替换为 `engine *echo.Echo`,并更新 `NewAPI` 方法中的初始化逻辑。
-`config.yml``config.example.yml` 中, 更新关于 `mode` 配置项的注释, 将 "Gin 运行模式" 修改为 "服务运行模式", 因为该配置项现在控制 Echo 的调试模式。
2. **上下文对象 (Context) 与处理器签名**:
- **From**: `func(c *gin.Context)`
- **To**: `func(c echo.Context) error`
- **Rationale**: 这是两个框架的核心区别。所有控制器处理函数签名都需要更新。常见方法映射如下:
- `ctx.ShouldBindJSON(&req)` -> `c.Bind(&req)` (Echo 的 `Bind` 更通用,能根据 `Content-Type` 自动选择解析器)
- `ctx.ShouldBindQuery(&req)` -> `c.Bind(&req)`
- `ctx.Param("id")` -> `c.Param("id")` (签名相同)
- `ctx.GetHeader("Authorization")` -> `c.Request().Header.Get("Authorization")`
- `ctx.Set("key", value)` -> `c.Set("key", value)` (签名相同)
- `ctx.Get("key")` -> `c.Get("key")` (签名相同)
- `ctx.ClientIP()` -> `c.RealIP()`
- `controller.SendResponse(ctx, ...)` -> `return controller.SendResponse(c, ...)` (控制器方法需要返回 `error`,辅助函数也需要修改以返回 `error`)
- `controller.SendErrorResponse(ctx, ...)` -> `return controller.SendErrorResponse(c, ...)` (同上)
- `ctx.AbortWithStatusJSON(...)` -> `return c.JSON(...)` (在中间件中,通过 `return c.JSON(...)` 来中断链并响应)
3. **中间件 (Middleware)**:
- **From**: `func AuthMiddleware(...) gin.HandlerFunc { return func(c *gin.Context) { ... } }`
- **To**: `func AuthMiddleware(...) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { ...; return next(c) } } }`
- **Rationale**: Echo 的中间件是一个包装器模式。我们需要将现有的 `AuthMiddleware``AuditLogMiddleware` 逻辑迁移到这个新的结构中。中断请求链的方式从 `c.AbortWithStatusJSON()` 变为从处理函数中 `return c.JSON(...)`
4. **Swagger 集成**:
- **From**: `github.com/swaggo/gin-swagger`
- **To**: `github.com/swaggo/echo-swagger`
- **Rationale**: 这是 `swaggo` 官方为 Echo 提供的适配库,可以无缝替换。
- **Implementation**: 在 `router.go` 中使用 `e.GET("/swagger/*", echoSwagger.WrapHandler)`
5. **Pprof 与其他 `net/http` 处理器集成**:
- **From**: `gin.WrapH``gin.WrapF`
- **To**: `echo.WrapHandler``echo.WrapFunc`
- **Rationale**: Echo 提供了类似的 `net/http` 处理器包装函数,可以轻松集成 pprof 和项目中的 `listenHandler`
- **Implementation**: 在 `router.go` 中替换所有 `gin.WrapH``gin.WrapF` 的调用。
6. **控制器辅助函数**:
- **Affected Files**:
- `internal/app/controller/response.go`
- `internal/app/controller/auth_utils.go`
- `internal/app/controller/management/controller_helpers.go`
- **Change**:
-`response.go``auth_utils.go` 中, 所有接收 `*gin.Context` 的辅助函数 (如 `SendResponse`, `GetOperatorIDFromContext` 等) 签名都需要修改为接收 `echo.Context`
-`controller_helpers.go` 中, `handle...` 系列的泛型辅助函数 (如 `handleAPIRequest`, `handleNoBodyAPIRequest` 等) 及其依赖的 `extractOperatorAndPrimaryID``mapAndSendError` 函数, 都需要将其中的 `*gin.Context` 参数和相关调用 (如 `ShouldBindJSON`) 替换为 `echo.Context` 的等效实现。
- 所有这些辅助函数, 如果它们原本不返回 `error`, 现在需要修改为返回 `error`, 以便与 Echo 的处理器错误链兼容。例如, `SendResponse` 这类函数在调用 `c.JSON(...)` 后, 最终应 `return nil`
- **Rationale**: 这些辅助函数封装了请求处理、响应发送和错误处理的核心逻辑, 必须进行适配以兼容 Echo 的 `echo.Context` 上下文对象和 `return error` 的错误处理模式。
## Risks / Trade-offs
- **Risk**: 迁移工作量大,可能遗漏某些 Gin 特有的功能或上下文用法,导致运行时错误。
- **Mitigation**: 采用逐个文件、逐个控制器修改的方式,每修改完一部分就进行编译检查。在完成所有编码后,进行全面的手动 API 测试。
- **Risk**: `AuditLogMiddleware` 中间件依赖 `bodyLogWriter` 捕获响应体,需要验证其与 Echo 的 `ResponseWriter` 是否兼容或需要寻找替代方案。
- **Mitigation**: 在迁移中间件时,优先研究 Echo 官方推荐的 Body Dump 或类似中间件,如果不适用,再尝试适配 `bodyLogWriter`

View File

@@ -0,0 +1,26 @@
## Why
本项目当前使用 Gin 作为核心 Web 框架。Gin 的路由系统存在一些限制,例如无法优雅地支持类似 `/:id/action``/:other_id/other-action` 这种在同一层级使用不同动态参数的路由模式。为了解决此问题并利用更现代、灵活的路由和中间件系统,我们计划将框架迁移到 Echo (v4)。本次变更仅进行框架替换,暂不修改现有路由结构。
## What Changes
- **核心框架替换**: 将 `github.com/gin-gonic/gin` 的所有引用替换为 `github.com/labstack/echo/v4`
- **API 路由重写**: 更新 `internal/app/api/router.go` 以使用 Echo 的路由注册方式。
- **上下文对象适配**: 在所有 Controller 和 Middleware 中,将 `*gin.Context` 替换为 `echo.Context`,并调整相关方法调用。
- **中间件迁移**: 将现有的 Gin 中间件 (`AuthMiddleware`, `AuditLogMiddleware`) 适配为 Echo 的中间件格式。
- **Swagger 文档适配**: 将 `gin-swagger` 替换为 Echo 兼容的 `echo-swagger`,确保 API 文档能够正常生成和访问。
- **Pprof 路由适配**: 确保性能分析工具 pprof 的路由在 Echo 框架下正常工作。
**BREAKING**: 这是一项纯粹的技术栈重构,**不应该**对外部 API 消费者产生任何破坏性影响。所有 API 端点、请求/响应格式将保持完全兼容。
## Impact
- **Affected specs**: 无。此变更是技术实现层面的重构,不改变任何已定义的功能规约。
- **Affected code**:
- `go.mod` / `go.sum`: 依赖项变更。
- `config.yml` / `config.example.yml`: 更新 `mode` 配置项的注释。
- `internal/app/api/api.go`
- `internal/app/api/router.go`
- `internal/app/middleware/auth.go`
- `internal/app/middleware/audit.go`
- `internal/app/controller/**/*.go`: 所有控制器及其辅助函数。

View File

@@ -0,0 +1,17 @@
# HTTP Server Specification
本文档概述了 HTTP 服务器的需求。
## MODIFIED Requirements
### Requirement: API 服务器框架已更新
- **说明**: 底层 Web 框架从 Gin 迁移到 Echo。所有现有的 API 端点 **MUST** 保持功能齐全和向后兼容。
- **理由**: 为了提高路由灵活性并使技术栈现代化。这是一次技术重构,不会改变任何外部 API 行为。
- **影响**: 高。影响核心请求处理、路由和中间件。
- **受影响的端点**: 全部。
#### Scenario: 所有现有的 API 端点保持功能齐全和向后兼容
- **假如**: API 服务器在迁移到 Echo 后正在运行。
- **当**: 客户端向任何现有的 API 端点(例如, `POST /api/v1/users/login`)发送请求。
- **那么**: 服务器处理该请求并返回与使用 Gin 框架时完全相同的响应(状态码、头部和正文格式)。

View File

@@ -0,0 +1,60 @@
## 任务清单Gin 到 Echo 迁移
- [ ] **1. 配置文件 (无代码依赖)**
- [ ] 修改 `config.yml``mode` 配置项的注释,将 "Gin 运行模式" 改为 "服务运行模式"。
- [ ] 修改 `config.example.yml``mode` 配置项的注释,保持与 `config.yml` 一致。
- [ ] **2. 控制器辅助函数 (最基础的依赖)**
- [ ] **`internal/app/controller/response.go`**
- [ ]`*gin.Context` 参数全部替换为 `echo.Context`
- [ ] 修改 `SendResponse``SendErrorResponse` 等函数,使其不再直接写入响应,而是返回 `error`,并在内部调用 `c.JSON(...)`
- [ ] **`internal/app/controller/auth_utils.go`**
- [ ]`*gin.Context` 参数全部替换为 `echo.Context`
- [ ] 适配 `Get...FromContext` 系列函数,使用 `c.Get("key")` 提取数据。
- [ ] **3. 中间件 (`internal/app/middleware`)**
- [ ] **`auth.go`**
- [ ]`import "github.com/gin-gonic/gin"` 替换为 `import "github.com/labstack/echo/v4"`
- [ ] 将中间件函数签名从 `func AuthMiddleware(...) gin.HandlerFunc` 更新为 `func AuthMiddleware(...) echo.MiddlewareFunc`
- [ ] 适配中间件内部逻辑,将 `func(c *gin.Context)` 改造为 `func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { ... } }` 的结构。
- [ ]`c.AbortWithStatusJSON(...)` 调用替换为 `return c.JSON(...)`
- [ ] 在逻辑正常通过的末尾,调用 `return next(c)`
- [ ] **4. 控制器 (`internal/app/controller/...`)**
- [ ] **通用修改**:对所有控制器文件执行以下操作:
- [ ]`import "github.com/gin-gonic/gin"` 替换为 `import "github.com/labstack/echo/v4"`
- [ ] 将所有处理函数签名从 `func(c *gin.Context)` 修改为 `func(c echo.Context) error`
- [ ]`c.ShouldBindJSON(&req)``c.ShouldBindQuery(&req)` 替换为 `if err := c.Bind(&req); err != nil { ... }`
- [ ]`c.Param("id")` 替换为 `c.Param("id")` (用法相同,检查返回值即可)。
- [ ]`controller.SendResponse(c, ...)``controller.SendErrorResponse(c, ...)` 调用修改为 `return controller.SendResponse(c, ...)``return controller.SendErrorResponse(c, ...)`
- [ ] **文件清单** (按依赖顺序建议):
- [ ] `internal/app/controller/management/controller_helpers.go` (注意此文件中的泛型辅助函数也需要适配)
- [ ] `internal/app/controller/device/device_controller.go`
- [ ] `internal/app/controller/management/pig_batch_controller.go`
- [ ] `internal/app/controller/plan/plan_controller.go`
- [ ] `internal/app/controller/user/user_controller.go`
- [ ] **5. 核心 API 层 (`internal/app/api`)**
- [ ] **`router.go`**
- [ ] 将所有 `router.GET`, `router.POST` 等 Gin 路由注册方法替换为 Echo 的 `e.GET`, `e.POST` 等方法。
- [ ] 将 Swagger 路由 `router.GET("/swagger/*", ginSwagger.WrapHandler(swaggerFiles.Handler))` 替换为 `e.GET("/swagger/*", echoSwagger.WrapHandler)`
- [ ] 将 pprof 路由的 `gin.WrapH``gin.WrapF` 调用替换为 `echo.WrapHandler``echo.WrapFunc`
- [ ] **`api.go`**
- [ ]`engine *gin.Engine` 替换为 `engine *echo.Echo`
- [ ] 更新 `NewAPI` 函数:
- [ ]`gin.SetMode(cfg.Mode)` 替换为 `e.Debug = (cfg.Mode == "debug")`
- [ ]`gin.New()` 替换为 `echo.New()`
- [ ]`engine.Use(gin.Recovery())` 替换为 `e.Use(middleware.Recover())`
- [ ] **6. 依赖管理**
- [ ]`go.mod` 中移除 `github.com/gin-gonic/gin`
- [ ]`go.mod` 中移除 `github.com/swaggo/gin-swagger`
- [ ]`go.mod` 中添加 `github.com/labstack/echo/v4`
- [ ]`go.mod` 中添加 `github.com/swaggo/echo-swagger`
- [ ] 执行 `go mod tidy` 清理依赖项。
- [ ] **7. 验证**
- [ ] 运行 `go build ./...` 确保项目能够成功编译。
- [ ] 启动服务,手动测试所有 API 端点,验证功能是否与迁移前一致。
- [ ] 访问 `/swagger/index.html`,确认 Swagger UI 是否正常工作。
- [ ] (可选) 访问 `/debug/pprof/`,确认 pprof 路由是否正常。