refactor(settings): changed config to settings and added in the update method for this as well
strict fields on the updates so we can only change what we want in here
This commit is contained in:
@@ -1,25 +1,21 @@
|
|||||||
package settings
|
package settings
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"lst.net/utils/db"
|
"lst.net/utils/db"
|
||||||
|
"lst.net/utils/inputs"
|
||||||
logging "lst.net/utils/logger"
|
logging "lst.net/utils/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SettingUpdateInput struct {
|
|
||||||
Description *string `json:"description"`
|
|
||||||
Value *string `json:"value"`
|
|
||||||
Enabled *bool `json:"enabled"`
|
|
||||||
AppService *string `json:"app_service"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterSettingsRoutes(l *gin.Engine, baseUrl string) {
|
func RegisterSettingsRoutes(l *gin.Engine, baseUrl string) {
|
||||||
// seed the db on start up
|
// seed the db on start up
|
||||||
db.SeedConfigs(db.DB)
|
db.SeedConfigs(db.DB)
|
||||||
|
|
||||||
s := l.Group(baseUrl + "/api/v1")
|
s := l.Group(baseUrl + "/api/v1")
|
||||||
s.GET("/settings", getSettings)
|
s.GET("/settings", getSettings)
|
||||||
s.PATCH("/settings", updateSettingById)
|
s.PATCH("/settings/:id", updateSettingById)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSettings(c *gin.Context) {
|
func getSettings(c *gin.Context) {
|
||||||
@@ -39,6 +35,7 @@ func getSettings(c *gin.Context) {
|
|||||||
"error": err,
|
"error": err,
|
||||||
})
|
})
|
||||||
c.JSON(500, gin.H{"message": "There was an error getting the settings", "error": err})
|
c.JSON(500, gin.H{"message": "There was an error getting the settings", "error": err})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(200, gin.H{"message": "Current settings", "data": configs})
|
c.JSON(200, gin.H{"message": "Current settings", "data": configs})
|
||||||
@@ -46,18 +43,44 @@ func getSettings(c *gin.Context) {
|
|||||||
|
|
||||||
func updateSettingById(c *gin.Context) {
|
func updateSettingById(c *gin.Context) {
|
||||||
logger := logging.New()
|
logger := logging.New()
|
||||||
var setting SettingUpdateInput
|
settingID := c.Param("id")
|
||||||
|
|
||||||
err := c.ShouldBindBodyWithJSON(&setting)
|
if settingID == "" {
|
||||||
|
c.JSON(500, gin.H{"message": "Invalid data"})
|
||||||
|
logger.Error("Invalid data", "system", map[string]interface{}{
|
||||||
|
"endpoint": "/api/v1/settings",
|
||||||
|
"client_ip": c.ClientIP(),
|
||||||
|
"user_agent": c.Request.UserAgent(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var setting inputs.SettingUpdateInput
|
||||||
|
|
||||||
if err != nil {
|
//err := c.ShouldBindBodyWithJSON(&setting)
|
||||||
c.JSON(500, gin.H{"message": "Internal Server Error"})
|
|
||||||
logger.Error("Current Settings", "system", map[string]interface{}{
|
decoder := json.NewDecoder(c.Request.Body) // more strict and will force us to have correct data
|
||||||
|
decoder.DisallowUnknownFields()
|
||||||
|
|
||||||
|
if err := decoder.Decode(&setting); err != nil {
|
||||||
|
c.JSON(400, gin.H{"message": "Invalid request body", "error": err.Error()})
|
||||||
|
logger.Error("Invalid request body", "system", map[string]interface{}{
|
||||||
"endpoint": "/api/v1/settings",
|
"endpoint": "/api/v1/settings",
|
||||||
"client_ip": c.ClientIP(),
|
"client_ip": c.ClientIP(),
|
||||||
"user_agent": c.Request.UserAgent(),
|
"user_agent": c.Request.UserAgent(),
|
||||||
"error": err,
|
"error": err,
|
||||||
})
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.UpdateConfig(db.DB, settingID, setting); err != nil {
|
||||||
|
c.JSON(500, gin.H{"message": "Failed to update setting", "error": err.Error()})
|
||||||
|
logger.Error("Failed to update setting", "system", map[string]interface{}{
|
||||||
|
"endpoint": "/api/v1/settings",
|
||||||
|
"client_ip": c.ClientIP(),
|
||||||
|
"user_agent": c.Request.UserAgent(),
|
||||||
|
"error": err,
|
||||||
|
})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(200, gin.H{"message": "Setting was just updated", "data": setting})
|
c.JSON(200, gin.H{"message": "Setting was just updated", "data": setting})
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ require (
|
|||||||
github.com/gorilla/websocket v1.5.3
|
github.com/gorilla/websocket v1.5.3
|
||||||
github.com/joho/godotenv v1.5.1
|
github.com/joho/godotenv v1.5.1
|
||||||
github.com/rs/zerolog v1.34.0
|
github.com/rs/zerolog v1.34.0
|
||||||
github.com/swaggo/swag v1.16.5
|
github.com/swaggo/swag v1.16.6
|
||||||
gorm.io/driver/postgres v1.6.0
|
gorm.io/driver/postgres v1.6.0
|
||||||
gorm.io/gorm v1.30.0
|
gorm.io/gorm v1.30.0
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import (
|
|||||||
"lst.net/cmd/services/system/settings"
|
"lst.net/cmd/services/system/settings"
|
||||||
"lst.net/cmd/services/websocket"
|
"lst.net/cmd/services/websocket"
|
||||||
|
|
||||||
_ "lst.net/docs"
|
// _ "lst.net/docs"
|
||||||
|
|
||||||
"lst.net/utils/db"
|
"lst.net/utils/db"
|
||||||
logging "lst.net/utils/logger"
|
logging "lst.net/utils/logger"
|
||||||
|
|||||||
@@ -2,14 +2,17 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"lst.net/utils/inputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
ConfigID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4();primaryKey" json:"id"`
|
SettingID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4();primaryKey" json:"id"`
|
||||||
Name string `gorm:"uniqueIndex;not null"`
|
Name string `gorm:"uniqueIndex;not null"`
|
||||||
Description string `gorm:"type:text"`
|
Description string `gorm:"type:text"`
|
||||||
Value string `gorm:"not null"`
|
Value string `gorm:"not null"`
|
||||||
@@ -89,11 +92,76 @@ func SeedConfigs(db *gorm.DB) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAllConfigs(db *gorm.DB) ([]Settings, error) {
|
func GetAllConfigs(db *gorm.DB) ([]map[string]interface{}, error) {
|
||||||
var settings []Settings
|
var settings []Settings
|
||||||
|
|
||||||
result := db.Find(&settings)
|
result := db.Find(&settings)
|
||||||
|
|
||||||
return settings, result.Error
|
if result.Error != nil {
|
||||||
|
return nil, result.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to convert struct to map with lowercase keys
|
||||||
|
toLowercase := func(s Settings) map[string]interface{} {
|
||||||
|
t := reflect.TypeOf(s)
|
||||||
|
v := reflect.ValueOf(s)
|
||||||
|
|
||||||
|
data := make(map[string]interface{})
|
||||||
|
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
field := strings.ToLower(t.Field(i).Name)
|
||||||
|
data[field] = v.Field(i).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert each struct in settings slice to a map with lowercase keys
|
||||||
|
var lowercaseSettings []map[string]interface{}
|
||||||
|
for _, setting := range settings {
|
||||||
|
lowercaseSettings = append(lowercaseSettings, toLowercase(setting))
|
||||||
|
}
|
||||||
|
|
||||||
|
return lowercaseSettings, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateConfig(db *gorm.DB, id string, input inputs.SettingUpdateInput) error {
|
||||||
|
var cfg Settings
|
||||||
|
if err := db.Where("setting_id =?", id).First(&cfg).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
updates := map[string]interface{}{}
|
||||||
|
|
||||||
|
if input.Description != nil {
|
||||||
|
updates["description"] = *input.Description
|
||||||
|
}
|
||||||
|
if input.Value != nil {
|
||||||
|
updates["value"] = *input.Value
|
||||||
|
}
|
||||||
|
if input.Enabled != nil {
|
||||||
|
updates["enabled"] = *input.Enabled
|
||||||
|
}
|
||||||
|
if input.AppService != nil {
|
||||||
|
updates["app_service"] = *input.AppService
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(updates) == 0 {
|
||||||
|
return nil // nothing to update
|
||||||
|
}
|
||||||
|
|
||||||
|
return db.Model(&cfg).Updates(updates).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteConfig(db *gorm.DB, id uint) error {
|
||||||
|
// Soft delete by ID
|
||||||
|
return db.Delete(&Settings{}, id).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func RestoreConfig(db *gorm.DB, id uint) error {
|
||||||
|
var cfg Settings
|
||||||
|
if err := db.Unscoped().First(&cfg, id).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cfg.DeletedAt = gorm.DeletedAt{}
|
||||||
|
return db.Unscoped().Save(&cfg).Error
|
||||||
}
|
}
|
||||||
|
|||||||
8
backend/utils/inputs/settingsInput.go
Normal file
8
backend/utils/inputs/settingsInput.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package inputs
|
||||||
|
|
||||||
|
type SettingUpdateInput struct {
|
||||||
|
Description *string `json:"description"`
|
||||||
|
Value *string `json:"value"`
|
||||||
|
Enabled *bool `json:"enabled"`
|
||||||
|
AppService *string `json:"app_service"`
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user