feat(ci): normalize shared environment semantics
This commit is contained in:
98
docs/plans/2026-04-21-env-normalization-checklist.md
Normal file
98
docs/plans/2026-04-21-env-normalization-checklist.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# 2026-04-21 Env Normalization Checklist
|
||||
|
||||
## P2-C-01 三服务环境枚举与别名盘点
|
||||
|
||||
1. `gateway`
|
||||
- 当前输入源是 `GATEWAY_ENV`。
|
||||
- 共享环境判定历史上同时接受 `production`、`prod`、`online`。
|
||||
- `staging` 也被视为非开发共享环境,禁止 `inmemory` token runtime。
|
||||
2. `supply-api`
|
||||
- `ResolveEnv` 只接受 `dev`、`staging`、`prod`。
|
||||
- 默认配置路径按 `config.<env>.yaml` 组装。
|
||||
- 现有 devtest 脚本曾存在 `-env=staging -config=config.dev.yaml` 的错配。
|
||||
3. `platform-token-runtime`
|
||||
- `TOKEN_RUNTIME_ENV` 只接受 `dev`、`staging`、`prod`。
|
||||
- `staging/prod` 需要显式 PostgreSQL store,`dev` 才允许内存 store。
|
||||
4. 本次盘点覆盖的枚举全集:
|
||||
- 规范值:`dev`、`staging`、`prod`
|
||||
- 兼容别名:`production`、`online`
|
||||
|
||||
## P2-C-02 统一枚举
|
||||
|
||||
仓库内部只保留三种规范值:
|
||||
|
||||
1. `dev`
|
||||
2. `staging`
|
||||
3. `prod`
|
||||
|
||||
统一规则:
|
||||
|
||||
1. `production`、`online` 只允许作为兼容输入存在。
|
||||
2. 兼容输入一进入服务边界就必须立即折叠为 `prod`。
|
||||
3. 文档、模板、脚本、报告、CI 产物里不再引入新的别名。
|
||||
|
||||
## P2-C-03 gateway 归一化入口
|
||||
|
||||
唯一入口定在 `gateway/internal/config/config.go`:
|
||||
|
||||
1. `LoadConfig` 读取 `GATEWAY_ENV` 后立刻归一化。
|
||||
2. `ValidateAuthConfig` 与启动安全校验只消费归一化后的值。
|
||||
3. `bootstrap.go` 不再维护独立的 `production/online` 判定分支。
|
||||
|
||||
## P2-C-04 supply-api 错配拒绝规则
|
||||
|
||||
拒绝条件:
|
||||
|
||||
1. 当 `-env` 为 `staging` 或 `prod` 时,`-config` 不得指向 `config.dev.yaml` 或 `config.dev.yml`。
|
||||
|
||||
错误信息草稿:
|
||||
|
||||
`config path "<path>" is a dev template and cannot be used with -env=<env>; use config.<env>.yaml or a <env> example template instead`
|
||||
|
||||
## P2-C-05 staging 模板骨架
|
||||
|
||||
`supply-api/config/config.staging.example.yaml` 至少保留以下段落:
|
||||
|
||||
1. `server`
|
||||
2. `database`
|
||||
3. `redis`
|
||||
4. `token`
|
||||
5. `audit`
|
||||
|
||||
## P2-C-06 prod 模板骨架
|
||||
|
||||
`supply-api/config/config.prod.example.yaml` 必须额外显式包含:
|
||||
|
||||
1. `server.default_supplier_id: 0`
|
||||
2. `token.algorithm: RS256`
|
||||
3. `token.public_key`
|
||||
4. `settlement.withdraw_enabled`
|
||||
5. `sms` 占位字段
|
||||
|
||||
## P2-C-07 devtest 参数设计
|
||||
|
||||
`scripts/devtest/start_dev_stack.sh` 改为:
|
||||
|
||||
1. 使用 `LIJIAOQIAO_DEVTEST_SUPPLY_CONFIG` 作为 `supply-api` 配置路径参数。
|
||||
2. 默认值改为 `./config/config.staging.example.yaml`。
|
||||
3. 不再把 `config.dev.yaml` 硬编码进 staging 启动链路。
|
||||
|
||||
## P2-C-08 环境归一化检查清单
|
||||
|
||||
### 启动前检查
|
||||
|
||||
1. 所有新文档和样例文件只出现 `dev`、`staging`、`prod` 三种规范值。
|
||||
2. 兼容别名只存在于输入归一化代码,不存在于模板与脚本默认值。
|
||||
3. `supply-api` 的 `staging/prod` 启动命令不引用 `config.dev.yaml`。
|
||||
|
||||
### 启动后检查
|
||||
|
||||
1. `gateway` 在 `production` 或 `online` 输入下对外表现为 `prod` 语义。
|
||||
2. `supply-api` 在 `-env=staging -config=config.dev.yaml` 时必须 fail fast。
|
||||
3. `platform-token-runtime` 仍然只接受 `dev/staging/prod`,不新增额外别名。
|
||||
|
||||
### CI 检查
|
||||
|
||||
1. `gateway` 运行环境归一化相关单测。
|
||||
2. `supply-api` 运行命令行错配拒绝测试。
|
||||
3. `scripts/devtest/start_dev_stack.sh` 至少通过 `bash -n` 语法检查。
|
||||
@@ -113,3 +113,22 @@ git diff --check
|
||||
1. 已创建 `docs/plans/2026-04-21-real-staging-gate-rules.md`,逐项覆盖 `P2-B-01` 到 `P2-B-08`,写死 rehearsal / real staging 术语边界、`PASS_REAL|PASS_REHEARSAL|FAIL` 状态枚举、override 约束和完成率口径。
|
||||
2. 已在 `scripts/ci/superpowers_stage_validate.sh`、`scripts/ci/staging_real_readiness_check.sh`、`scripts/ci/superpowers_release_pipeline.sh`、`scripts/ci/final_decision_consistency_check.sh` 补入迁移设计注释,明确真实 staging 是唯一 release 硬门禁,且 `DEFERRED` / rehearsal 不得计入 release pass。
|
||||
3. 四个脚本 `bash -n` 通过,且 `git diff --check` 无格式错误;本批次仅落设计规则与迁移约束,没有伪装成已完成实现。
|
||||
|
||||
## P2-C 环境归一化与模板骨架完成
|
||||
|
||||
执行命令:
|
||||
|
||||
```bash
|
||||
bash -n scripts/devtest/start_dev_stack.sh
|
||||
go test ./internal/config ./internal/app
|
||||
go test ./cmd/supply-api ./internal/app ./internal/config
|
||||
git diff --check
|
||||
```
|
||||
|
||||
执行结果:
|
||||
|
||||
1. 已在 `docs/plans/2026-04-21-env-normalization-checklist.md` 盘点 `gateway`、`supply-api`、`platform-token-runtime` 的环境枚举,统一仓库内规范值为 `dev`、`staging`、`prod`,并补全启动前、启动后、CI 三类检查项。
|
||||
2. 已在 `gateway/internal/config/config.go` 增加单一 `NormalizeEnv` 入口,并让 `gateway/internal/app/bootstrap.go` 的生产安全判定复用该入口,收敛 `production/online -> prod` 兼容逻辑。
|
||||
3. 已在 `supply-api/cmd/supply-api/main.go` 增加 `staging/prod + config.dev.yaml` 的 fail-fast 拒绝规则,并补充命令行测试覆盖;同时新增 `supply-api/config/config.staging.example.yaml` 与 `supply-api/config/config.prod.example.yaml` 模板骨架。
|
||||
4. 已在 `scripts/devtest/start_dev_stack.sh` 引入 `LIJIAOQIAO_DEVTEST_SUPPLY_CONFIG` 参数,默认改用 `./config/config.staging.example.yaml`,去除 staging 启动链路里的 `config.dev.yaml` 硬编码。
|
||||
5. `bash -n scripts/devtest/start_dev_stack.sh`、`go test ./internal/config ./internal/app`、`go test ./cmd/supply-api ./internal/app ./internal/config` 均通过,且 `git diff --check` 无格式错误。
|
||||
|
||||
@@ -357,21 +357,21 @@
|
||||
- Create: `supply-api/config/config.prod.example.yaml`
|
||||
- Create: `docs/plans/2026-04-21-env-normalization-checklist.md`
|
||||
|
||||
- [ ] `P2-C-01` 盘点三服务支持的环境枚举和值别名。
|
||||
- [x] `P2-C-01` 盘点三服务支持的环境枚举和值别名。
|
||||
完成标准:清单覆盖 `dev`、`staging`、`prod`、`production`、`online`。
|
||||
- [ ] `P2-C-02` 定义统一枚举。
|
||||
- [x] `P2-C-02` 定义统一枚举。
|
||||
完成标准:计划文档只保留 `dev`、`staging`、`prod`。
|
||||
- [ ] `P2-C-03` 设计 `gateway` 对 `production/online -> prod` 的归一化入口。
|
||||
- [x] `P2-C-03` 设计 `gateway` 对 `production/online -> prod` 的归一化入口。
|
||||
完成标准:只保留一个真正规则。
|
||||
- [ ] `P2-C-04` 设计 `supply-api` 对 `-env=staging -config=config.dev.yaml` 的拒绝规则。
|
||||
- [x] `P2-C-04` 设计 `supply-api` 对 `-env=staging -config=config.dev.yaml` 的拒绝规则。
|
||||
完成标准:规则中包含错误信息草稿。
|
||||
- [ ] `P2-C-05` 复制 `config.dev.yaml` 所需段落,生成 staging 模板骨架。
|
||||
- [x] `P2-C-05` 复制 `config.dev.yaml` 所需段落,生成 staging 模板骨架。
|
||||
完成标准:`config.staging.example.yaml` 包含必要配置段。
|
||||
- [ ] `P2-C-06` 复制 prod 模板骨架。
|
||||
- [x] `P2-C-06` 复制 prod 模板骨架。
|
||||
完成标准:`config.prod.example.yaml` 包含关键安全配置占位。
|
||||
- [ ] `P2-C-07` 在 `scripts/devtest/start_dev_stack.sh` 设计改用 staging 模板的参数。
|
||||
- [x] `P2-C-07` 在 `scripts/devtest/start_dev_stack.sh` 设计改用 staging 模板的参数。
|
||||
完成标准:脚本不再硬编码 `config.dev.yaml`。
|
||||
- [ ] `P2-C-08` 写环境归一化检查清单。
|
||||
- [x] `P2-C-08` 写环境归一化检查清单。
|
||||
完成标准:包括启动前检查、启动后检查、CI 检查三类项。
|
||||
|
||||
### Task P2-D: 重构测试分类,补真实跨服务 smoke
|
||||
|
||||
@@ -273,12 +273,9 @@ func validateStartupSecurity(cfg config.Config) error {
|
||||
}
|
||||
|
||||
func isProductionEnv(env string) bool {
|
||||
switch strings.ToLower(strings.TrimSpace(env)) {
|
||||
case "production", "prod", "online":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
// 共享环境别名归一化只允许在 config.NormalizeEnv 一处定义,
|
||||
// 启动安全校验只消费归一化后的 prod 结果,避免多处规则漂移。
|
||||
return config.NormalizeEnv(env) == "prod"
|
||||
}
|
||||
|
||||
func isDefaultEncryptionKey() bool {
|
||||
|
||||
@@ -38,11 +38,11 @@ type ServerConfig struct {
|
||||
|
||||
// AuthConfig 鉴权运行时配置
|
||||
type AuthConfig struct {
|
||||
Env string
|
||||
TokenRuntimeMode string
|
||||
TokenRuntimeURL string
|
||||
TrustedProxies []string // 可信的代理IP列表,用于IP伪造防护
|
||||
CORSAllowOrigins []string // 允许的CORS来源,为空则使用默认通配符
|
||||
Env string
|
||||
TokenRuntimeMode string
|
||||
TokenRuntimeURL string
|
||||
TrustedProxies []string // 可信的代理IP列表,用于IP伪造防护
|
||||
CORSAllowOrigins []string // 允许的CORS来源,为空则使用默认通配符
|
||||
}
|
||||
|
||||
// DatabaseConfig 数据库配置
|
||||
@@ -166,7 +166,7 @@ func LoadConfig(path string) (*Config, error) {
|
||||
IdleTimeout: 120 * time.Second,
|
||||
},
|
||||
Auth: AuthConfig{
|
||||
Env: strings.ToLower(getEnv("GATEWAY_ENV", "dev")),
|
||||
Env: NormalizeEnv(getEnv("GATEWAY_ENV", "dev")),
|
||||
TokenRuntimeMode: strings.ToLower(getEnv("GATEWAY_TOKEN_RUNTIME_MODE", "inmemory")),
|
||||
TokenRuntimeURL: strings.TrimSpace(getEnv("GATEWAY_TOKEN_RUNTIME_URL", "")),
|
||||
},
|
||||
@@ -222,9 +222,24 @@ func LoadConfig(path string) (*Config, error) {
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
// NormalizeEnv 将兼容别名统一折叠到仓库内的唯一环境枚举。
|
||||
// Phase P2-C 之后,代码与文档内部只保留 dev/staging/prod。
|
||||
func NormalizeEnv(raw string) string {
|
||||
switch strings.ToLower(strings.TrimSpace(raw)) {
|
||||
case "", "dev":
|
||||
return "dev"
|
||||
case "staging":
|
||||
return "staging"
|
||||
case "production", "online", "prod":
|
||||
return "prod"
|
||||
default:
|
||||
return strings.ToLower(strings.TrimSpace(raw))
|
||||
}
|
||||
}
|
||||
|
||||
func ValidateAuthConfig(cfg AuthConfig) error {
|
||||
mode := strings.ToLower(strings.TrimSpace(cfg.TokenRuntimeMode))
|
||||
env := strings.ToLower(strings.TrimSpace(cfg.Env))
|
||||
env := NormalizeEnv(cfg.Env)
|
||||
|
||||
switch mode {
|
||||
case "inmemory", "remote_introspection":
|
||||
|
||||
@@ -444,6 +444,36 @@ func TestValidateAuthConfig_ProdRequiresRemoteIntrospection(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateAuthConfig_OnlineAliasRequiresRemoteIntrospection(t *testing.T) {
|
||||
cfg := AuthConfig{Env: "online", TokenRuntimeMode: "inmemory"}
|
||||
if err := ValidateAuthConfig(cfg); err == nil {
|
||||
t.Fatal("expected online alias to be normalized to prod and rejected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfig_NormalizesProductionAliases(t *testing.T) {
|
||||
t.Setenv("GATEWAY_TOKEN_RUNTIME_MODE", "remote_introspection")
|
||||
t.Setenv("GATEWAY_TOKEN_RUNTIME_URL", "http://127.0.0.1:18081")
|
||||
|
||||
t.Setenv("GATEWAY_ENV", "production")
|
||||
cfg, err := LoadConfig("")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error loading production alias: %v", err)
|
||||
}
|
||||
if cfg.Auth.Env != "prod" {
|
||||
t.Fatalf("expected production alias to normalize to prod, got %q", cfg.Auth.Env)
|
||||
}
|
||||
|
||||
t.Setenv("GATEWAY_ENV", "online")
|
||||
cfg, err = LoadConfig("")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error loading online alias: %v", err)
|
||||
}
|
||||
if cfg.Auth.Env != "prod" {
|
||||
t.Fatalf("expected online alias to normalize to prod, got %q", cfg.Auth.Env)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfig_DefaultProvider(t *testing.T) {
|
||||
t.Setenv("OPENAI_BASE_URL", "https://api.openai.com")
|
||||
t.Setenv("OPENAI_MODELS", "gpt-4o-mini,gpt-4o")
|
||||
|
||||
@@ -25,6 +25,7 @@ GATEWAY_PORT="${LIJIAOQIAO_DEVTEST_GATEWAY_PORT:-18080}"
|
||||
|
||||
SUPPLY_TOKEN_SECRET_KEY="${LIJIAOQIAO_DEVTEST_SUPPLY_TOKEN_SECRET_KEY:-devtest-secret-key-12345678901234567890}"
|
||||
SUPPLY_TOKEN_ISSUER="${LIJIAOQIAO_DEVTEST_SUPPLY_TOKEN_ISSUER:-lijiaoqiao/supply-api}"
|
||||
SUPPLY_CONFIG_PATH="${LIJIAOQIAO_DEVTEST_SUPPLY_CONFIG:-./config/config.staging.example.yaml}"
|
||||
|
||||
OPENAI_MODELS="${LIJIAOQIAO_DEVTEST_OPENAI_MODELS:-gpt-4o-mini,gpt-4o,gpt-4.1,o3-mini,claude-3-5-sonnet,claude-3-7-sonnet,gemini-2.0-flash,deepseek-chat}"
|
||||
|
||||
@@ -132,6 +133,7 @@ export LIJIAOQIAO_DEVTEST_GATEWAY_PORT="${GATEWAY_PORT}"
|
||||
export LIJIAOQIAO_DEVTEST_OPENAI_MODELS="${OPENAI_MODELS}"
|
||||
export LIJIAOQIAO_DEVTEST_SUPPLY_TOKEN_SECRET_KEY="${SUPPLY_TOKEN_SECRET_KEY}"
|
||||
export LIJIAOQIAO_DEVTEST_SUPPLY_TOKEN_ISSUER="${SUPPLY_TOKEN_ISSUER}"
|
||||
export LIJIAOQIAO_DEVTEST_SUPPLY_CONFIG="${SUPPLY_CONFIG_PATH}"
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -187,7 +189,7 @@ start_process "platform-token-runtime" \
|
||||
wait_http "platform-token-runtime" "http://${TOKEN_RUNTIME_ADDR}/actuator/health"
|
||||
|
||||
start_process "supply-api" \
|
||||
"cd \"${ROOT_DIR}/supply-api\" && SUPPLY_API_ADDR=\"${SUPPLY_API_ADDR}\" SUPPLY_DB_HOST=\"${PG_HOST}\" SUPPLY_DB_PORT=\"${PG_PORT}\" SUPPLY_DB_USER=\"${PG_USER}\" SUPPLY_DB_PASSWORD=\"${PG_PASSWORD}\" SUPPLY_DB_NAME=\"${SUPPLY_DB}\" SUPPLY_API_IAM_ENABLED=\"true\" SUPPLY_TOKEN_SECRET_KEY=\"${SUPPLY_TOKEN_SECRET_KEY}\" SUPPLY_TOKEN_ISSUER=\"${SUPPLY_TOKEN_ISSUER}\" GOCACHE=\"${STATE_DIR}/go-cache/supply-api\" go run ./cmd/supply-api -env=staging -config ./config/config.dev.yaml"
|
||||
"cd \"${ROOT_DIR}/supply-api\" && SUPPLY_API_ADDR=\"${SUPPLY_API_ADDR}\" SUPPLY_DB_HOST=\"${PG_HOST}\" SUPPLY_DB_PORT=\"${PG_PORT}\" SUPPLY_DB_USER=\"${PG_USER}\" SUPPLY_DB_PASSWORD=\"${PG_PASSWORD}\" SUPPLY_DB_NAME=\"${SUPPLY_DB}\" SUPPLY_API_IAM_ENABLED=\"true\" SUPPLY_TOKEN_SECRET_KEY=\"${SUPPLY_TOKEN_SECRET_KEY}\" SUPPLY_TOKEN_ISSUER=\"${SUPPLY_TOKEN_ISSUER}\" GOCACHE=\"${STATE_DIR}/go-cache/supply-api\" go run ./cmd/supply-api -env=staging -config \"${SUPPLY_CONFIG_PATH}\""
|
||||
wait_http "supply-api" "http://127.0.0.1${SUPPLY_API_ADDR#:}/actuator/health"
|
||||
|
||||
start_process "gateway" \
|
||||
|
||||
@@ -3,9 +3,12 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@@ -30,6 +33,9 @@ func main() {
|
||||
if *configPath == "" {
|
||||
*configPath = "./config/config." + *env + ".yaml"
|
||||
}
|
||||
if err := validateEnvConfigPath(*env, *configPath); err != nil {
|
||||
logging.NewLogger("supply-api", logging.LogLevelInfo).Fatalf("%v", err)
|
||||
}
|
||||
|
||||
// P1-010修复: 初始化结构化日志
|
||||
jsonLogger := logging.NewLogger("supply-api", logging.LogLevelInfo)
|
||||
@@ -105,3 +111,23 @@ func main() {
|
||||
|
||||
jsonLogger.Info("shutdown complete")
|
||||
}
|
||||
|
||||
func validateEnvConfigPath(envName, configPath string) error {
|
||||
if envName == "dev" {
|
||||
return nil
|
||||
}
|
||||
|
||||
base := strings.ToLower(strings.TrimSpace(filepath.Base(configPath)))
|
||||
switch base {
|
||||
case "config.dev.yaml", "config.dev.yml":
|
||||
return fmt.Errorf(
|
||||
"config path %q is a dev template and cannot be used with -env=%s; use config.%s.yaml or a %s example template instead",
|
||||
configPath,
|
||||
envName,
|
||||
envName,
|
||||
envName,
|
||||
)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,27 @@ func TestMain_RejectsUnsupportedEnvBeforeLoadingConfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMain_RejectsDevConfigPathForStaging(t *testing.T) {
|
||||
configPath := filepath.Join(t.TempDir(), "config.dev.yaml")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
cmd := exec.CommandContext(ctx, os.Args[0], "-test.run=TestMainHelperProcess", "--", "-env", "staging", "-config", configPath)
|
||||
cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
|
||||
output, err := cmd.CombinedOutput()
|
||||
|
||||
if ctx.Err() == context.DeadlineExceeded {
|
||||
t.Fatalf("expected staging + dev config mismatch to fail fast, but process timed out. output=%s", string(output))
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatalf("expected staging + dev config mismatch to fail, but process exited successfully. output=%s", string(output))
|
||||
}
|
||||
if !strings.Contains(string(output), "dev template") {
|
||||
t.Fatalf("expected output to mention dev template mismatch, got: %s", string(output))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMainHelperProcess(t *testing.T) {
|
||||
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
|
||||
return
|
||||
|
||||
56
supply-api/config/config.prod.example.yaml
Normal file
56
supply-api/config/config.prod.example.yaml
Normal file
@@ -0,0 +1,56 @@
|
||||
# Supply API Production Example Configuration
|
||||
# Production rules:
|
||||
# - keep server.default_supplier_id at 0
|
||||
# - do not use HS256/HS384/HS512
|
||||
# - provide token.public_key for RSA verification
|
||||
|
||||
server:
|
||||
addr: ":18082"
|
||||
read_timeout: 10s
|
||||
write_timeout: 15s
|
||||
idle_timeout: 30s
|
||||
shutdown_timeout: 5s
|
||||
default_supplier_id: 0
|
||||
|
||||
database:
|
||||
host: "prod-postgres.internal"
|
||||
port: 5432
|
||||
user: "supply_api"
|
||||
password: "${SUPPLY_DB_PASSWORD}"
|
||||
database: "supply_prod"
|
||||
max_open_conns: 50
|
||||
max_idle_conns: 10
|
||||
conn_max_lifetime: 1h
|
||||
conn_max_idle_time: 10m
|
||||
|
||||
redis:
|
||||
host: "prod-redis.internal"
|
||||
port: 6379
|
||||
password: "${SUPPLY_REDIS_PASSWORD}"
|
||||
db: 0
|
||||
pool_size: 20
|
||||
|
||||
token:
|
||||
algorithm: "RS256"
|
||||
public_key: |
|
||||
${SUPPLY_TOKEN_PUBLIC_KEY}
|
||||
issuer: "lijiaoqiao/supply-api"
|
||||
access_token_ttl: 1h
|
||||
refresh_token_ttl: 168h
|
||||
revocation_cache_ttl: 30s
|
||||
|
||||
settlement:
|
||||
withdraw_enabled: false
|
||||
|
||||
sms:
|
||||
enabled: false
|
||||
provider: ""
|
||||
app_id: ""
|
||||
app_secret: ""
|
||||
sign_name: ""
|
||||
template_code: ""
|
||||
|
||||
audit:
|
||||
buffer_size: 1000
|
||||
flush_interval: 5s
|
||||
export_timeout: 30s
|
||||
40
supply-api/config/config.staging.example.yaml
Normal file
40
supply-api/config/config.staging.example.yaml
Normal file
@@ -0,0 +1,40 @@
|
||||
# Supply API Staging Example Configuration
|
||||
# Use with:
|
||||
# go run ./cmd/supply-api -env=staging -config ./config/config.staging.example.yaml
|
||||
|
||||
server:
|
||||
addr: ":18082"
|
||||
read_timeout: 10s
|
||||
write_timeout: 15s
|
||||
idle_timeout: 30s
|
||||
shutdown_timeout: 5s
|
||||
|
||||
database:
|
||||
host: "staging-postgres.internal"
|
||||
port: 5432
|
||||
user: "supply_api"
|
||||
password: "${SUPPLY_DB_PASSWORD}"
|
||||
database: "supply_staging"
|
||||
max_open_conns: 25
|
||||
max_idle_conns: 5
|
||||
conn_max_lifetime: 1h
|
||||
conn_max_idle_time: 10m
|
||||
|
||||
redis:
|
||||
host: "staging-redis.internal"
|
||||
port: 6379
|
||||
password: "${SUPPLY_REDIS_PASSWORD}"
|
||||
db: 0
|
||||
pool_size: 10
|
||||
|
||||
token:
|
||||
secret_key: "${SUPPLY_TOKEN_SECRET_KEY}"
|
||||
issuer: "lijiaoqiao/supply-api-staging"
|
||||
access_token_ttl: 1h
|
||||
refresh_token_ttl: 168h
|
||||
revocation_cache_ttl: 30s
|
||||
|
||||
audit:
|
||||
buffer_size: 1000
|
||||
flush_interval: 5s
|
||||
export_timeout: 30s
|
||||
Reference in New Issue
Block a user