@@ -2,6 +2,8 @@ package handlers
22
33import (
44 "net/http"
5+ "strings"
6+ "time"
57 "stellarbill-backend/internal/audit"
68 "stellarbill-backend/internal/featureflags"
79
@@ -50,15 +52,38 @@ func (h *FeatureFlagsHandler) ToggleFeatureFlag(c *gin.Context) {
5052
5153 // Toggle and update flag
5254 afterEnabled := ! beforeEnabled
53- h .flagManager .SetFlag (req .Name , afterEnabled , flag .Description )
55+ newVersion := time .Now ().UnixNano ()
56+
57+ success := h .flagManager .SetFlagWithVersion (req .Name , afterEnabled , flag .Description , newVersion )
58+ if ! success {
59+ RespondWithError (c , http .StatusConflict , ErrorCodeConflict , "concurrent modification: flag was updated by another request" )
60+ return
61+ }
5462
5563 // Get updated flag
5664 updatedFlag , _ := h .flagManager .GetFlag (req .Name )
5765
66+ isSensitive := false
67+ lowerName := strings .ToLower (req .Name )
68+ sensitiveKeys := []string {"secret" , "token" , "password" , "key" , "auth" , "cvv" , "card" }
69+ for _ , sk := range sensitiveKeys {
70+ if strings .Contains (lowerName , sk ) {
71+ isSensitive = true
72+ break
73+ }
74+ }
75+
76+ beforeStr := boolToString (beforeEnabled )
77+ afterStr := boolToString (afterEnabled )
78+ if isSensitive {
79+ beforeStr = "[REDACTED]"
80+ afterStr = "[REDACTED]"
81+ }
82+
5883 // Log audit action (failure doesn't block success)
5984 audit .LogAction (c , "feature_flag_toggle" , req .Name , "success" , map [string ]string {
60- "before_enabled" : boolToString ( beforeEnabled ) ,
61- "after_enabled" : boolToString ( afterEnabled ) ,
85+ "before_enabled" : beforeStr ,
86+ "after_enabled" : afterStr ,
6287 "reason" : req .Reason ,
6388 })
6489
0 commit comments