mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-15 22:45:57 +08:00
refactor(preference): better readability
This commit is contained in:
parent
6ed30318bd
commit
a7d0ae21ac
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/SigNoz/signoz/pkg/modules/preference"
|
"github.com/SigNoz/signoz/pkg/modules/preference"
|
||||||
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
||||||
"github.com/SigNoz/signoz/pkg/types/preferencetypes"
|
"github.com/SigNoz/signoz/pkg/types/preferencetypes"
|
||||||
|
"github.com/SigNoz/signoz/pkg/valuer"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ func NewHandler(module preference.Module) preference.Handler {
|
|||||||
return &handler{module: module}
|
return &handler{module: module}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *handler) GetOrg(rw http.ResponseWriter, r *http.Request) {
|
func (handler *handler) ListByOrg(rw http.ResponseWriter, r *http.Request) {
|
||||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@ -32,65 +33,7 @@ func (handler *handler) GetOrg(rw http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
id, ok := mux.Vars(r)["preferenceId"]
|
preferences, err := handler.module.ListByOrg(ctx, valuer.MustNewUUID(claims.OrgID))
|
||||||
if !ok {
|
|
||||||
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is required"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
preference, err := handler.module.GetOrg(ctx, id, claims.OrgID)
|
|
||||||
if err != nil {
|
|
||||||
render.Error(rw, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
render.Success(rw, http.StatusOK, preference)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (handler *handler) UpdateOrg(rw http.ResponseWriter, r *http.Request) {
|
|
||||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
claims, err := authtypes.ClaimsFromContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
render.Error(rw, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
id, ok := mux.Vars(r)["preferenceId"]
|
|
||||||
if !ok {
|
|
||||||
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is required"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
req := new(preferencetypes.UpdatablePreference)
|
|
||||||
|
|
||||||
err = json.NewDecoder(r.Body).Decode(req)
|
|
||||||
if err != nil {
|
|
||||||
render.Error(rw, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = handler.module.UpdateOrg(ctx, id, req.PreferenceValue, claims.OrgID)
|
|
||||||
if err != nil {
|
|
||||||
render.Error(rw, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
render.Success(rw, http.StatusNoContent, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (handler *handler) GetAllOrg(rw http.ResponseWriter, r *http.Request) {
|
|
||||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
claims, err := authtypes.ClaimsFromContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
render.Error(rw, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
preferences, err := handler.module.GetAllOrg(ctx, claims.OrgID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
render.Error(rw, err)
|
render.Error(rw, err)
|
||||||
return
|
return
|
||||||
@ -99,7 +42,7 @@ func (handler *handler) GetAllOrg(rw http.ResponseWriter, r *http.Request) {
|
|||||||
render.Success(rw, http.StatusOK, preferences)
|
render.Success(rw, http.StatusOK, preferences)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *handler) GetUser(rw http.ResponseWriter, r *http.Request) {
|
func (handler *handler) GetByOrg(rw http.ResponseWriter, r *http.Request) {
|
||||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@ -109,13 +52,19 @@ func (handler *handler) GetUser(rw http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
id, ok := mux.Vars(r)["preferenceId"]
|
nameString, ok := mux.Vars(r)["preferenceId"]
|
||||||
if !ok {
|
if !ok {
|
||||||
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is required"))
|
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is required"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
preference, err := handler.module.GetUser(ctx, id, claims.OrgID, claims.UserID)
|
name, err := preferencetypes.NewName(nameString)
|
||||||
|
if err != nil {
|
||||||
|
render.Error(rw, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
preference, err := handler.module.GetByOrg(ctx, valuer.MustNewUUID(claims.OrgID), name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
render.Error(rw, err)
|
render.Error(rw, err)
|
||||||
return
|
return
|
||||||
@ -124,7 +73,7 @@ func (handler *handler) GetUser(rw http.ResponseWriter, r *http.Request) {
|
|||||||
render.Success(rw, http.StatusOK, preference)
|
render.Success(rw, http.StatusOK, preference)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *handler) UpdateUser(rw http.ResponseWriter, r *http.Request) {
|
func (handler *handler) UpdateByOrg(rw http.ResponseWriter, r *http.Request) {
|
||||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@ -134,12 +83,18 @@ func (handler *handler) UpdateUser(rw http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
id, ok := mux.Vars(r)["preferenceId"]
|
nameString, ok := mux.Vars(r)["preferenceId"]
|
||||||
if !ok {
|
if !ok {
|
||||||
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is required"))
|
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is required"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name, err := preferencetypes.NewName(nameString)
|
||||||
|
if err != nil {
|
||||||
|
render.Error(rw, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
req := new(preferencetypes.UpdatablePreference)
|
req := new(preferencetypes.UpdatablePreference)
|
||||||
err = json.NewDecoder(r.Body).Decode(req)
|
err = json.NewDecoder(r.Body).Decode(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -147,7 +102,7 @@ func (handler *handler) UpdateUser(rw http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = handler.module.UpdateUser(ctx, id, req.PreferenceValue, claims.UserID)
|
err = handler.module.UpdateByOrg(ctx, valuer.MustNewUUID(claims.OrgID), name, req.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
render.Error(rw, err)
|
render.Error(rw, err)
|
||||||
return
|
return
|
||||||
@ -156,7 +111,7 @@ func (handler *handler) UpdateUser(rw http.ResponseWriter, r *http.Request) {
|
|||||||
render.Success(rw, http.StatusNoContent, nil)
|
render.Success(rw, http.StatusNoContent, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *handler) GetAllUser(rw http.ResponseWriter, r *http.Request) {
|
func (handler *handler) ListByUser(rw http.ResponseWriter, r *http.Request) {
|
||||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@ -166,7 +121,7 @@ func (handler *handler) GetAllUser(rw http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
preferences, err := handler.module.GetAllUser(ctx, claims.OrgID, claims.UserID)
|
preferences, err := handler.module.ListByUser(ctx, valuer.MustNewUUID(claims.UserID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
render.Error(rw, err)
|
render.Error(rw, err)
|
||||||
return
|
return
|
||||||
@ -174,3 +129,72 @@ func (handler *handler) GetAllUser(rw http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
render.Success(rw, http.StatusOK, preferences)
|
render.Success(rw, http.StatusOK, preferences)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (handler *handler) GetByUser(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
claims, err := authtypes.ClaimsFromContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
render.Error(rw, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nameString, ok := mux.Vars(r)["preferenceId"]
|
||||||
|
if !ok {
|
||||||
|
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is required"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
name, err := preferencetypes.NewName(nameString)
|
||||||
|
if err != nil {
|
||||||
|
render.Error(rw, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
preference, err := handler.module.GetByUser(ctx, valuer.MustNewUUID(claims.UserID), name)
|
||||||
|
if err != nil {
|
||||||
|
render.Error(rw, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
render.Success(rw, http.StatusOK, preference)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *handler) UpdateByUser(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
claims, err := authtypes.ClaimsFromContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
render.Error(rw, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nameString, ok := mux.Vars(r)["preferenceId"]
|
||||||
|
if !ok {
|
||||||
|
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is required"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
name, err := preferencetypes.NewName(nameString)
|
||||||
|
if err != nil {
|
||||||
|
render.Error(rw, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req := new(preferencetypes.UpdatablePreference)
|
||||||
|
err = json.NewDecoder(r.Body).Decode(req)
|
||||||
|
if err != nil {
|
||||||
|
render.Error(rw, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = handler.module.UpdateByUser(ctx, valuer.MustNewUUID(claims.UserID), name, req.Value)
|
||||||
|
if err != nil {
|
||||||
|
render.Error(rw, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
render.Success(rw, http.StatusNoContent, nil)
|
||||||
|
}
|
||||||
|
@ -2,8 +2,6 @@ package implpreference
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"github.com/SigNoz/signoz/pkg/errors"
|
"github.com/SigNoz/signoz/pkg/errors"
|
||||||
"github.com/SigNoz/signoz/pkg/modules/preference"
|
"github.com/SigNoz/signoz/pkg/modules/preference"
|
||||||
@ -14,265 +12,155 @@ import (
|
|||||||
// Do not take inspiration from this code, it is a work in progress. See Organization module for a better implementation.
|
// Do not take inspiration from this code, it is a work in progress. See Organization module for a better implementation.
|
||||||
type module struct {
|
type module struct {
|
||||||
store preferencetypes.Store
|
store preferencetypes.Store
|
||||||
defaultMap map[string]preferencetypes.Preference
|
available map[preferencetypes.Name]preferencetypes.Preference
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewModule(store preferencetypes.Store, defaultMap map[string]preferencetypes.Preference) preference.Module {
|
func NewModule(store preferencetypes.Store, available map[preferencetypes.Name]preferencetypes.Preference) preference.Module {
|
||||||
return &module{store: store, defaultMap: defaultMap}
|
return &module{store: store, available: available}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (module *module) GetOrg(ctx context.Context, preferenceID string, orgID string) (*preferencetypes.GettablePreference, error) {
|
func (module *module) ListByOrg(ctx context.Context, orgID valuer.UUID) ([]*preferencetypes.GettablePreference, error) {
|
||||||
preference, seen := module.defaultMap[preferenceID]
|
storableOrgPreferences, err := module.store.ListByOrg(ctx, orgID)
|
||||||
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 != nil {
|
||||||
if err == sql.ErrNoRows {
|
return nil, err
|
||||||
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{
|
var gettablePreferences []*preferencetypes.GettablePreference
|
||||||
PreferenceID: preferenceID,
|
for _, preference := range module.available {
|
||||||
PreferenceValue: preference.SanitizeValue(org.PreferenceValue),
|
copyOfPreference, err := preferencetypes.NewPreferenceFromAvailable(preference.Name, module.available)
|
||||||
}, nil
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, storableOrgPreference := range storableOrgPreferences {
|
||||||
|
if storableOrgPreference.Name == preference.Name {
|
||||||
|
gettablePreferences = append(gettablePreferences, preferencetypes.NewGettablePreference(copyOfPreference, storableOrgPreference.Value))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
gettablePreferences = append(gettablePreferences, preferencetypes.NewGettablePreference(copyOfPreference, preference.DefaultValue))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return gettablePreferences, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (module *module) UpdateOrg(ctx context.Context, preferenceID string, preferenceValue interface{}, orgID string) error {
|
func (module *module) GetByOrg(ctx context.Context, orgID valuer.UUID, name preferencetypes.Name) (*preferencetypes.GettablePreference, error) {
|
||||||
preference, seen := module.defaultMap[preferenceID]
|
preference, err := preferencetypes.NewPreference(name, preferencetypes.ScopeOrg, module.available)
|
||||||
if !seen {
|
if err != nil {
|
||||||
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot find preference with id: %s", preferenceID)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
isEnabled := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope)
|
org, err := module.store.GetByOrg(ctx, orgID, name)
|
||||||
if !isEnabled {
|
if err != nil {
|
||||||
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "preference is not enabled at org scope: %s", preferenceID)
|
if errors.As(err, errors.TypeNotFound) {
|
||||||
|
return preferencetypes.NewGettablePreference(preference, preference.DefaultValue), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err := preference.IsValidValue(preferenceValue)
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return preferencetypes.NewGettablePreference(preference, org.Value), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (module *module) UpdateByOrg(ctx context.Context, orgID valuer.UUID, name preferencetypes.Name, preferenceValue string) error {
|
||||||
|
preference, err := preferencetypes.NewPreference(name, preferencetypes.ScopeOrg, module.available)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
storableValue, encodeErr := json.Marshal(preferenceValue)
|
_, err = preferencetypes.NewPreferenceValueFromString(preference, preferenceValue)
|
||||||
if encodeErr != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(encodeErr, errors.TypeInvalidInput, errors.CodeInvalidInput, "error in encoding the preference value")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
org, dberr := module.store.GetOrg(ctx, orgID, preferenceID)
|
storableOrgPreference, err := module.store.GetByOrg(ctx, orgID, name)
|
||||||
if dberr != nil && dberr != sql.ErrNoRows {
|
if err != nil {
|
||||||
return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in getting the preference value")
|
if !errors.As(err, errors.TypeNotFound) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if dberr != nil {
|
if storableOrgPreference == nil {
|
||||||
org.ID = valuer.GenerateUUID()
|
storableOrgPreference = preferencetypes.NewStorableOrgPreference(preference, preferenceValue, orgID)
|
||||||
org.PreferenceID = preferenceID
|
|
||||||
org.PreferenceValue = string(storableValue)
|
|
||||||
org.OrgID = orgID
|
|
||||||
} else {
|
|
||||||
org.PreferenceValue = string(storableValue)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dberr = module.store.UpsertOrg(ctx, org)
|
err = module.store.UpsertByOrg(ctx, storableOrgPreference)
|
||||||
if dberr != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in setting the preference value")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (module *module) GetAllOrg(ctx context.Context, orgID string) ([]*preferencetypes.PreferenceWithValue, error) {
|
func (module *module) ListByUser(ctx context.Context, userID valuer.UUID) ([]*preferencetypes.GettablePreference, error) {
|
||||||
allOrgs := []*preferencetypes.PreferenceWithValue{}
|
storableUserPreferences, err := module.store.ListByUser(ctx, userID)
|
||||||
orgs, err := module.store.GetAllOrg(ctx, orgID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "error in setting all org preference values")
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
preferenceValueMap := map[string]interface{}{}
|
var gettablePreferences []*preferencetypes.GettablePreference
|
||||||
for _, preferenceValue := range orgs {
|
for _, preference := range module.available {
|
||||||
preferenceValueMap[preferenceValue.PreferenceID] = preferenceValue.PreferenceValue
|
copyOfPreference, err := preferencetypes.NewPreferenceFromAvailable(preference.Name, module.available)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, storableUserPreference := range storableUserPreferences {
|
||||||
|
if storableUserPreference.Name == preference.Name {
|
||||||
|
gettablePreferences = append(gettablePreferences, preferencetypes.NewGettablePreference(copyOfPreference, storableUserPreference.Value))
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, preference := range module.defaultMap {
|
gettablePreferences = append(gettablePreferences, preferencetypes.NewGettablePreference(copyOfPreference, preference.DefaultValue))
|
||||||
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)
|
return gettablePreferences, nil
|
||||||
allOrgs = append(allOrgs, preferenceWithValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return allOrgs, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (module *module) GetUser(ctx context.Context, preferenceID string, orgID string, userID string) (*preferencetypes.GettablePreference, error) {
|
func (module *module) GetByUser(ctx context.Context, userID valuer.UUID, name preferencetypes.Name) (*preferencetypes.GettablePreference, error) {
|
||||||
preference, seen := module.defaultMap[preferenceID]
|
preference, err := preferencetypes.NewPreference(name, preferencetypes.ScopeUser, module.available)
|
||||||
if !seen {
|
if err != nil {
|
||||||
return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot find preference with id: %s", preferenceID)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
preferenceValue := preferencetypes.GettablePreference{
|
storableUserPreference, err := module.store.GetByUser(ctx, userID, name)
|
||||||
PreferenceID: preferenceID,
|
if err != nil {
|
||||||
PreferenceValue: preference.DefaultValue,
|
if errors.As(err, errors.TypeNotFound) {
|
||||||
|
return preferencetypes.NewGettablePreference(preference, preference.DefaultValue), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
isEnabledAtUserScope := preference.IsEnabledForScope(preferencetypes.UserAllowedScope)
|
return nil, err
|
||||||
if !isEnabledAtUserScope {
|
|
||||||
return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "preference is not enabled at user scope: %s", preferenceID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isEnabledAtOrgScope := preference.IsEnabledForScope(preferencetypes.OrgAllowedScope)
|
return preferencetypes.NewGettablePreference(preference, storableUserPreference.Value), nil
|
||||||
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 {
|
func (module *module) UpdateByUser(ctx context.Context, userID valuer.UUID, name preferencetypes.Name, preferenceValue string) error {
|
||||||
preference, seen := module.defaultMap[preferenceID]
|
preference, err := preferencetypes.NewPreference(name, preferencetypes.ScopeUser, module.available)
|
||||||
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
storableValue, encodeErr := json.Marshal(preferenceValue)
|
_, err = preferencetypes.NewPreferenceValueFromString(preference, preferenceValue)
|
||||||
if encodeErr != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(encodeErr, errors.TypeInvalidInput, errors.CodeInvalidInput, "error in encoding the preference value")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
user, dberr := module.store.GetUser(ctx, userID, preferenceID)
|
storableUserPreference, err := module.store.GetByUser(ctx, userID, name)
|
||||||
if dberr != nil && dberr != sql.ErrNoRows {
|
if err != nil {
|
||||||
return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in getting the preference value")
|
if !errors.As(err, errors.TypeNotFound) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if dberr != nil {
|
if storableUserPreference == nil {
|
||||||
user.ID = valuer.GenerateUUID()
|
storableUserPreference = preferencetypes.NewStorableUserPreference(preference, preferenceValue, userID)
|
||||||
user.PreferenceID = preferenceID
|
|
||||||
user.PreferenceValue = string(storableValue)
|
|
||||||
user.UserID = userID
|
|
||||||
} else {
|
|
||||||
user.PreferenceValue = string(storableValue)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dberr = module.store.UpsertUser(ctx, user)
|
err = module.store.UpsertByUser(ctx, storableUserPreference)
|
||||||
if dberr != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(dberr, errors.TypeInternal, errors.CodeInternal, "error in setting the preference value")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
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
|
|
||||||
}
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||||
"github.com/SigNoz/signoz/pkg/types/preferencetypes"
|
"github.com/SigNoz/signoz/pkg/types/preferencetypes"
|
||||||
|
"github.com/SigNoz/signoz/pkg/valuer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type store struct {
|
type store struct {
|
||||||
@ -15,14 +16,14 @@ func NewStore(db sqlstore.SQLStore) preferencetypes.Store {
|
|||||||
return &store{store: db}
|
return &store{store: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *store) GetOrg(ctx context.Context, orgID string, preferenceID string) (*preferencetypes.StorableOrgPreference, error) {
|
func (store *store) GetByOrg(ctx context.Context, orgID valuer.UUID, name preferencetypes.Name) (*preferencetypes.StorableOrgPreference, error) {
|
||||||
orgPreference := new(preferencetypes.StorableOrgPreference)
|
orgPreference := new(preferencetypes.StorableOrgPreference)
|
||||||
err := store.
|
err := store.
|
||||||
store.
|
store.
|
||||||
BunDB().
|
BunDB().
|
||||||
NewSelect().
|
NewSelect().
|
||||||
Model(orgPreference).
|
Model(orgPreference).
|
||||||
Where("preference_id = ?", preferenceID).
|
Where("preference_id = ?", name).
|
||||||
Where("org_id = ?", orgID).
|
Where("org_id = ?", orgID).
|
||||||
Scan(ctx)
|
Scan(ctx)
|
||||||
|
|
||||||
@ -33,7 +34,7 @@ func (store *store) GetOrg(ctx context.Context, orgID string, preferenceID strin
|
|||||||
return orgPreference, nil
|
return orgPreference, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *store) GetAllOrg(ctx context.Context, orgID string) ([]*preferencetypes.StorableOrgPreference, error) {
|
func (store *store) ListByOrg(ctx context.Context, orgID valuer.UUID) ([]*preferencetypes.StorableOrgPreference, error) {
|
||||||
orgPreferences := make([]*preferencetypes.StorableOrgPreference, 0)
|
orgPreferences := make([]*preferencetypes.StorableOrgPreference, 0)
|
||||||
err := store.
|
err := store.
|
||||||
store.
|
store.
|
||||||
@ -50,7 +51,7 @@ func (store *store) GetAllOrg(ctx context.Context, orgID string) ([]*preferencet
|
|||||||
return orgPreferences, nil
|
return orgPreferences, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *store) UpsertOrg(ctx context.Context, orgPreference *preferencetypes.StorableOrgPreference) error {
|
func (store *store) UpsertByOrg(ctx context.Context, orgPreference *preferencetypes.StorableOrgPreference) error {
|
||||||
_, err := store.
|
_, err := store.
|
||||||
store.
|
store.
|
||||||
BunDB().
|
BunDB().
|
||||||
@ -65,17 +66,16 @@ func (store *store) UpsertOrg(ctx context.Context, orgPreference *preferencetype
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *store) GetUser(ctx context.Context, userID string, preferenceID string) (*preferencetypes.StorableUserPreference, error) {
|
func (store *store) GetByUser(ctx context.Context, userID valuer.UUID, name preferencetypes.Name) (*preferencetypes.StorableUserPreference, error) {
|
||||||
userPreference := new(preferencetypes.StorableUserPreference)
|
userPreference := new(preferencetypes.StorableUserPreference)
|
||||||
|
|
||||||
err := store.
|
err := store.
|
||||||
store.
|
store.
|
||||||
BunDB().
|
BunDB().
|
||||||
NewSelect().
|
NewSelect().
|
||||||
Model(userPreference).
|
Model(userPreference).
|
||||||
Where("preference_id = ?", preferenceID).
|
|
||||||
Where("user_id = ?", userID).
|
Where("user_id = ?", userID).
|
||||||
Scan(ctx)
|
Scan(ctx)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return userPreference, err
|
return userPreference, err
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ func (store *store) GetUser(ctx context.Context, userID string, preferenceID str
|
|||||||
return userPreference, nil
|
return userPreference, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *store) GetAllUser(ctx context.Context, userID string) ([]*preferencetypes.StorableUserPreference, error) {
|
func (store *store) ListByUser(ctx context.Context, userID valuer.UUID) ([]*preferencetypes.StorableUserPreference, error) {
|
||||||
userPreferences := make([]*preferencetypes.StorableUserPreference, 0)
|
userPreferences := make([]*preferencetypes.StorableUserPreference, 0)
|
||||||
err := store.
|
err := store.
|
||||||
store.
|
store.
|
||||||
@ -100,7 +100,7 @@ func (store *store) GetAllUser(ctx context.Context, userID string) ([]*preferenc
|
|||||||
return userPreferences, nil
|
return userPreferences, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *store) UpsertUser(ctx context.Context, userPreference *preferencetypes.StorableUserPreference) error {
|
func (store *store) UpsertByUser(ctx context.Context, userPreference *preferencetypes.StorableUserPreference) error {
|
||||||
_, err := store.
|
_, err := store.
|
||||||
store.
|
store.
|
||||||
BunDB().
|
BunDB().
|
||||||
|
@ -5,44 +5,45 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/SigNoz/signoz/pkg/types/preferencetypes"
|
"github.com/SigNoz/signoz/pkg/types/preferencetypes"
|
||||||
|
"github.com/SigNoz/signoz/pkg/valuer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Module interface {
|
type Module interface {
|
||||||
// Returns the preference for the given organization
|
|
||||||
GetOrg(ctx context.Context, preferenceId string, orgId string) (*preferencetypes.GettablePreference, error)
|
|
||||||
|
|
||||||
// Returns the preference for the given user
|
|
||||||
GetUser(ctx context.Context, preferenceId string, orgId string, userId string) (*preferencetypes.GettablePreference, error)
|
|
||||||
|
|
||||||
// Returns all preferences for the given organization
|
// Returns all preferences for the given organization
|
||||||
GetAllOrg(ctx context.Context, orgId string) ([]*preferencetypes.PreferenceWithValue, error)
|
ListByOrg(context.Context, valuer.UUID) ([]*preferencetypes.GettablePreference, error)
|
||||||
|
|
||||||
// Returns all preferences for the given user
|
// Returns the preference for the given organization by name.
|
||||||
GetAllUser(ctx context.Context, orgId string, userId string) ([]*preferencetypes.PreferenceWithValue, error)
|
GetByOrg(context.Context, valuer.UUID, preferencetypes.Name) (*preferencetypes.GettablePreference, error)
|
||||||
|
|
||||||
// Updates the preference for the given organization
|
// Updates the preference for the given organization
|
||||||
UpdateOrg(ctx context.Context, preferenceId string, preferenceValue interface{}, orgId string) error
|
UpdateByOrg(context.Context, valuer.UUID, preferencetypes.Name, string) error
|
||||||
|
|
||||||
|
// Returns all preferences for the given user
|
||||||
|
ListByUser(context.Context, valuer.UUID) ([]*preferencetypes.GettablePreference, error)
|
||||||
|
|
||||||
|
// Returns the preference for the given user by name.
|
||||||
|
GetByUser(context.Context, valuer.UUID, preferencetypes.Name) (*preferencetypes.GettablePreference, error)
|
||||||
|
|
||||||
// Updates the preference for the given user
|
// Updates the preference for the given user
|
||||||
UpdateUser(ctx context.Context, preferenceId string, preferenceValue interface{}, userId string) error
|
UpdateByUser(context.Context, valuer.UUID, preferencetypes.Name, string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
// Returns the preference for the given organization
|
// Returns the preference for the given organization
|
||||||
GetOrg(http.ResponseWriter, *http.Request)
|
GetByOrg(http.ResponseWriter, *http.Request)
|
||||||
|
|
||||||
// Updates the preference for the given organization
|
// Updates the preference for the given organization
|
||||||
UpdateOrg(http.ResponseWriter, *http.Request)
|
UpdateByOrg(http.ResponseWriter, *http.Request)
|
||||||
|
|
||||||
// Returns all preferences for the given organization
|
// Returns all preferences for the given organization
|
||||||
GetAllOrg(http.ResponseWriter, *http.Request)
|
ListByOrg(http.ResponseWriter, *http.Request)
|
||||||
|
|
||||||
// Returns the preference for the given user
|
// Returns the preference for the given user
|
||||||
GetUser(http.ResponseWriter, *http.Request)
|
GetByUser(http.ResponseWriter, *http.Request)
|
||||||
|
|
||||||
// Updates the preference for the given user
|
// Updates the preference for the given user
|
||||||
UpdateUser(http.ResponseWriter, *http.Request)
|
UpdateByUser(http.ResponseWriter, *http.Request)
|
||||||
|
|
||||||
// Returns all preferences for the given user
|
// Returns all preferences for the given user
|
||||||
GetAllUser(http.ResponseWriter, *http.Request)
|
ListByUser(http.ResponseWriter, *http.Request)
|
||||||
}
|
}
|
||||||
|
@ -561,12 +561,12 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router, am *middleware.AuthZ) {
|
|||||||
|
|
||||||
router.HandleFunc("/api/v1/disks", am.ViewAccess(aH.getDisks)).Methods(http.MethodGet)
|
router.HandleFunc("/api/v1/disks", am.ViewAccess(aH.getDisks)).Methods(http.MethodGet)
|
||||||
|
|
||||||
router.HandleFunc("/api/v1/user/preferences", am.ViewAccess(aH.Signoz.Handlers.Preference.GetAllUser)).Methods(http.MethodGet)
|
router.HandleFunc("/api/v1/user/preferences", am.ViewAccess(aH.Signoz.Handlers.Preference.ListByUser)).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/user/preferences/{preferenceId}", am.ViewAccess(aH.Signoz.Handlers.Preference.GetUser)).Methods(http.MethodGet)
|
router.HandleFunc("/api/v1/user/preferences/{preferenceId}", am.ViewAccess(aH.Signoz.Handlers.Preference.GetByUser)).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/user/preferences/{preferenceId}", am.ViewAccess(aH.Signoz.Handlers.Preference.UpdateUser)).Methods(http.MethodPut)
|
router.HandleFunc("/api/v1/user/preferences/{preferenceId}", am.ViewAccess(aH.Signoz.Handlers.Preference.UpdateByUser)).Methods(http.MethodPut)
|
||||||
router.HandleFunc("/api/v1/org/preferences", am.AdminAccess(aH.Signoz.Handlers.Preference.GetAllOrg)).Methods(http.MethodGet)
|
router.HandleFunc("/api/v1/org/preferences", am.AdminAccess(aH.Signoz.Handlers.Preference.ListByOrg)).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/org/preferences/{preferenceId}", am.AdminAccess(aH.Signoz.Handlers.Preference.GetOrg)).Methods(http.MethodGet)
|
router.HandleFunc("/api/v1/org/preferences/{preferenceId}", am.AdminAccess(aH.Signoz.Handlers.Preference.GetByOrg)).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/org/preferences/{preferenceId}", am.AdminAccess(aH.Signoz.Handlers.Preference.UpdateOrg)).Methods(http.MethodPut)
|
router.HandleFunc("/api/v1/org/preferences/{preferenceId}", am.AdminAccess(aH.Signoz.Handlers.Preference.UpdateByOrg)).Methods(http.MethodPut)
|
||||||
|
|
||||||
// Quick Filters
|
// Quick Filters
|
||||||
router.HandleFunc("/api/v1/orgs/me/filters", am.ViewAccess(aH.Signoz.Handlers.QuickFilter.GetQuickFilters)).Methods(http.MethodGet)
|
router.HandleFunc("/api/v1/orgs/me/filters", am.ViewAccess(aH.Signoz.Handlers.QuickFilter.GetQuickFilters)).Methods(http.MethodGet)
|
||||||
|
@ -51,7 +51,7 @@ func NewModules(
|
|||||||
return Modules{
|
return Modules{
|
||||||
OrgGetter: orgGetter,
|
OrgGetter: orgGetter,
|
||||||
OrgSetter: orgSetter,
|
OrgSetter: orgSetter,
|
||||||
Preference: implpreference.NewModule(implpreference.NewStore(sqlstore), preferencetypes.NewDefaultPreferenceMap()),
|
Preference: implpreference.NewModule(implpreference.NewStore(sqlstore), preferencetypes.NewAvailablePreference()),
|
||||||
SavedView: implsavedview.NewModule(sqlstore),
|
SavedView: implsavedview.NewModule(sqlstore),
|
||||||
Apdex: implapdex.NewModule(sqlstore),
|
Apdex: implapdex.NewModule(sqlstore),
|
||||||
Dashboard: impldashboard.NewModule(sqlstore, providerSettings),
|
Dashboard: impldashboard.NewModule(sqlstore, providerSettings),
|
||||||
|
44
pkg/types/preferencetypes/name.go
Normal file
44
pkg/types/preferencetypes/name.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package preferencetypes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"slices"
|
||||||
|
|
||||||
|
"github.com/SigNoz/signoz/pkg/errors"
|
||||||
|
"github.com/SigNoz/signoz/pkg/valuer"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
NameOrgOnboarding = Name{valuer.NewString("org_onboarding")}
|
||||||
|
NameWelcomeChecklistDoLater = Name{valuer.NewString("welcome_checklist_do_later")}
|
||||||
|
NameWelcomeChecklistSendLogsSkipped = Name{valuer.NewString("welcome_checklist_send_logs_skipped")}
|
||||||
|
NameWelcomeChecklistSendTracesSkipped = Name{valuer.NewString("welcome_checklist_send_traces_skipped")}
|
||||||
|
NameWelcomeChecklistSendInfraMetricsSkipped = Name{valuer.NewString("welcome_checklist_send_infra_metrics_skipped")}
|
||||||
|
NameWelcomeChecklistSetupDashboardsSkipped = Name{valuer.NewString("welcome_checklist_setup_dashboards_skipped")}
|
||||||
|
NameWelcomeChecklistSetupAlertsSkipped = Name{valuer.NewString("welcome_checklist_setup_alerts_skipped")}
|
||||||
|
NameWelcomeChecklistSetupSavedViewSkipped = Name{valuer.NewString("welcome_checklist_setup_saved_view_skipped")}
|
||||||
|
NameSidenavPinned = Name{valuer.NewString("sidenav_pinned")}
|
||||||
|
)
|
||||||
|
|
||||||
|
type Name struct{ valuer.String }
|
||||||
|
|
||||||
|
func NewName(name string) (Name, error) {
|
||||||
|
ok := slices.Contains(
|
||||||
|
[]string{
|
||||||
|
NameOrgOnboarding.StringValue(),
|
||||||
|
NameWelcomeChecklistDoLater.StringValue(),
|
||||||
|
NameWelcomeChecklistSendLogsSkipped.StringValue(),
|
||||||
|
NameWelcomeChecklistSendTracesSkipped.StringValue(),
|
||||||
|
NameWelcomeChecklistSendInfraMetricsSkipped.StringValue(),
|
||||||
|
NameWelcomeChecklistSetupDashboardsSkipped.StringValue(),
|
||||||
|
NameWelcomeChecklistSetupAlertsSkipped.StringValue(),
|
||||||
|
NameWelcomeChecklistSetupSavedViewSkipped.StringValue(),
|
||||||
|
NameSidenavPinned.StringValue(),
|
||||||
|
},
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
if !ok {
|
||||||
|
return Name{}, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "invalid name: %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Name{valuer.NewString(name)}, nil
|
||||||
|
}
|
@ -2,298 +2,204 @@ package preferencetypes
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strings"
|
"slices"
|
||||||
|
|
||||||
"github.com/SigNoz/signoz/pkg/errors"
|
"github.com/SigNoz/signoz/pkg/errors"
|
||||||
"github.com/SigNoz/signoz/pkg/types"
|
"github.com/SigNoz/signoz/pkg/types"
|
||||||
|
"github.com/SigNoz/signoz/pkg/valuer"
|
||||||
"github.com/uptrace/bun"
|
"github.com/uptrace/bun"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GettablePreference struct {
|
type Preference struct {
|
||||||
PreferenceID string `json:"preference_id" db:"preference_id"`
|
Name Name `json:"name"`
|
||||||
PreferenceValue interface{} `json:"preference_value" db:"preference_value"`
|
Description string `json:"description"`
|
||||||
}
|
ValueType ValueType `json:"valueType"`
|
||||||
|
DefaultValue any `json:"defaultValue"`
|
||||||
type UpdatablePreference struct {
|
AllowedValues []any `json:"allowedValues"`
|
||||||
PreferenceValue interface{} `json:"preference_value" db:"preference_value"`
|
IsDiscreteValues bool `json:"isDiscreteValues"`
|
||||||
|
Range Range `json:"range"`
|
||||||
|
AllowedScopes []Scope `json:"allowedScopes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type StorableOrgPreference struct {
|
type StorableOrgPreference struct {
|
||||||
bun.BaseModel `bun:"table:org_preference"`
|
bun.BaseModel `bun:"table:org_preference"`
|
||||||
types.Identifiable
|
types.Identifiable
|
||||||
PreferenceID string `bun:"preference_id,type:text,notnull"`
|
Name Name `bun:"preference_id,type:text,notnull"`
|
||||||
PreferenceValue string `bun:"preference_value,type:text,notnull"`
|
Value string `bun:"preference_value,type:text,notnull"`
|
||||||
OrgID string `bun:"org_id,type:text,notnull"`
|
OrgID valuer.UUID `bun:"org_id,type:text,notnull"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type StorableUserPreference struct {
|
type StorableUserPreference struct {
|
||||||
bun.BaseModel `bun:"table:user_preference"`
|
bun.BaseModel `bun:"table:user_preference"`
|
||||||
types.Identifiable
|
types.Identifiable
|
||||||
PreferenceID string `bun:"preference_id,type:text,notnull"`
|
Name Name `bun:"preference_id,type:text,notnull"`
|
||||||
PreferenceValue string `bun:"preference_value,type:text,notnull"`
|
Value string `bun:"preference_value,type:text,notnull"`
|
||||||
UserID string `bun:"user_id,type:text,notnull"`
|
UserID valuer.UUID `bun:"user_id,type:text,notnull"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Preference struct {
|
type GettablePreference struct {
|
||||||
Key string `json:"key"`
|
*Preference
|
||||||
Name string `json:"name"`
|
Value any `json:"preference_value"`
|
||||||
Description string `json:"description"`
|
|
||||||
ValueType string `json:"valueType"`
|
|
||||||
DefaultValue interface{} `json:"defaultValue"`
|
|
||||||
AllowedValues []interface{} `json:"allowedValues"`
|
|
||||||
IsDiscreteValues bool `json:"isDiscreteValues"`
|
|
||||||
Range Range `json:"range"`
|
|
||||||
AllowedScopes []string `json:"allowedScopes"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDefaultPreferenceMap() map[string]Preference {
|
type UpdatablePreference struct {
|
||||||
return map[string]Preference{
|
Value string `json:"preference_value"`
|
||||||
"ORG_ONBOARDING": {
|
}
|
||||||
Key: "ORG_ONBOARDING",
|
|
||||||
Name: "Organisation Onboarding",
|
func NewAvailablePreference() map[Name]Preference {
|
||||||
|
return map[Name]Preference{
|
||||||
|
NameOrgOnboarding: {
|
||||||
|
Name: NameOrgOnboarding,
|
||||||
Description: "Organisation Onboarding",
|
Description: "Organisation Onboarding",
|
||||||
ValueType: "boolean",
|
ValueType: ValueTypeBoolean,
|
||||||
DefaultValue: false,
|
DefaultValue: false,
|
||||||
AllowedValues: []interface{}{true, false},
|
AllowedValues: []any{true, false},
|
||||||
IsDiscreteValues: true,
|
IsDiscreteValues: true,
|
||||||
AllowedScopes: []string{"org"},
|
AllowedScopes: []Scope{ScopeOrg},
|
||||||
},
|
},
|
||||||
"WELCOME_CHECKLIST_DO_LATER": {
|
NameWelcomeChecklistDoLater: {
|
||||||
Key: "WELCOME_CHECKLIST_DO_LATER",
|
Name: NameWelcomeChecklistDoLater,
|
||||||
Name: "Welcome Checklist Do Later",
|
|
||||||
Description: "Welcome Checklist Do Later",
|
Description: "Welcome Checklist Do Later",
|
||||||
ValueType: "boolean",
|
ValueType: ValueTypeBoolean,
|
||||||
DefaultValue: false,
|
DefaultValue: false,
|
||||||
AllowedValues: []interface{}{true, false},
|
AllowedValues: []any{true, false},
|
||||||
IsDiscreteValues: true,
|
IsDiscreteValues: true,
|
||||||
AllowedScopes: []string{"user"},
|
AllowedScopes: []Scope{ScopeUser},
|
||||||
},
|
},
|
||||||
"WELCOME_CHECKLIST_SEND_LOGS_SKIPPED": {
|
NameWelcomeChecklistSendLogsSkipped: {
|
||||||
Key: "WELCOME_CHECKLIST_SEND_LOGS_SKIPPED",
|
Name: NameWelcomeChecklistSendLogsSkipped,
|
||||||
Name: "Welcome Checklist Send Logs Skipped",
|
|
||||||
Description: "Welcome Checklist Send Logs Skipped",
|
Description: "Welcome Checklist Send Logs Skipped",
|
||||||
ValueType: "boolean",
|
ValueType: ValueTypeBoolean,
|
||||||
DefaultValue: false,
|
DefaultValue: false,
|
||||||
AllowedValues: []interface{}{true, false},
|
AllowedValues: []any{true, false},
|
||||||
IsDiscreteValues: true,
|
IsDiscreteValues: true,
|
||||||
AllowedScopes: []string{"user"},
|
AllowedScopes: []Scope{ScopeUser},
|
||||||
},
|
},
|
||||||
"WELCOME_CHECKLIST_SEND_TRACES_SKIPPED": {
|
NameWelcomeChecklistSendTracesSkipped: {
|
||||||
Key: "WELCOME_CHECKLIST_SEND_TRACES_SKIPPED",
|
Name: NameWelcomeChecklistSendTracesSkipped,
|
||||||
Name: "Welcome Checklist Send Traces Skipped",
|
|
||||||
Description: "Welcome Checklist Send Traces Skipped",
|
Description: "Welcome Checklist Send Traces Skipped",
|
||||||
ValueType: "boolean",
|
ValueType: ValueTypeBoolean,
|
||||||
DefaultValue: false,
|
DefaultValue: false,
|
||||||
AllowedValues: []interface{}{true, false},
|
AllowedValues: []any{true, false},
|
||||||
IsDiscreteValues: true,
|
IsDiscreteValues: true,
|
||||||
AllowedScopes: []string{"user"},
|
AllowedScopes: []Scope{ScopeUser},
|
||||||
},
|
},
|
||||||
"WELCOME_CHECKLIST_SEND_INFRA_METRICS_SKIPPED": {
|
NameWelcomeChecklistSendInfraMetricsSkipped: {
|
||||||
Key: "WELCOME_CHECKLIST_SEND_INFRA_METRICS_SKIPPED",
|
Name: NameWelcomeChecklistSendInfraMetricsSkipped,
|
||||||
Name: "Welcome Checklist Send Infra Metrics Skipped",
|
|
||||||
Description: "Welcome Checklist Send Infra Metrics Skipped",
|
Description: "Welcome Checklist Send Infra Metrics Skipped",
|
||||||
ValueType: "boolean",
|
ValueType: ValueTypeBoolean,
|
||||||
DefaultValue: false,
|
DefaultValue: false,
|
||||||
AllowedValues: []interface{}{true, false},
|
AllowedValues: []any{true, false},
|
||||||
IsDiscreteValues: true,
|
IsDiscreteValues: true,
|
||||||
AllowedScopes: []string{"user"},
|
AllowedScopes: []Scope{ScopeUser},
|
||||||
},
|
},
|
||||||
"WELCOME_CHECKLIST_SETUP_DASHBOARDS_SKIPPED": {
|
NameWelcomeChecklistSetupDashboardsSkipped: {
|
||||||
Key: "WELCOME_CHECKLIST_SETUP_DASHBOARDS_SKIPPED",
|
Name: NameWelcomeChecklistSetupDashboardsSkipped,
|
||||||
Name: "Welcome Checklist Setup Dashboards Skipped",
|
|
||||||
Description: "Welcome Checklist Setup Dashboards Skipped",
|
Description: "Welcome Checklist Setup Dashboards Skipped",
|
||||||
ValueType: "boolean",
|
ValueType: ValueTypeBoolean,
|
||||||
DefaultValue: false,
|
DefaultValue: false,
|
||||||
AllowedValues: []interface{}{true, false},
|
AllowedValues: []any{true, false},
|
||||||
IsDiscreteValues: true,
|
IsDiscreteValues: true,
|
||||||
AllowedScopes: []string{"user"},
|
AllowedScopes: []Scope{ScopeUser},
|
||||||
},
|
},
|
||||||
"WELCOME_CHECKLIST_SETUP_ALERTS_SKIPPED": {
|
NameWelcomeChecklistSetupAlertsSkipped: {
|
||||||
Key: "WELCOME_CHECKLIST_SETUP_ALERTS_SKIPPED",
|
Name: NameWelcomeChecklistSetupAlertsSkipped,
|
||||||
Name: "Welcome Checklist Setup Alerts Skipped",
|
|
||||||
Description: "Welcome Checklist Setup Alerts Skipped",
|
Description: "Welcome Checklist Setup Alerts Skipped",
|
||||||
ValueType: "boolean",
|
ValueType: ValueTypeBoolean,
|
||||||
DefaultValue: false,
|
DefaultValue: false,
|
||||||
AllowedValues: []interface{}{true, false},
|
AllowedValues: []any{true, false},
|
||||||
IsDiscreteValues: true,
|
IsDiscreteValues: true,
|
||||||
AllowedScopes: []string{"user"},
|
AllowedScopes: []Scope{ScopeUser},
|
||||||
},
|
},
|
||||||
"WELCOME_CHECKLIST_SETUP_SAVED_VIEW_SKIPPED": {
|
NameWelcomeChecklistSetupSavedViewSkipped: {
|
||||||
Key: "WELCOME_CHECKLIST_SETUP_SAVED_VIEW_SKIPPED",
|
Name: NameWelcomeChecklistSetupSavedViewSkipped,
|
||||||
Name: "Welcome Checklist Setup Saved View Skipped",
|
|
||||||
Description: "Welcome Checklist Setup Saved View Skipped",
|
Description: "Welcome Checklist Setup Saved View Skipped",
|
||||||
ValueType: "boolean",
|
ValueType: ValueTypeBoolean,
|
||||||
DefaultValue: false,
|
DefaultValue: false,
|
||||||
AllowedValues: []interface{}{true, false},
|
AllowedValues: []any{true, false},
|
||||||
IsDiscreteValues: true,
|
IsDiscreteValues: true,
|
||||||
AllowedScopes: []string{"user"},
|
AllowedScopes: []Scope{ScopeUser},
|
||||||
},
|
},
|
||||||
"SIDENAV_PINNED": {
|
NameSidenavPinned: {
|
||||||
Key: "SIDENAV_PINNED",
|
Name: NameSidenavPinned,
|
||||||
Name: "Keep the primary sidenav always open",
|
|
||||||
Description: "Controls whether the primary sidenav remains expanded or can be collapsed. When enabled, the sidenav will stay open and pinned to provide constant visibility of navigation options.",
|
Description: "Controls whether the primary sidenav remains expanded or can be collapsed. When enabled, the sidenav will stay open and pinned to provide constant visibility of navigation options.",
|
||||||
ValueType: "boolean",
|
ValueType: ValueTypeBoolean,
|
||||||
DefaultValue: false,
|
DefaultValue: false,
|
||||||
AllowedValues: []interface{}{true, false},
|
AllowedValues: []any{true, false},
|
||||||
IsDiscreteValues: true,
|
IsDiscreteValues: true,
|
||||||
AllowedScopes: []string{"user"},
|
AllowedScopes: []Scope{ScopeUser},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Preference) ErrorValueTypeMismatch() error {
|
func NewPreference(name Name, scope Scope, available map[Name]Preference) (*Preference, error) {
|
||||||
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "the preference value is not of expected type: %s", p.ValueType)
|
preference, ok := available[name]
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.Newf(errors.TypeNotFound, errors.CodeNotFound, "the preference does not exist: %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !slices.Contains(preference.AllowedScopes, scope) {
|
||||||
|
return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "the preference is not allowed for the given scope: %s", scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Preference{
|
||||||
|
Name: name,
|
||||||
|
Description: preference.Description,
|
||||||
|
ValueType: preference.ValueType,
|
||||||
|
DefaultValue: preference.DefaultValue,
|
||||||
|
AllowedValues: preference.AllowedValues,
|
||||||
|
IsDiscreteValues: preference.IsDiscreteValues,
|
||||||
|
Range: preference.Range,
|
||||||
|
AllowedScopes: preference.AllowedScopes,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Preference) checkIfInAllowedValues(preferenceValue interface{}) (bool, error) {
|
func NewPreferenceFromAvailable(name Name, available map[Name]Preference) (*Preference, error) {
|
||||||
|
preference, ok := available[name]
|
||||||
switch p.ValueType {
|
|
||||||
case PreferenceValueTypeInteger:
|
|
||||||
_, ok := preferenceValue.(int64)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return false, p.ErrorValueTypeMismatch()
|
return nil, errors.Newf(errors.TypeNotFound, errors.CodeNotFound, "the preference does not exist: %s", name)
|
||||||
}
|
|
||||||
case PreferenceValueTypeFloat:
|
|
||||||
_, ok := preferenceValue.(float64)
|
|
||||||
if !ok {
|
|
||||||
return false, p.ErrorValueTypeMismatch()
|
|
||||||
}
|
|
||||||
case PreferenceValueTypeString:
|
|
||||||
_, ok := preferenceValue.(string)
|
|
||||||
if !ok {
|
|
||||||
return false, p.ErrorValueTypeMismatch()
|
|
||||||
}
|
|
||||||
case PreferenceValueTypeBoolean:
|
|
||||||
_, ok := preferenceValue.(bool)
|
|
||||||
if !ok {
|
|
||||||
return false, p.ErrorValueTypeMismatch()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
isInAllowedValues := false
|
|
||||||
for _, value := range p.AllowedValues {
|
|
||||||
switch p.ValueType {
|
|
||||||
case PreferenceValueTypeInteger:
|
|
||||||
allowedValue, ok := value.(int64)
|
|
||||||
if !ok {
|
|
||||||
return false, p.ErrorValueTypeMismatch()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if allowedValue == preferenceValue {
|
return &Preference{
|
||||||
isInAllowedValues = true
|
Name: name,
|
||||||
}
|
Description: preference.Description,
|
||||||
case PreferenceValueTypeFloat:
|
ValueType: preference.ValueType,
|
||||||
allowedValue, ok := value.(float64)
|
DefaultValue: preference.DefaultValue,
|
||||||
if !ok {
|
AllowedValues: preference.AllowedValues,
|
||||||
return false, p.ErrorValueTypeMismatch()
|
IsDiscreteValues: preference.IsDiscreteValues,
|
||||||
}
|
Range: preference.Range,
|
||||||
|
AllowedScopes: preference.AllowedScopes,
|
||||||
if allowedValue == preferenceValue {
|
}, nil
|
||||||
isInAllowedValues = true
|
|
||||||
}
|
|
||||||
case PreferenceValueTypeString:
|
|
||||||
allowedValue, ok := value.(string)
|
|
||||||
if !ok {
|
|
||||||
return false, p.ErrorValueTypeMismatch()
|
|
||||||
}
|
|
||||||
|
|
||||||
if allowedValue == preferenceValue {
|
|
||||||
isInAllowedValues = true
|
|
||||||
}
|
|
||||||
case PreferenceValueTypeBoolean:
|
|
||||||
allowedValue, ok := value.(bool)
|
|
||||||
if !ok {
|
|
||||||
return false, p.ErrorValueTypeMismatch()
|
|
||||||
}
|
|
||||||
|
|
||||||
if allowedValue == preferenceValue {
|
|
||||||
isInAllowedValues = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isInAllowedValues, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Preference) IsValidValue(preferenceValue interface{}) error {
|
func NewGettablePreference(preference *Preference, value any) *GettablePreference {
|
||||||
typeSafeValue := preferenceValue
|
return &GettablePreference{
|
||||||
switch p.ValueType {
|
Preference: preference,
|
||||||
case PreferenceValueTypeInteger:
|
Value: value,
|
||||||
val, ok := preferenceValue.(int64)
|
|
||||||
if !ok {
|
|
||||||
floatVal, ok := preferenceValue.(float64)
|
|
||||||
if !ok || floatVal != float64(int64(floatVal)) {
|
|
||||||
return p.ErrorValueTypeMismatch()
|
|
||||||
}
|
}
|
||||||
val = int64(floatVal)
|
|
||||||
typeSafeValue = val
|
|
||||||
}
|
|
||||||
if !p.IsDiscreteValues {
|
|
||||||
if val < p.Range.Min || val > p.Range.Max {
|
|
||||||
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "the preference value is not in the range specified, min: %v , max: %v", p.Range.Min, p.Range.Max)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case PreferenceValueTypeString:
|
|
||||||
_, ok := preferenceValue.(string)
|
|
||||||
if !ok {
|
|
||||||
return p.ErrorValueTypeMismatch()
|
|
||||||
}
|
|
||||||
case PreferenceValueTypeFloat:
|
|
||||||
_, ok := preferenceValue.(float64)
|
|
||||||
if !ok {
|
|
||||||
return p.ErrorValueTypeMismatch()
|
|
||||||
}
|
|
||||||
case PreferenceValueTypeBoolean:
|
|
||||||
_, ok := preferenceValue.(bool)
|
|
||||||
if !ok {
|
|
||||||
return p.ErrorValueTypeMismatch()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check the validity of the value being part of allowed values or the range specified if any
|
|
||||||
if p.IsDiscreteValues {
|
|
||||||
if p.AllowedValues != nil {
|
|
||||||
isInAllowedValues, valueMisMatchErr := p.checkIfInAllowedValues(typeSafeValue)
|
|
||||||
|
|
||||||
if valueMisMatchErr != nil {
|
|
||||||
return valueMisMatchErr
|
|
||||||
}
|
|
||||||
if !isInAllowedValues {
|
|
||||||
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "the preference value is not in the list of allowedValues: %v", p.AllowedValues)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Preference) IsEnabledForScope(scope string) bool {
|
func NewStorableOrgPreference(preference *Preference, value string, orgID valuer.UUID) *StorableOrgPreference {
|
||||||
isPreferenceEnabledForGivenScope := false
|
return &StorableOrgPreference{
|
||||||
if p.AllowedScopes != nil {
|
Name: preference.Name,
|
||||||
for _, allowedScope := range p.AllowedScopes {
|
Value: value,
|
||||||
if allowedScope == strings.ToLower(scope) {
|
OrgID: orgID,
|
||||||
isPreferenceEnabledForGivenScope = true
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return isPreferenceEnabledForGivenScope
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Preference) SanitizeValue(preferenceValue interface{}) interface{} {
|
func NewStorableUserPreference(preference *Preference, value string, userID valuer.UUID) *StorableUserPreference {
|
||||||
switch p.ValueType {
|
return &StorableUserPreference{
|
||||||
case PreferenceValueTypeBoolean:
|
Name: preference.Name,
|
||||||
if preferenceValue == "1" || preferenceValue == true || preferenceValue == "true" {
|
Value: value,
|
||||||
return true
|
UserID: userID,
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return preferenceValue
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Store interface {
|
type Store interface {
|
||||||
GetOrg(context.Context, string, string) (*StorableOrgPreference, error)
|
GetByOrg(context.Context, valuer.UUID, Name) (*StorableOrgPreference, error)
|
||||||
GetAllOrg(context.Context, string) ([]*StorableOrgPreference, error)
|
ListByOrg(context.Context, valuer.UUID) ([]*StorableOrgPreference, error)
|
||||||
UpsertOrg(context.Context, *StorableOrgPreference) error
|
UpsertByOrg(context.Context, *StorableOrgPreference) error
|
||||||
GetUser(context.Context, string, string) (*StorableUserPreference, error)
|
GetByUser(context.Context, valuer.UUID, Name) (*StorableUserPreference, error)
|
||||||
GetAllUser(context.Context, string) ([]*StorableUserPreference, error)
|
ListByUser(context.Context, valuer.UUID) ([]*StorableUserPreference, error)
|
||||||
UpsertUser(context.Context, *StorableUserPreference) error
|
UpsertByUser(context.Context, *StorableUserPreference) error
|
||||||
}
|
}
|
||||||
|
10
pkg/types/preferencetypes/scope.go
Normal file
10
pkg/types/preferencetypes/scope.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package preferencetypes
|
||||||
|
|
||||||
|
import "github.com/SigNoz/signoz/pkg/valuer"
|
||||||
|
|
||||||
|
var (
|
||||||
|
ScopeOrg = Scope{valuer.NewString("org")}
|
||||||
|
ScopeUser = Scope{valuer.NewString("user")}
|
||||||
|
)
|
||||||
|
|
||||||
|
type Scope struct{ valuer.String }
|
@ -1,23 +1,97 @@
|
|||||||
package preferencetypes
|
package preferencetypes
|
||||||
|
|
||||||
const (
|
import (
|
||||||
PreferenceValueTypeInteger string = "integer"
|
"encoding/json"
|
||||||
PreferenceValueTypeFloat string = "float"
|
"strconv"
|
||||||
PreferenceValueTypeString string = "string"
|
|
||||||
PreferenceValueTypeBoolean string = "boolean"
|
"github.com/SigNoz/signoz/pkg/errors"
|
||||||
|
"github.com/SigNoz/signoz/pkg/valuer"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
var (
|
||||||
OrgAllowedScope string = "org"
|
ValueTypeInteger = ValueType{valuer.NewString("integer")}
|
||||||
UserAllowedScope string = "user"
|
ValueTypeFloat = ValueType{valuer.NewString("float")}
|
||||||
|
ValueTypeString = ValueType{valuer.NewString("string")}
|
||||||
|
ValueTypeBoolean = ValueType{valuer.NewString("boolean")}
|
||||||
|
ValueTypeArray = ValueType{valuer.NewString("array")}
|
||||||
|
ValueTypeObject = ValueType{valuer.NewString("object")}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ValueType struct{ valuer.String }
|
||||||
|
|
||||||
type Range struct {
|
type Range struct {
|
||||||
Min int64 `json:"min"`
|
Min int64 `json:"min"`
|
||||||
Max int64 `json:"max"`
|
Max int64 `json:"max"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PreferenceWithValue struct {
|
func NewPreferenceValueFromString(preference *Preference, value string) (any, error) {
|
||||||
Preference
|
switch preference.ValueType {
|
||||||
Value interface{} `json:"value"`
|
case ValueTypeInteger:
|
||||||
|
val, err := strconv.ParseInt(value, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !preference.IsDiscreteValues {
|
||||||
|
if val < preference.Range.Min || val > preference.Range.Max {
|
||||||
|
return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "value is not in the range specified, min: %d , max: %d", preference.Range.Min, preference.Range.Max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(preference.AllowedValues) > 0 {
|
||||||
|
for _, allowedValue := range preference.AllowedValues {
|
||||||
|
if allowedValue == val {
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "value is not one of the allowed values: %v", preference.AllowedValues)
|
||||||
|
}
|
||||||
|
|
||||||
|
return val, nil
|
||||||
|
case ValueTypeFloat:
|
||||||
|
val, err := strconv.ParseFloat(value, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(preference.AllowedValues) > 0 {
|
||||||
|
for _, allowedValue := range preference.AllowedValues {
|
||||||
|
if allowedValue == val {
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "value is not one of the allowed values: %v", preference.AllowedValues)
|
||||||
|
}
|
||||||
|
|
||||||
|
return val, nil
|
||||||
|
case ValueTypeString:
|
||||||
|
if len(preference.AllowedValues) > 0 {
|
||||||
|
for _, allowedValue := range preference.AllowedValues {
|
||||||
|
if allowedValue == value {
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "value is not in the list of allowedValues: %v", preference.AllowedValues)
|
||||||
|
}
|
||||||
|
return value, nil
|
||||||
|
case ValueTypeBoolean:
|
||||||
|
return strconv.ParseBool(value)
|
||||||
|
case ValueTypeArray:
|
||||||
|
var arr []any
|
||||||
|
err := json.Unmarshal([]byte(value), &arr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return arr, nil
|
||||||
|
case ValueTypeObject:
|
||||||
|
var obj map[string]any
|
||||||
|
err := json.Unmarshal([]byte(value), &obj)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return obj, nil
|
||||||
|
default:
|
||||||
|
return nil, errors.Newf(errors.TypeUnsupported, errors.CodeUnsupported, "the preference value type is not supported: %s", preference.ValueType)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user