Files
antidrift/internal/web/settings_handlers.go
T
2026-06-01 20:10:47 -04:00

62 lines
1.8 KiB
Go

package web
import (
"net/http"
"antidrift/internal/settings"
"github.com/gin-gonic/gin"
)
// SetSettings injects the persisted settings, their file path, and the applier
// closure (built by main, which owns adapter construction). Mirrors the
// controller's Set* injection so web never imports ai/tasks/knowledge.
func (s *Server) SetSettings(path string, current settings.Settings, apply func(settings.Settings) error) {
s.settingsMu.Lock()
s.settingsPath = path
s.settings = current
s.applyFn = apply
s.settingsMu.Unlock()
}
func (s *Server) handleGetSettings(c *gin.Context) {
s.settingsMu.Lock()
cur := s.settings
s.settingsMu.Unlock()
c.JSON(http.StatusOK, cur)
}
// handlePostSettings validates-and-applies atomically, then persists. The applier
// checks the backend before mutating any state, so an invalid backend yields 400
// with nothing saved and the prior wiring intact.
func (s *Server) handlePostSettings(c *gin.Context) {
var req settings.Settings
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid json"})
return
}
s.settingsMu.Lock()
apply := s.applyFn
path := s.settingsPath
s.settingsMu.Unlock()
if apply == nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "settings not wired"})
return
}
if err := apply(req); err != nil {
// Apply validates the backend before mutating anything, so any error
// (invalid backend or otherwise) means nothing changed; surface it as 400.
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := settings.Save(path, req); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
s.settingsMu.Lock()
s.settings = req
s.settingsMu.Unlock()
s.broadcast()
c.JSON(http.StatusOK, req)
}