From 3266093248bf3e6f5f670ce0327a645d6b61a68f Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Mon, 9 Feb 2026 20:10:06 -0500 Subject: [PATCH] feat(handlers): add system-wide scan settings handler Create new SystemSettingsHandler for managing system-wide scan settings: - GetScanSettings: retrieve scan frequency and auto-scan status - UpdateScanSettings: update scan settings (15-1440 minutes range) - Admin-only access (no user-specific data) - Key-value based storage instead of per-user settings Replaces per-user scan settings with centralized system configuration. This handler is used by /api/libraries/scan-settings endpoints. --- internal/handlers/system_settings.go | 111 +++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 internal/handlers/system_settings.go diff --git a/internal/handlers/system_settings.go b/internal/handlers/system_settings.go new file mode 100644 index 0000000..1c38753 --- /dev/null +++ b/internal/handlers/system_settings.go @@ -0,0 +1,111 @@ +package handlers + +import ( + "bookhoard/internal/database" + "net/http" + "strconv" + + "github.com/jackc/pgx/v5" + "github.com/labstack/echo/v4" +) + +type SystemSettingsHandler struct { + db *database.Queries +} + +func NewSystemSettingsHandler(db *database.Queries) *SystemSettingsHandler { + return &SystemSettingsHandler{ + db: db, + } +} + +type UpdateScanSettingsRequest struct { + ScanFrequencyMinutes int32 `json:"scan_frequency_minutes" validate:"required,min=15,max=1440"` + AutoScanEnabled bool `json:"auto_scan_enabled"` +} + +type ScanSettingsResponse struct { + ScanFrequencyMinutes int32 `json:"scan_frequency_minutes"` + AutoScanEnabled bool `json:"auto_scan_enabled"` + Message string `json:"message,omitempty"` +} + +func (h *SystemSettingsHandler) UpdateScanSettings(c echo.Context) error { + var req UpdateScanSettingsRequest + if err := c.Bind(&req); err != nil { + return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid request"}) + } + if err := c.Validate(&req); err != nil { + return c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()}) + } + + scanFrequencyValue := strconv.FormatInt(int64(req.ScanFrequencyMinutes), 10) + autoScanValue := strconv.FormatBool(req.AutoScanEnabled) + + err := h.db.UpdateSystemSetting(c.Request().Context(), database.UpdateSystemSettingParams{ + SettingKey: "scan_frequency_minutes", + SettingValue: scanFrequencyValue, + }) + if err != nil { + if err == pgx.ErrNoRows { + return c.JSON(http.StatusNotFound, map[string]string{"error": "system setting not found"}) + } + return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) + } + + err = h.db.UpdateSystemSetting(c.Request().Context(), database.UpdateSystemSettingParams{ + SettingKey: "auto_scan_enabled", + SettingValue: autoScanValue, + }) + if err != nil { + if err == pgx.ErrNoRows { + return c.JSON(http.StatusNotFound, map[string]string{"error": "system setting not found"}) + } + return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) + } + + return c.JSON(http.StatusOK, ScanSettingsResponse{ + ScanFrequencyMinutes: req.ScanFrequencyMinutes, + AutoScanEnabled: req.AutoScanEnabled, + Message: "scan settings updated successfully", + }) +} + +func (h *SystemSettingsHandler) GetScanSettings(c echo.Context) error { + scanFrequencySetting, err := h.db.GetSystemSetting(c.Request().Context(), "scan_frequency_minutes") + if err != nil { + if err == pgx.ErrNoRows { + return c.JSON(http.StatusOK, ScanSettingsResponse{ + ScanFrequencyMinutes: 60, + AutoScanEnabled: true, + }) + } + return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) + } + + autoScanSetting, err := h.db.GetSystemSetting(c.Request().Context(), "auto_scan_enabled") + if err != nil { + if err == pgx.ErrNoRows { + return c.JSON(http.StatusOK, ScanSettingsResponse{ + ScanFrequencyMinutes: 60, + AutoScanEnabled: true, + }) + } + return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) + } + + scanFrequency, err := strconv.ParseInt(scanFrequencySetting, 10, 32) + if err != nil { + return c.JSON(http.StatusInternalServerError, map[string]string{"error": "invalid scan frequency setting"}) + } + + autoScanEnabled, err := strconv.ParseBool(autoScanSetting) + if err != nil { + return c.JSON(http.StatusInternalServerError, map[string]string{"error": "invalid auto scan setting"}) + } + + return c.JSON(http.StatusOK, ScanSettingsResponse{ + ScanFrequencyMinutes: int32(scanFrequency), + AutoScanEnabled: autoScanEnabled, + }) +}