All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m2s
176 lines
5.2 KiB
Markdown
176 lines
5.2 KiB
Markdown
# Gateway Config Specification
|
||
|
||
Gateway API 的配置集成规范,定义配置结构和加载方式。
|
||
|
||
## ADDED Requirements
|
||
|
||
### Requirement: Gateway 配置结构
|
||
|
||
系统 SHALL 在 `pkg/config/config.go` 中添加 `GatewayConfig` 结构体。
|
||
|
||
配置字段:
|
||
- `BaseURL string` - Gateway API 基础 URL
|
||
- `AppID string` - 应用 ID
|
||
- `AppSecret string` - 应用密钥
|
||
- `Timeout int` - 请求超时时间(秒)
|
||
|
||
#### Scenario: 配置结构定义
|
||
|
||
- **WHEN** 定义 `GatewayConfig` 结构体
|
||
- **THEN** 包含 `mapstructure` 标签用于 Viper 解析
|
||
- **AND** 字段名使用 snake_case(如 `base_url`、`app_id`)
|
||
|
||
#### Scenario: 集成到主配置
|
||
|
||
- **WHEN** 在 `Config` 结构体中添加 `Gateway GatewayConfig` 字段
|
||
- **THEN** 使用 `mapstructure:"gateway"` 标签
|
||
- **AND** 配置可通过 `config.Get().Gateway` 访问
|
||
|
||
### Requirement: 默认配置嵌入
|
||
|
||
系统 SHALL 在 `pkg/config/defaults/config.yaml` 中添加 Gateway 默认配置。
|
||
|
||
#### Scenario: 嵌入默认配置
|
||
|
||
- **WHEN** 读取嵌入的默认配置文件
|
||
- **THEN** 包含 `gateway` 配置节
|
||
- **AND** 配置包含:
|
||
```yaml
|
||
gateway:
|
||
base_url: "https://lplan.whjhft.com/openapi"
|
||
app_id: "60bgt1X8i7AvXqkd"
|
||
app_secret: "BZeQttaZQt0i73moF"
|
||
timeout: 30
|
||
```
|
||
|
||
### Requirement: 环境变量覆盖
|
||
|
||
系统 SHALL 支持通过环境变量覆盖 Gateway 配置。
|
||
|
||
环境变量格式:`JUNHONG_GATEWAY_{KEY}`
|
||
|
||
#### Scenario: 覆盖 BaseURL
|
||
|
||
- **WHEN** 设置环境变量 `JUNHONG_GATEWAY_BASE_URL=https://test.example.com`
|
||
- **THEN** `config.Gateway.BaseURL` 的值为 "https://test.example.com"
|
||
- **AND** 覆盖嵌入配置中的默认值
|
||
|
||
#### Scenario: 覆盖 AppID
|
||
|
||
- **WHEN** 设置环境变量 `JUNHONG_GATEWAY_APP_ID=test_app_id`
|
||
- **THEN** `config.Gateway.AppID` 的值为 "test_app_id"
|
||
|
||
#### Scenario: 覆盖 AppSecret
|
||
|
||
- **WHEN** 设置环境变量 `JUNHONG_GATEWAY_APP_SECRET=test_secret`
|
||
- **THEN** `config.Gateway.AppSecret` 的值为 "test_secret"
|
||
|
||
#### Scenario: 覆盖 Timeout
|
||
|
||
- **WHEN** 设置环境变量 `JUNHONG_GATEWAY_TIMEOUT=60`
|
||
- **THEN** `config.Gateway.Timeout` 的值为 60
|
||
|
||
### Requirement: 配置验证
|
||
|
||
系统 SHALL 在配置加载后验证 Gateway 配置的有效性。
|
||
|
||
#### Scenario: 必填字段验证
|
||
|
||
- **WHEN** 配置加载完成
|
||
- **THEN** 验证 `BaseURL`、`AppID`、`AppSecret` 不为空
|
||
- **AND** 如果为空,返回明确的错误信息
|
||
|
||
#### Scenario: BaseURL 格式验证
|
||
|
||
- **WHEN** 验证 `BaseURL` 字段
|
||
- **THEN** 必须以 `http://` 或 `https://` 开头
|
||
- **AND** 不能以 `/` 结尾
|
||
|
||
#### Scenario: Timeout 范围验证
|
||
|
||
- **WHEN** 验证 `Timeout` 字段
|
||
- **THEN** 值必须在 5 到 300 秒之间
|
||
- **AND** 如果超出范围,返回验证错误
|
||
|
||
#### Scenario: AppID 格式验证
|
||
|
||
- **WHEN** 验证 `AppID` 字段
|
||
- **THEN** 长度必须 > 0
|
||
- **AND** 不包含特殊字符(仅允许字母、数字、下划线)
|
||
|
||
### Requirement: 敏感配置处理
|
||
|
||
系统 SHALL 确保 `AppSecret` 不记录到日志中。
|
||
|
||
#### Scenario: 配置日志脱敏
|
||
|
||
- **WHEN** 记录配置加载成功的日志
|
||
- **THEN** `AppSecret` 字段显示为 "***"
|
||
- **AND** 实际值不出现在日志中
|
||
|
||
#### Scenario: 错误日志脱敏
|
||
|
||
- **WHEN** 配置验证失败并记录错误日志
|
||
- **THEN** `AppSecret` 字段显示为 "***"
|
||
|
||
### Requirement: Gateway 客户端初始化
|
||
|
||
系统 SHALL 在 `internal/bootstrap/bootstrap.go` 中初始化 Gateway 客户端。
|
||
|
||
#### Scenario: Bootstrap 中初始化
|
||
|
||
- **WHEN** 调用 `bootstrap.Bootstrap(deps)`
|
||
- **THEN** 从 `deps.Config.Gateway` 读取配置
|
||
- **AND** 调用 `gateway.NewClient(baseURL, appID, appSecret).WithTimeout(...)`
|
||
- **AND** 将客户端赋值给 `deps.GatewayClient`
|
||
|
||
#### Scenario: 配置错误时启动失败
|
||
|
||
- **WHEN** Gateway 配置验证失败
|
||
- **THEN** `bootstrap.Bootstrap` 返回错误
|
||
- **AND** 应用启动失败
|
||
|
||
### Requirement: 多环境配置支持
|
||
|
||
系统 SHALL 支持通过环境变量切换不同环境的 Gateway 配置。
|
||
|
||
#### Scenario: 开发环境配置
|
||
|
||
- **WHEN** 使用默认嵌入配置(未设置环境变量)
|
||
- **THEN** 使用生产环境的 Gateway URL 和凭证
|
||
|
||
#### Scenario: 测试环境配置
|
||
|
||
- **WHEN** 设置环境变量指向测试 Gateway
|
||
- **AND** `JUNHONG_GATEWAY_BASE_URL=https://test-gateway.example.com`
|
||
- **AND** `JUNHONG_GATEWAY_APP_ID=test_app_id`
|
||
- **THEN** 客户端连接到测试环境
|
||
|
||
## MODIFIED Requirements
|
||
|
||
### Requirement: Config 结构体扩展
|
||
|
||
系统 SHALL 在现有的 `Config` 结构体中添加 `Gateway` 字段。
|
||
|
||
#### Scenario: 配置结构兼容性
|
||
|
||
- **WHEN** 添加 `Gateway GatewayConfig` 字段
|
||
- **THEN** 不影响现有配置字段的加载
|
||
- **AND** 现有配置(Server、Database、Redis 等)继续正常工作
|
||
|
||
### Requirement: Dependencies 结构体扩展
|
||
|
||
系统 SHALL 在 `internal/bootstrap/bootstrap.go` 的 `Dependencies` 结构体中添加 `GatewayClient` 字段。
|
||
|
||
#### Scenario: 依赖注入扩展
|
||
|
||
- **WHEN** 在 `Dependencies` 中添加 `GatewayClient *gateway.Client` 字段
|
||
- **THEN** 不影响现有依赖的注入
|
||
- **AND** Gateway 客户端可以注入到需要的 Service
|
||
|
||
#### Scenario: Service 层使用
|
||
|
||
- **WHEN** Service 需要调用 Gateway API
|
||
- **THEN** 在 Service 构造函数中接收 `gatewayClient *gateway.Client` 参数
|
||
- **AND** 从 Bootstrap 中传递 `deps.GatewayClient`
|