Files
huang 62708892ec
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m2s
文档
2026-01-31 13:06:30 +08:00

176 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`