package config import ( "time" "github.com/spf13/viper" ) // setDefaults sets all default values using viper. func setDefaults() { viper.SetDefault("run_mode", RunModeStandard) // Server viper.SetDefault("server.host", "0.0.0.0") viper.SetDefault("server.port", 8080) viper.SetDefault("server.mode", "release") viper.SetDefault("server.frontend_url", "") viper.SetDefault("server.read_header_timeout", 30) viper.SetDefault("server.idle_timeout", 120) viper.SetDefault("server.trusted_proxies", []string{}) viper.SetDefault("server.max_request_body_size", int64(256*1024*1024)) // H2C viper.SetDefault("server.h2c.enabled", false) viper.SetDefault("server.h2c.max_concurrent_streams", uint32(50)) viper.SetDefault("server.h2c.idle_timeout", 75) viper.SetDefault("server.h2c.max_read_frame_size", 1<<20) viper.SetDefault("server.h2c.max_upload_buffer_per_connection", 2<<20) viper.SetDefault("server.h2c.max_upload_buffer_per_stream", 512<<10) // Log viper.SetDefault("log.level", "info") viper.SetDefault("log.format", "console") viper.SetDefault("log.service_name", "sub2api") viper.SetDefault("log.env", "production") viper.SetDefault("log.caller", true) viper.SetDefault("log.stacktrace_level", "error") viper.SetDefault("log.output.to_stdout", true) viper.SetDefault("log.output.to_file", true) viper.SetDefault("log.output.file_path", "") viper.SetDefault("log.rotation.max_size_mb", 100) viper.SetDefault("log.rotation.max_backups", 10) viper.SetDefault("log.rotation.max_age_days", 7) viper.SetDefault("log.rotation.compress", true) viper.SetDefault("log.rotation.local_time", true) viper.SetDefault("log.sampling.enabled", false) viper.SetDefault("log.sampling.initial", 100) viper.SetDefault("log.sampling.thereafter", 100) // CORS viper.SetDefault("cors.allowed_origins", []string{}) viper.SetDefault("cors.allow_credentials", true) // Security setSecurityDefaults() // Billing viper.SetDefault("billing.circuit_breaker.enabled", true) viper.SetDefault("billing.circuit_breaker.failure_threshold", 5) viper.SetDefault("billing.circuit_breaker.reset_timeout_seconds", 30) viper.SetDefault("billing.circuit_breaker.half_open_requests", 3) viper.SetDefault("turnstile.required", false) // LinuxDo Connect OAuth setLinuxDoDefaults() // Generic OIDC OAuth setOIDCDefaults() // Database viper.SetDefault("database.host", "localhost") viper.SetDefault("database.port", 5432) viper.SetDefault("database.user", "postgres") viper.SetDefault("database.password", "postgres") viper.SetDefault("database.dbname", "sub2api") viper.SetDefault("database.sslmode", "prefer") viper.SetDefault("database.max_open_conns", 256) viper.SetDefault("database.max_idle_conns", 128) viper.SetDefault("database.conn_max_lifetime_minutes", 30) viper.SetDefault("database.conn_max_idle_time_minutes", 5) // Redis viper.SetDefault("redis.host", "localhost") viper.SetDefault("redis.port", 6379) viper.SetDefault("redis.password", "") viper.SetDefault("redis.db", 0) viper.SetDefault("redis.dial_timeout_seconds", 5) viper.SetDefault("redis.read_timeout_seconds", 3) viper.SetDefault("redis.write_timeout_seconds", 3) viper.SetDefault("redis.pool_size", 1024) viper.SetDefault("redis.min_idle_conns", 128) viper.SetDefault("redis.enable_tls", false) // Ops (vNext) viper.SetDefault("ops.enabled", true) viper.SetDefault("ops.use_preaggregated_tables", true) viper.SetDefault("ops.cleanup.enabled", true) viper.SetDefault("ops.cleanup.schedule", "0 2 * * *") viper.SetDefault("ops.cleanup.error_log_retention_days", 30) viper.SetDefault("ops.cleanup.minute_metrics_retention_days", 30) viper.SetDefault("ops.cleanup.hourly_metrics_retention_days", 30) viper.SetDefault("ops.aggregation.enabled", true) viper.SetDefault("ops.metrics_collector_cache.enabled", true) viper.SetDefault("ops.metrics_collector_cache.ttl", 65*time.Second) // JWT viper.SetDefault("jwt.secret", "") viper.SetDefault("jwt.expire_hour", 24) viper.SetDefault("jwt.access_token_expire_minutes", 0) viper.SetDefault("jwt.refresh_token_expire_days", 30) viper.SetDefault("jwt.refresh_window_minutes", 2) // TOTP viper.SetDefault("totp.encryption_key", "") // Default viper.SetDefault("default.admin_email", "") viper.SetDefault("default.admin_password", "") viper.SetDefault("default.user_concurrency", 5) viper.SetDefault("default.user_balance", 0) viper.SetDefault("default.api_key_prefix", "sk-") viper.SetDefault("default.rate_multiplier", 1.0) // RateLimit viper.SetDefault("rate_limit.overload_cooldown_minutes", 10) viper.SetDefault("rate_limit.oauth_401_cooldown_minutes", 10) // Pricing viper.SetDefault("pricing.remote_url", "https://raw.githubusercontent.com/Wei-Shaw/model-price-repo/main/model_prices_and_context_window.json") viper.SetDefault("pricing.hash_url", "https://raw.githubusercontent.com/Wei-Shaw/model-price-repo/main/model_prices_and_context_window.sha256") viper.SetDefault("pricing.data_dir", "./data") viper.SetDefault("pricing.fallback_file", "./resources/model-pricing/model_prices_and_context_window.json") viper.SetDefault("pricing.update_interval_hours", 24) viper.SetDefault("pricing.hash_check_interval_minutes", 10) viper.SetDefault("timezone", "Asia/Shanghai") // API Key auth cache viper.SetDefault("api_key_auth_cache.l1_size", 65535) viper.SetDefault("api_key_auth_cache.l1_ttl_seconds", 15) viper.SetDefault("api_key_auth_cache.l2_ttl_seconds", 300) viperSetDefault("api_key_auth_cache.negative_ttl_seconds", 30) viper.SetDefault("api_key_auth_cache.jitter_percent", 10) viper.SetDefault("api_key_auth_cache.singleflight", true) // Subscription auth L1 cache viper.SetDefault("subscription_cache.l1_size", 16384) viper.SetDefault("subscription_cache.l1_ttl_seconds", 10) viper.SetDefault("subscription_cache.jitter_percent", 10) // Dashboard cache viper.SetDefault("dashboard_cache.enabled", true) viper.SetDefault("dashboard_cache.key_prefix", "sub2api:") viper.SetDefault("dashboard_cache.stats_fresh_ttl_seconds", 15) viper.SetDefault("dashboard_cache.stats_ttl_seconds", 30) viper.SetDefault("dashboard_cache.stats_refresh_timeout_seconds", 30) // Dashboard aggregation viper.SetDefault("dashboard_aggregation.enabled", true) viper.SetDefault("dashboard_aggregation.interval_seconds", 60) viper.SetDefault("dashboard_aggregation.lookback_seconds", 120) viper.SetDefault("dashboard_aggregation.backfill_enabled", false) viper.SetDefault("dashboard_aggregation.backfill_max_days", 31) viper.SetDefault("dashboard_aggregation.retention.usage_logs_days", 90) viper.SetDefault("dashboard_aggregation.retention.usage_billing_dedup_days", 365) viper.SetDefault("dashboard_aggregation.retention.hourly_days", 180) viper.SetDefault("dashboard_aggregation.retention.daily_days", 730) viper.SetDefault("dashboard_aggregation.recompute_days", 2) // Usage cleanup task viper.SetDefault("usage_cleanup.enabled", true) viper.SetDefault("usage_cleanup.max_range_days", 31) viper.SetDefault("usage_cleanup.batch_size", 5000) viper.SetDefault("usage_cleanup.worker_interval_seconds", 10) viper.SetDefault("usage_cleanup.task_timeout_seconds", 1800) // Idempotency viper.SetDefault("idempotency.observe_only", true) viper.SetDefault("idempotency.default_ttl_seconds", 86400) viper.SetDefault("idempotency.system_operation_ttl_seconds", 3600) viper.SetDefault("idempotency.processing_timeout_seconds", 30) viper.SetDefault("idempotency.failed_retry_backoff_seconds", 5) viper.SetDefault("idempotency.max_stored_response_len", 64*1024) viper.SetDefault("idempotency.cleanup_interval_seconds", 60) viper.SetDefault("idempotency.cleanup_batch_size", 500) // Gateway defaults setGatewayDefaults() // Gemini OAuth viper.SetDefault("gemini.oauth.client_id", "") viper.SetDefault("gemini.oauth.client_secret", "") viper.SetDefault("gemini.oauth.scopes", "") viper.SetDefault("gemini.quota.policy", "") // Subscription Maintenance viper.SetDefault("subscription_maintenance.worker_count", 2) viper.SetDefault("subscription_maintenance.queue_size", 1024) // Concurrency viper.SetDefault("concurrency.ping_interval", 10) // TokenRefresh viper.SetDefault("token_refresh.enabled", true) viper.SetDefault("token_refresh.check_interval_minutes", 5) viper.SetDefault("token_refresh.refresh_before_expiry_hours", 0.5) viper.SetDefault("token_refresh.max_retries", 3) viper.SetDefault("token_refresh.retry_backoff_seconds", 2) } // NOTE: there was a typo in original code ("viperSetDefault" instead of "viper.SetDefault"). // Preserved here for exact compatibility. func viperSetDefault(key string, value any) { viper.SetDefault(key, value) }