package implpreference import ( "context" "database/sql" "encoding/json" "github.com/SigNoz/signoz/pkg/errors" "github.com/SigNoz/signoz/pkg/modules/preference" "github.com/SigNoz/signoz/pkg/types/preferencetypes" "github.com/SigNoz/signoz/pkg/valuer" ) // Do not take inspiration from this code, it is a work in progress. See Organization module for a better implementation. type module struct { store preferencetypes.Store defaultMap map[string]preferencetypes.Preference } func NewModule(store preferencetypes.Store, defaultMap map[string]preferencetypes.Preference) preference.Module { return &module{store: store, defaultMap: defaultMap} } func (module *module) GetOrg(ctx context.Context, preferenceID string, orgID string) (*preferencetypes.GettablePreference, error) { preference, seen := module.defaultMap[preferenceID] if !seen { return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot find preference with id: %s", preferenceID) } isEnabled := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope) if !isEnabled { return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "preference is not enabled at org scope: %s", preferenceID) } org, err := module.store.GetOrg(ctx, orgID, preferenceID) if err != nil { if err == sql.ErrNoRows { return &preferencetypes.GettablePreference{ PreferenceID: preferenceID, PreferenceValue: preference.DefaultValue, }, nil } return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in fetching the org preference: %s", preferenceID) } return &preferencetypes.GettablePreference{ PreferenceID: preferenceID, PreferenceValue: preference.SanitizeValue(org.PreferenceValue), }, nil } func (module *module) UpdateOrg(ctx context.Context, preferenceID string, preferenceValue interface{}, orgID string) error { preference, seen := module.defaultMap[preferenceID] if !seen { return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot find preference with id: %s", preferenceID) } isEnabled := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope) if !isEnabled { return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "preference is not enabled at org scope: %s", preferenceID) } err := preference.IsValidValue(preferenceValue) if err != nil { return err } storableValue, encodeErr := json.Marshal(preferenceValue) if encodeErr != nil { return errors.Wrapf(encodeErr, errors.TypeInvalidInput, errors.CodeInvalidInput, "error in encoding the preference value") } org, dberr := module.store.GetOrg(ctx, orgID, preferenceID) if dberr != nil && dberr != sql.ErrNoRows { return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in getting the preference value") } if dberr != nil { org.ID = valuer.GenerateUUID() org.PreferenceID = preferenceID org.PreferenceValue = string(storableValue) org.OrgID = orgID } else { org.PreferenceValue = string(storableValue) } dberr = module.store.UpsertOrg(ctx, org) if dberr != nil { return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in setting the preference value") } return nil } func (module *module) GetAllOrg(ctx context.Context, orgID string) ([]*preferencetypes.PreferenceWithValue, error) { allOrgs := []*preferencetypes.PreferenceWithValue{} orgs, err := module.store.GetAllOrg(ctx, orgID) if err != nil { return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in setting all org preference values") } preferenceValueMap := map[string]interface{}{} for _, preferenceValue := range orgs { preferenceValueMap[preferenceValue.PreferenceID] = preferenceValue.PreferenceValue } for _, preference := range module.defaultMap { isEnabledForOrgScope := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope) if isEnabledForOrgScope { preferenceWithValue := &preferencetypes.PreferenceWithValue{} preferenceWithValue.Key = preference.Key preferenceWithValue.Name = preference.Name preferenceWithValue.Description = preference.Description preferenceWithValue.AllowedScopes = preference.AllowedScopes preferenceWithValue.AllowedValues = preference.AllowedValues preferenceWithValue.DefaultValue = preference.DefaultValue preferenceWithValue.Range = preference.Range preferenceWithValue.ValueType = preference.ValueType preferenceWithValue.IsDiscreteValues = preference.IsDiscreteValues value, seen := preferenceValueMap[preference.Key] if seen { preferenceWithValue.Value = value } else { preferenceWithValue.Value = preference.DefaultValue } preferenceWithValue.Value = preference.SanitizeValue(preferenceWithValue.Value) allOrgs = append(allOrgs, preferenceWithValue) } } return allOrgs, nil } func (module *module) GetUser(ctx context.Context, preferenceID string, orgID string, userID string) (*preferencetypes.GettablePreference, error) { preference, seen := module.defaultMap[preferenceID] if !seen { return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot find preference with id: %s", preferenceID) } preferenceValue := preferencetypes.GettablePreference{ PreferenceID: preferenceID, PreferenceValue: preference.DefaultValue, } isEnabledAtUserScope := preference.IsEnabledForScope(preferencetypes.UserAllowedScope) if !isEnabledAtUserScope { return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "preference is not enabled at user scope: %s", preferenceID) } isEnabledAtOrgScope := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope) if isEnabledAtOrgScope { org, err := module.store.GetOrg(ctx, orgID, preferenceID) if err != nil && err != sql.ErrNoRows { return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in fetching the org preference: %s", preferenceID) } if err == nil { preferenceValue.PreferenceValue = org.PreferenceValue } } user, err := module.store.GetUser(ctx, userID, preferenceID) if err != nil && err != sql.ErrNoRows { return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in fetching the user preference: %s", preferenceID) } if err == nil { preferenceValue.PreferenceValue = user.PreferenceValue } return &preferencetypes.GettablePreference{ PreferenceID: preferenceValue.PreferenceID, PreferenceValue: preference.SanitizeValue(preferenceValue.PreferenceValue), }, nil } func (module *module) UpdateUser(ctx context.Context, preferenceID string, preferenceValue interface{}, userID string) error { preference, seen := module.defaultMap[preferenceID] if !seen { return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot find preference with id: %s", preferenceID) } isEnabledAtUserScope := preference.IsEnabledForScope(preferencetypes.UserAllowedScope) if !isEnabledAtUserScope { return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "preference is not enabled at user scope: %s", preferenceID) } err := preference.IsValidValue(preferenceValue) if err != nil { return err } storableValue, encodeErr := json.Marshal(preferenceValue) if encodeErr != nil { return errors.Wrapf(encodeErr, errors.TypeInvalidInput, errors.CodeInvalidInput, "error in encoding the preference value") } user, dberr := module.store.GetUser(ctx, userID, preferenceID) if dberr != nil && dberr != sql.ErrNoRows { return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in getting the preference value") } if dberr != nil { user.ID = valuer.GenerateUUID() user.PreferenceID = preferenceID user.PreferenceValue = string(storableValue) user.UserID = userID } else { user.PreferenceValue = string(storableValue) } dberr = module.store.UpsertUser(ctx, user) if dberr != nil { return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in setting the preference value") } return nil } func (module *module) GetAllUser(ctx context.Context, orgID string, userID string) ([]*preferencetypes.PreferenceWithValue, error) { allUsers := []*preferencetypes.PreferenceWithValue{} orgs, err := module.store.GetAllOrg(ctx, orgID) if err != nil { return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in setting all org preference values") } preferenceOrgValueMap := map[string]interface{}{} for _, preferenceValue := range orgs { preferenceOrgValueMap[preferenceValue.PreferenceID] = preferenceValue.PreferenceValue } users, err := module.store.GetAllUser(ctx, userID) if err != nil { return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in setting all user preference values") } preferenceUserValueMap := map[string]interface{}{} for _, preferenceValue := range users { preferenceUserValueMap[preferenceValue.PreferenceID] = preferenceValue.PreferenceValue } for _, preference := range module.defaultMap { isEnabledForUserScope := preference.IsEnabledForScope(preferencetypes.UserAllowedScope) if isEnabledForUserScope { preferenceWithValue := &preferencetypes.PreferenceWithValue{} preferenceWithValue.Key = preference.Key preferenceWithValue.Name = preference.Name preferenceWithValue.Description = preference.Description preferenceWithValue.AllowedScopes = preference.AllowedScopes preferenceWithValue.AllowedValues = preference.AllowedValues preferenceWithValue.DefaultValue = preference.DefaultValue preferenceWithValue.Range = preference.Range preferenceWithValue.ValueType = preference.ValueType preferenceWithValue.IsDiscreteValues = preference.IsDiscreteValues preferenceWithValue.Value = preference.DefaultValue isEnabledForOrgScope := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope) if isEnabledForOrgScope { value, seen := preferenceOrgValueMap[preference.Key] if seen { preferenceWithValue.Value = value } } value, seen := preferenceUserValueMap[preference.Key] if seen { preferenceWithValue.Value = value } preferenceWithValue.Value = preference.SanitizeValue(preferenceWithValue.Value) allUsers = append(allUsers, preferenceWithValue) } } return allUsers, nil }