feat: sdk migration in progress

This commit is contained in:
allanice001
2025-11-02 13:19:30 +00:00
commit 0d10d42442
492 changed files with 71067 additions and 0 deletions

194
internal/config/config.go Normal file
View File

@@ -0,0 +1,194 @@
package config
import (
"errors"
"fmt"
"strings"
"sync"
"github.com/joho/godotenv"
"github.com/spf13/viper"
"gopkg.in/yaml.v3"
)
type Config struct {
DbURL string
Port string
Host string
JWTIssuer string
JWTAudience string
JWTPrivateEncKey string
OAuthRedirectBase string
GoogleClientID string
GoogleClientSecret string
GithubClientID string
GithubClientSecret string
UIDev bool
Env string
Debug bool
Swagger bool
}
var (
once sync.Once
cached Config
loadErr error
)
func Load() (Config, error) {
once.Do(func() {
_ = godotenv.Load()
// Use a private viper to avoid global mutation/races
v := viper.New()
// Defaults
v.SetDefault("bind.address", "127.0.0.1")
v.SetDefault("bind.port", "8080")
v.SetDefault("database.url", "postgres://user:pass@localhost:5432/db?sslmode=disable")
v.SetDefault("ui.dev", false)
v.SetDefault("env", "development")
v.SetDefault("debug", false)
v.SetDefault("swagger", false)
// Env setup and binding
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
v.AutomaticEnv()
keys := []string{
"bind.address",
"bind.port",
"database.url",
"jwt.issuer",
"jwt.audience",
"jwt.private.enc.key",
"oauth.redirect.base",
"google.client.id",
"google.client.secret",
"github.client.id",
"github.client.secret",
"ui.dev",
"env",
"debug",
"swagger",
}
for _, k := range keys {
_ = v.BindEnv(k)
}
// Build config
cfg := Config{
DbURL: v.GetString("database.url"),
Port: v.GetString("bind.port"),
Host: v.GetString("bind.address"),
JWTIssuer: v.GetString("jwt.issuer"),
JWTAudience: v.GetString("jwt.audience"),
JWTPrivateEncKey: v.GetString("jwt.private.enc.key"),
OAuthRedirectBase: v.GetString("oauth.redirect.base"),
GoogleClientID: v.GetString("google.client.id"),
GoogleClientSecret: v.GetString("google.client.secret"),
GithubClientID: v.GetString("github.client.id"),
GithubClientSecret: v.GetString("github.client.secret"),
UIDev: v.GetBool("ui.dev"),
Env: v.GetString("env"),
Debug: v.GetBool("debug"),
Swagger: v.GetBool("swagger"),
}
// Validate
if err := validateConfig(cfg); err != nil {
loadErr = err
return
}
cached = cfg
})
return cached, loadErr
}
func validateConfig(cfg Config) error {
var errs []string
// Required general settings
req := map[string]string{
"jwt.issuer": cfg.JWTIssuer,
"jwt.audience": cfg.JWTAudience,
"jwt.private.enc.key": cfg.JWTPrivateEncKey,
"oauth.redirect.base": cfg.OAuthRedirectBase,
}
for k, v := range req {
if strings.TrimSpace(v) == "" {
errs = append(errs, fmt.Sprintf("missing required config key %q (env %s)", k, envNameFromKey(k)))
}
}
// OAuth provider requirements:
googleOK := strings.TrimSpace(cfg.GoogleClientID) != "" && strings.TrimSpace(cfg.GoogleClientSecret) != ""
githubOK := strings.TrimSpace(cfg.GithubClientID) != "" && strings.TrimSpace(cfg.GithubClientSecret) != ""
// If partially configured, report what's missing for each
if !googleOK && (cfg.GoogleClientID != "" || cfg.GoogleClientSecret != "") {
if cfg.GoogleClientID == "" {
errs = append(errs, fmt.Sprintf("google.client.id is missing (env %s) while google.client.secret is set", envNameFromKey("google.client.id")))
}
if cfg.GoogleClientSecret == "" {
errs = append(errs, fmt.Sprintf("google.client.secret is missing (env %s) while google.client.id is set", envNameFromKey("google.client.secret")))
}
}
if !githubOK && (cfg.GithubClientID != "" || cfg.GithubClientSecret != "") {
if cfg.GithubClientID == "" {
errs = append(errs, fmt.Sprintf("github.client.id is missing (env %s) while github.client.secret is set", envNameFromKey("github.client.id")))
}
if cfg.GithubClientSecret == "" {
errs = append(errs, fmt.Sprintf("github.client.secret is missing (env %s) while github.client.id is set", envNameFromKey("github.client.secret")))
}
}
// Enforce minimum: at least one full provider
if !googleOK && !githubOK {
errs = append(errs, "at least one OAuth provider must be fully configured: either Google (google.client.id + google.client.secret) or GitHub (github.client.id + github.client.secret)")
}
if len(errs) > 0 {
return errors.New(strings.Join(errs, "; "))
}
return nil
}
func envNameFromKey(key string) string {
return strings.ToUpper(strings.ReplaceAll(key, ".", "_"))
}
func DebugPrintConfig() {
cfg, _ := Load()
b, err := yaml.Marshal(cfg)
if err != nil {
fmt.Println("error marshalling config:", err)
return
}
fmt.Println("Loaded configuration:")
fmt.Println(string(b))
}
func IsUIDev() bool {
cfg, _ := Load()
return cfg.UIDev
}
func IsDev() bool {
cfg, _ := Load()
return strings.EqualFold(cfg.Env, "development")
}
func IsDebug() bool {
cfg, _ := Load()
return cfg.Debug
}
func IsSwaggerEnabled() bool {
cfg, _ := Load()
return cfg.Swagger
}