# Gin Mode Config Design 日期:2026-07-02 ## 目标 移除 `internal/api.NewRouter` 中硬编码的: ```go gin.SetMode(gin.ReleaseMode) ``` 改为通过项目配置控制 Gin mode。 ## 当前问题 当前 `NewRouter` 写死 release mode。这个做法有两个问题: 1. 开发、测试、生产不能用同一套配置机制控制 Gin mode。 2. Gin mode 是运行配置,不应该藏在 router 代码里。 ## 非目标 本次不做: - 不改变 API 路径、method、响应结构。 - 不改变 Gin middleware。 - 不改变 slog 日志策略。 - 不引入新依赖。 - 不实现 auth/CORS/WebSocket/Git/LSP/Agent。 ## 配置设计 `configs/config.yaml` 增加: ```yaml gin: mode: "release" ``` `pkg/config` 增加: ```go type GinConfig struct { Mode string `yaml:"mode"` } ``` `Config` 增加: ```go Gin GinConfig `yaml:"gin"` ``` 默认值: ```text release ``` 环境变量覆盖: ```text CODESPACE_GIN_MODE ``` 合法值: - `debug` - `release` - `test` 非法值在 `config.Load` 阶段返回错误。不要等到 router 初始化才失败。 ## Router 设计 `api.NewRouter` 签名改为: ```go func NewRouter( workspaces *service.WorkspaceService, files *service.FileService, processes *service.ProcessService, lg *slog.Logger, ginMode string, ) *gin.Engine ``` 内部: ```go gin.SetMode(ginMode) r := gin.New() ``` `NewRouter` 不负责校验 mode。校验属于 config 层。 ## main.go 设计 ```go router := api.NewRouter(workspaceSvc, fileSvc, processSvc, lg, cfg.Gin.Mode) ``` ## 测试设计 ### config tests 覆盖: - 默认 mode 是 `release` - YAML 可设置 `debug` - env `CODESPACE_GIN_MODE` 可覆盖为 `test` - 非法 mode 返回错误 ### router tests 所有测试调用: ```go NewRouter(wsSvc, fileSvc, procSvc, nil, gin.TestMode) ``` 这样测试明确使用 Gin test mode。 ### validation 必须通过: ```sh gofmt -w cmd internal pkg go test ./... grep -R "gin.SetMode(gin.ReleaseMode)" cmd internal pkg || true grep -R "gin\.Default\|gin\.Logger" cmd internal pkg || true ``` 预期: - 不再出现 `gin.SetMode(gin.ReleaseMode)` - 不出现 `gin.Default` / `gin.Logger` ## 风险与处理 - 风险:Gin mode 是全局状态,测试互相污染。处理:router tests 统一传 `gin.TestMode`。 - 风险:非法 mode 到运行时才失败。处理:config.Load 阶段校验。 - 风险:把 Gin mode 塞进 `server` 配置造成语义混乱。处理:独立 `gin` 配置块。 ## 完成标准 - `configs/config.yaml` 有 `gin.mode`。 - `config.Default()` 返回 `Gin.Mode == "release"`。 - `CODESPACE_GIN_MODE` 可覆盖 mode。 - 非法 mode 让 `config.Load` 返回错误。 - `NewRouter` 不再硬编码 `gin.ReleaseMode`。 - `main.go` 从 config 传入 Gin mode。 - `go test ./...` 通过。 - server smoke test 通过。