package config import ( "time" sharedpostgres "knowfoolery/backend/shared/infra/database/postgres" sharedredis "knowfoolery/backend/shared/infra/database/redis" "knowfoolery/backend/shared/infra/observability/logging" "knowfoolery/backend/shared/infra/observability/metrics" "knowfoolery/backend/shared/infra/observability/tracing" "knowfoolery/backend/shared/infra/utils/envutil" ) // Config holds runtime configuration for game-session-service. type Config struct { AppName string Port int Env string LogLevel string SessionDuration time.Duration MaxAttempts int MinAnswerLatencyMs int LockTTL time.Duration ActiveKeyTTL time.Duration EndReasonDefault string QuestionBankBaseURL string UserServiceBaseURL string UpstreamTimeout time.Duration Postgres sharedpostgres.Config Redis sharedredis.Config Tracing tracing.Config Metrics metrics.Config Logging logging.Config ZitadelBaseURL string ZitadelIssuer string ZitadelAudience string ZitadelClientID string ZitadelSecret string } // FromEnv builds service configuration from environment variables. func FromEnv() Config { env := envutil.String("ENVIRONMENT", "development") appName := "Know Foolery - Game Session Service" serviceName := "game-session-service" logCfg := logging.DefaultConfig() logCfg.ServiceName = serviceName logCfg.Environment = env logCfg.Level = envutil.String("LOG_LEVEL", logCfg.Level) traceCfg := tracing.ConfigFromEnv() if traceCfg.ServiceName == "knowfoolery" { traceCfg.ServiceName = serviceName } traceCfg.Environment = env metricsCfg := metrics.ConfigFromEnv() if metricsCfg.ServiceName == "knowfoolery" { metricsCfg.ServiceName = serviceName } return Config{ AppName: appName, Port: envutil.Int("GAME_SESSION_PORT", 8080), Env: env, LogLevel: logCfg.Level, SessionDuration: envutil.Duration("GAME_SESSION_DURATION", 30*time.Minute), MaxAttempts: envutil.Int("GAME_SESSION_MAX_ATTEMPTS", 3), MinAnswerLatencyMs: envutil.Int("GAME_SESSION_MIN_ANSWER_LATENCY_MS", 300), LockTTL: envutil.Duration("GAME_SESSION_LOCK_TTL", 3*time.Second), ActiveKeyTTL: envutil.Duration("GAME_SESSION_ACTIVE_KEY_TTL", 35*time.Minute), EndReasonDefault: envutil.String("GAME_SESSION_END_REASON_DEFAULT", "abandoned"), QuestionBankBaseURL: envutil.String("QUESTION_BANK_BASE_URL", "http://localhost:8081"), UserServiceBaseURL: envutil.String("USER_SERVICE_BASE_URL", "http://localhost:8082"), UpstreamTimeout: envutil.Duration("UPSTREAM_HTTP_TIMEOUT", 3*time.Second), Postgres: sharedpostgres.ConfigFromEnv(), Redis: sharedredis.ConfigFromEnv(), Tracing: traceCfg, Metrics: metricsCfg, Logging: logCfg, ZitadelBaseURL: envutil.String("ZITADEL_URL", ""), ZitadelIssuer: envutil.String("ZITADEL_ISSUER", ""), ZitadelAudience: envutil.String("ZITADEL_AUDIENCE", ""), ZitadelClientID: envutil.String("ZITADEL_CLIENT_ID", ""), ZitadelSecret: envutil.String("ZITADEL_CLIENT_SECRET", ""), } }