feat: batch update config endpoint

This commit is contained in:
2026-03-22 12:16:40 +01:00
parent 7d470f3638
commit c9a32e8889
3 changed files with 114 additions and 0 deletions

View File

@@ -2,6 +2,7 @@ package controller
import (
"acc-server-manager/local/middleware"
"acc-server-manager/local/model"
"acc-server-manager/local/service"
"acc-server-manager/local/utl/common"
"acc-server-manager/local/utl/error_handler"
@@ -34,6 +35,7 @@ func NewConfigController(as *service.ConfigService, routeGroups *common.RouteGro
configGroup := routeGroups.Config
configGroup.Use(auth.Authenticate)
configGroup.Patch("/", ac.UpdateAllConfigs)
configGroup.Put("/:file", ac.UpdateConfig)
configGroup.Get("/:file", ac.GetConfig)
configGroup.Get("/", ac.GetConfigs)
@@ -41,6 +43,54 @@ func NewConfigController(as *service.ConfigService, routeGroups *common.RouteGro
return ac
}
// updateAllConfigs updates all configuration files
//
// @Summary Bulk update all server configuration files
// @Description Update multiple ACC server configuration files in one request. Null or omitted sections are skipped.
// @Tags Server Configuration
// @Accept json
// @Produce json
// @Param id path string true "Server ID (UUID format)"
// @Param restart query bool false "Restart the server after update"
// @Param override query bool false "Override instead of merging with existing config"
// @Param content body model.ConfigurationsUpdateRequest true "Configuration sections to update (null sections are skipped)"
// @Success 200 {array} model.Config "List of updated config audit records"
// @Failure 400 {object} error_handler.ErrorResponse "Invalid request or JSON format"
// @Failure 401 {object} error_handler.ErrorResponse "Unauthorized"
// @Failure 403 {object} error_handler.ErrorResponse "Insufficient permissions"
// @Failure 404 {object} error_handler.ErrorResponse "Server not found"
// @Failure 500 {object} error_handler.ErrorResponse "Internal server error"
// @Security BearerAuth
// @Router /server/{id}/config [patch]
func (ac *ConfigController) UpdateAllConfigs(c *fiber.Ctx) error {
restart := c.QueryBool("restart")
serverID := c.Params("id")
if _, err := uuid.Parse(serverID); err != nil {
return ac.errorHandler.HandleUUIDError(c, "server ID")
}
c.Locals("serverId", serverID)
var req model.ConfigurationsUpdateRequest
if err := c.BodyParser(&req); err != nil {
return ac.errorHandler.HandleParsingError(c, err)
}
configs, err := ac.service.UpdateAllConfigs(c, &req)
if err != nil {
return ac.errorHandler.HandleServiceError(c, err)
}
if restart {
if _, err := ac.apiService.ServiceControlRestartServer(c); err != nil {
logging.ErrorWithContext("CONFIG_RESTART", "Failed to restart server after bulk config update: %v", err)
}
}
return c.JSON(configs)
}
// updateConfig returns Config
//
// @Summary Update server configuration file

View File

@@ -40,6 +40,14 @@ type Configurations struct {
Settings ServerSettings `json:"settings"`
}
type ConfigurationsUpdateRequest struct {
Configuration *map[string]interface{} `json:"configuration"`
AssistRules *map[string]interface{} `json:"assistRules"`
Event *map[string]interface{} `json:"event"`
EventRules *map[string]interface{} `json:"eventRules"`
Settings *map[string]interface{} `json:"settings"`
}
type ServerSettings struct {
ServerName string `json:"serverName"`
AdminPassword string `json:"adminPassword"`

View File

@@ -91,6 +91,62 @@ func (as *ConfigService) SetServerService(serverService *ServerService) {
// context.Context: Application context
// Returns:
// string: Application version
func (as *ConfigService) UpdateAllConfigs(ctx *fiber.Ctx, req *model.ConfigurationsUpdateRequest) ([]*model.Config, error) {
serverID := ctx.Locals("serverId").(string)
override := ctx.QueryBool("override", false)
serverUUID, err := uuid.Parse(serverID)
if err != nil {
logging.Error("Invalid server ID format: %v", err)
return nil, fmt.Errorf("invalid server ID format")
}
server, err := as.serverRepository.GetByID(ctx.UserContext(), serverUUID)
if err != nil {
logging.Error("Server not found")
return nil, fmt.Errorf("server not found")
}
type configEntry struct {
fileName string
body *map[string]interface{}
}
entries := []configEntry{
{ConfigurationJson, req.Configuration},
{AssistRulesJson, req.AssistRules},
{EventJson, req.Event},
{EventRulesJson, req.EventRules},
{SettingsJson, req.Settings},
}
var results []*model.Config
for _, entry := range entries {
if entry.body == nil {
continue
}
oldDataUTF8, newData, err := as.updateConfigFiles(ctx.UserContext(), server, entry.fileName, entry.body, override)
if err != nil {
return nil, err
}
result := as.repository.UpdateConfig(ctx.UserContext(), &model.Config{
ServerID: serverUUID,
ConfigFile: entry.fileName,
OldConfig: string(oldDataUTF8),
NewConfig: string(newData),
ChangedAt: time.Now(),
})
results = append(results, result)
}
if len(results) > 0 {
as.configCache.InvalidateServerCache(serverID)
as.serverService.StartAccServerRuntime(server)
}
return results, nil
}
func (as *ConfigService) UpdateConfig(ctx *fiber.Ctx, body *map[string]interface{}) (*model.Config, error) {
serverID := ctx.Locals("serverId").(string)
configFile := ctx.Params("file")