This repository has been archived on 2026-07-17. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
codespace/docs/superpowers/specs/2026-07-02-gin-mode-config-design.md
T
2026-07-02 17:46:04 +08:00

157 lines
2.8 KiB
Markdown

# 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 通过。