Repository: answerdev/answer
File: internal/schema/siteinfo_schema.go (Go)

Code before:
func (p PrivilegeOptions) Choose(level PrivilegeLevel) (option *PrivilegeOption) {
	for _, op := range p {
		if op.Level == level {
			return op
		}
	}
	return nil
}

// GetPrivilegesConfigResp get privileges config response
type GetPrivilegesConfigResp struct {
	Options       []*PrivilegeOption `json:"options"`
	SelectedLevel PrivilegeLevel     `json:"selected_level"`
}

// PrivilegeOption privilege option
type PrivilegeOption struct {
	Level      PrivilegeLevel        `json:"level"`
	LevelDesc  string                `json:"level_desc"`
	Privileges []*constant.Privilege `validate:"dive" json:"privileges"`
}

// UpdatePrivilegesConfigReq update privileges config request
type UpdatePrivilegesConfigReq struct {
	Level  PrivilegeLevel   `validate:"required,min=1,max=3|eq=99" json:"level"`
	Custom *PrivilegeOption `validate:"required" json:"custom"`
}

var (
	DefaultPrivilegeOptions      PrivilegeOptions
	DefaultCustomPrivilegeOption *PrivilegeOption
	privilegeOptionsLevelMapping = map[string][]int{
		constant.RankQuestionAddKey:               {1, 1, 1},
		constant.RankAnswerAddKey:                 {1, 1, 1},
		constant.RankCommentAddKey:                {1, 1, 1},
		constant.RankReportAddKey:                 {1, 1, 1},
		constant.RankCommentVoteUpKey:             {1, 1, 1},
		constant.RankLinkUrlLimitKey:              {1, 10, 10},
		constant.RankQuestionVoteUpKey:            {1, 8, 15},
		constant.RankAnswerVoteUpKey:              {1, 8, 15},
		constant.RankQuestionVoteDownKey:          {125, 125, 125},
		constant.RankAnswerVoteDownKey:            {125, 125, 125},
		constant.RankInviteSomeoneToAnswerKey:     {1, 500, 1000},
		constant.RankTagAddKey:                    {1, 750, 1500},
		constant.RankTagEditKey:                   {1, 50, 100},
		constant.RankQuestionEditKey:              {1, 100, 200},
		constant.RankAnswerEditKey:                {1, 100, 200},
		constant.RankQuestionEditWithoutReviewKey: {1, 1000, 2000},
		constant.RankAnswerEditWithoutReviewKey:   {1, 1000, 2000},
		constant.RankQuestionAuditKey:             {1, 1000, 2000},
		constant.RankAnswerAuditKey:               {1, 1000, 2000},

Review comment (security):
Maybe we only need save the *privileges*. The `level` is on the top and the `level_desc` is a constant.
```
CustomPrivileges []*constant.Privilege `validate:"dive" json:"custom_privileges"`
```

Code after:
func (p PrivilegeOptions) Choose(level PrivilegeLevel) (option *PrivilegeOption) {
	for _, op := range p {
		if op.Level == level {
			return op
		}
	}
	return nil
}

// GetPrivilegesConfigResp get privileges config response
type GetPrivilegesConfigResp struct {
	Options       []*PrivilegeOption `json:"options"`
	SelectedLevel PrivilegeLevel     `json:"selected_level"`
}

// PrivilegeOption privilege option
type PrivilegeOption struct {
	Level      PrivilegeLevel        `json:"level"`
	LevelDesc  string                `json:"level_desc"`
	Privileges []*constant.Privilege `validate:"dive" json:"privileges"`
}

// UpdatePrivilegesConfigReq update privileges config request
type UpdatePrivilegesConfigReq struct {
	Level            PrivilegeLevel        `validate:"required,min=1,max=3|eq=99" json:"level"`
	CustomPrivileges []*constant.Privilege `validate:"dive" json:"custom_privileges"`
}

var (
	DefaultPrivilegeOptions      PrivilegeOptions
	DefaultCustomPrivilegeOption *PrivilegeOption
	privilegeOptionsLevelMapping = map[string][]int{
		constant.RankQuestionAddKey:               {1, 1, 1},
		constant.RankAnswerAddKey:                 {1, 1, 1},
		constant.RankCommentAddKey:                {1, 1, 1},
		constant.RankReportAddKey:                 {1, 1, 1},
		constant.RankCommentVoteUpKey:             {1, 1, 1},
		constant.RankLinkUrlLimitKey:              {1, 10, 10},
		constant.RankQuestionVoteUpKey:            {1, 8, 15},
		constant.RankAnswerVoteUpKey:              {1, 8, 15},
		constant.RankQuestionVoteDownKey:          {125, 125, 125},
		constant.RankAnswerVoteDownKey:            {125, 125, 125},
		constant.RankInviteSomeoneToAnswerKey:     {1, 500, 1000},
		constant.RankTagAddKey:                    {1, 750, 1500},
		constant.RankTagEditKey:                   {1, 50, 100},
		constant.RankQuestionEditKey:              {1, 100, 200},
		constant.RankAnswerEditKey:                {1, 100, 200},
		constant.RankQuestionEditWithoutReviewKey: {1, 1000, 2000},
		constant.RankAnswerEditWithoutReviewKey:   {1, 1000, 2000},
		constant.RankQuestionAuditKey:             {1, 1000, 2000},
		constant.RankAnswerAuditKey:               {1, 1000, 2000},