@@ -253,7 +253,7 @@ func (sm *SystemSettingsManager) ValidateSettings(settingsMap map[string]any) er
253253 jsonToField := make (map [string ]reflect.StructField )
254254 for i := range t .NumField () {
255255 field := t .Field (i )
256- jsonTag := field .Tag .Get ("json" )
256+ jsonTag := strings . Split ( field .Tag .Get ("json" ), "," )[ 0 ]
257257 if jsonTag != "" {
258258 jsonToField [jsonTag ] = field
259259 }
@@ -266,6 +266,7 @@ func (sm *SystemSettingsManager) ValidateSettings(settingsMap map[string]any) er
266266 }
267267
268268 validateTag := field .Tag .Get ("validate" )
269+ rules := strings .Split (validateTag , "," )
269270
270271 switch field .Type .Kind () {
271272 case reflect .Int :
@@ -278,21 +279,34 @@ func (sm *SystemSettingsManager) ValidateSettings(settingsMap map[string]any) er
278279 return fmt .Errorf ("invalid value for %s: must be an integer" , key )
279280 }
280281
281- if strings .HasPrefix (validateTag , "min=" ) {
282- minValStr := strings .TrimPrefix (validateTag , "min=" )
283- minVal , _ := strconv .Atoi (minValStr )
284- if intVal < minVal {
285- return fmt .Errorf ("value for %s (%d) is below minimum value (%d)" , key , intVal , minVal )
282+ // The 'required' check is implicitly handled by the type assertion above.
283+ for _ , rule := range rules {
284+ trimmedRule := strings .TrimSpace (rule )
285+ if strings .HasPrefix (trimmedRule , "min=" ) {
286+ minValStr := strings .TrimPrefix (trimmedRule , "min=" )
287+ minVal , _ := strconv .Atoi (minValStr )
288+ if intVal < minVal {
289+ return fmt .Errorf ("value for %s (%d) is below minimum value (%d)" , key , intVal , minVal )
290+ }
286291 }
287292 }
288293 case reflect .Bool :
289294 if _ , ok := value .(bool ); ! ok {
290295 return fmt .Errorf ("invalid type for %s: expected a boolean, got %T" , key , value )
291296 }
292297 case reflect .String :
293- if _ , ok := value .(string ); ! ok {
298+ strVal , ok := value .(string )
299+ if ! ok {
294300 return fmt .Errorf ("invalid type for %s: expected a string, got %T" , key , value )
295301 }
302+ for _ , rule := range rules {
303+ trimmedRule := strings .TrimSpace (rule )
304+ if trimmedRule == "required" {
305+ if strVal == "" {
306+ return fmt .Errorf ("value for %s is required" , key )
307+ }
308+ }
309+ }
296310 default :
297311 return fmt .Errorf ("unsupported type for setting key validation: %s" , key )
298312 }
@@ -309,7 +323,7 @@ func (sm *SystemSettingsManager) ValidateGroupConfigOverrides(configMap map[stri
309323 jsonToField := make (map [string ]reflect.StructField )
310324 for i := range t .NumField () {
311325 field := t .Field (i )
312- jsonTag := field .Tag .Get ("json" )
326+ jsonTag := strings . Split ( field .Tag .Get ("json" ), "," )[ 0 ]
313327 if jsonTag != "" {
314328 jsonToField [jsonTag ] = field
315329 }
@@ -326,22 +340,45 @@ func (sm *SystemSettingsManager) ValidateGroupConfigOverrides(configMap map[stri
326340 }
327341
328342 validateTag := field .Tag .Get ("validate" )
343+ rules := strings .Split (validateTag , "," )
329344
330- floatVal , isFloat := value .(float64 )
331- if ! isFloat {
332- continue
333- }
334- intVal := int (floatVal )
335- if floatVal != float64 (intVal ) {
336- return fmt .Errorf ("invalid value for %s: must be an integer" , key )
337- }
345+ switch field .Type .Kind () {
346+ case reflect .Int :
347+ floatVal , ok := value .(float64 )
348+ if ! ok {
349+ continue
350+ }
351+ intVal := int (floatVal )
352+ if floatVal != float64 (intVal ) {
353+ return fmt .Errorf ("invalid value for %s: must be an integer" , key )
354+ }
338355
339- if strings .HasPrefix (validateTag , "min=" ) {
340- minValStr := strings .TrimPrefix (validateTag , "min=" )
341- minVal , _ := strconv .Atoi (minValStr )
342- if intVal < minVal {
343- return fmt .Errorf ("value for %s (%d) is below minimum value (%d)" , key , intVal , minVal )
356+ // The 'required' check is implicitly handled by the type assertion above.
357+ for _ , rule := range rules {
358+ trimmedRule := strings .TrimSpace (rule )
359+ if strings .HasPrefix (trimmedRule , "min=" ) {
360+ minValStr := strings .TrimPrefix (trimmedRule , "min=" )
361+ minVal , _ := strconv .Atoi (minValStr )
362+ if intVal < minVal {
363+ return fmt .Errorf ("value for %s (%d) is below minimum value (%d)" , key , intVal , minVal )
364+ }
365+ }
344366 }
367+ case reflect .String :
368+ strVal , ok := value .(string )
369+ if ! ok {
370+ continue
371+ }
372+ for _ , rule := range rules {
373+ trimmedRule := strings .TrimSpace (rule )
374+ if trimmedRule == "required" {
375+ if strVal == "" {
376+ return fmt .Errorf ("value for %s is required" , key )
377+ }
378+ }
379+ }
380+ default :
381+ // Do not validate other types for group overrides
345382 }
346383 }
347384
0 commit comments