package config import ( "encoding/json" "errors" "os" ) // Config holds all backend runtime configuration. type Config struct { StoragePath string `json:"storage_path"` DBPath string `json:"db_path"` LDAP LDAPConfig `json:"ldap"` JWTSecret string `json:"jwt_secret"` ListenAddr string `json:"listen_addr"` } type LDAPConfig struct { Host string `json:"host"` Port int `json:"port"` BaseDN string `json:"base_dn"` BindDN string `json:"bind_dn"` BindPassword string `json:"bind_password"` } // ErrRequireSetup is returned when config is missing or empty, // signalling that the frontend should start the Setup Wizard. var ErrRequireSetup = errors.New("REQUIRE_SETUP") func Load(path string) (*Config, error) { data, err := os.ReadFile(path) if err != nil { if errors.Is(err, os.ErrNotExist) { return nil, ErrRequireSetup } return nil, err } var cfg Config if err := json.Unmarshal(data, &cfg); err != nil { return nil, err } if cfg.StoragePath == "" || cfg.JWTSecret == "" { return nil, ErrRequireSetup } if cfg.ListenAddr == "" { cfg.ListenAddr = ":4000" } return &cfg, nil } func Save(path string, cfg *Config) error { data, err := json.MarshalIndent(cfg, "", " ") if err != nil { return err } return os.WriteFile(path, data, 0600) }