126 lines
3.2 KiB
Go
126 lines
3.2 KiB
Go
package handlers
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
|
|
"git.gobha.me/xcaliber/chat-switchboard/database"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// GetModelPreferences returns the user's hidden model list.
|
|
// GET /api/v1/models/preferences
|
|
func GetModelPreferences(c *gin.Context) {
|
|
userID := getUserID(c)
|
|
|
|
rows, err := database.DB.Query(`
|
|
SELECT model_id, hidden FROM user_model_preferences
|
|
WHERE user_id = $1
|
|
`, userID)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to query preferences"})
|
|
return
|
|
}
|
|
defer rows.Close()
|
|
|
|
type pref struct {
|
|
ModelID string `json:"model_id"`
|
|
Hidden bool `json:"hidden"`
|
|
}
|
|
prefs := make([]pref, 0)
|
|
for rows.Next() {
|
|
var p pref
|
|
if err := rows.Scan(&p.ModelID, &p.Hidden); err != nil {
|
|
continue
|
|
}
|
|
prefs = append(prefs, p)
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"preferences": prefs})
|
|
}
|
|
|
|
// SetModelPreference sets hidden state for a single model.
|
|
// PUT /api/v1/models/preferences
|
|
func SetModelPreference(c *gin.Context) {
|
|
userID := getUserID(c)
|
|
|
|
var req struct {
|
|
ModelID string `json:"model_id" binding:"required"`
|
|
Hidden bool `json:"hidden"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
_, err := database.DB.Exec(`
|
|
INSERT INTO user_model_preferences (user_id, model_id, hidden, updated_at)
|
|
VALUES ($1, $2, $3, NOW())
|
|
ON CONFLICT (user_id, model_id)
|
|
DO UPDATE SET hidden = EXCLUDED.hidden, updated_at = NOW()
|
|
`, userID, req.ModelID, req.Hidden)
|
|
if err != nil {
|
|
log.Printf("[WARN] Failed to save model preference for user %s, model %s: %v", userID, req.ModelID, err)
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to save preference: " + err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"model_id": req.ModelID, "hidden": req.Hidden})
|
|
}
|
|
|
|
// BulkSetModelPreferences sets hidden state for multiple models at once.
|
|
// POST /api/v1/models/preferences/bulk
|
|
func BulkSetModelPreferences(c *gin.Context) {
|
|
userID := getUserID(c)
|
|
|
|
var req struct {
|
|
ModelIDs []string `json:"model_ids" binding:"required"`
|
|
Hidden bool `json:"hidden"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
if len(req.ModelIDs) == 0 {
|
|
c.JSON(http.StatusOK, gin.H{"updated": 0})
|
|
return
|
|
}
|
|
|
|
tx, err := database.DB.Begin()
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to begin transaction"})
|
|
return
|
|
}
|
|
defer tx.Rollback()
|
|
|
|
stmt, err := tx.Prepare(`
|
|
INSERT INTO user_model_preferences (user_id, model_id, hidden, updated_at)
|
|
VALUES ($1, $2, $3, NOW())
|
|
ON CONFLICT (user_id, model_id)
|
|
DO UPDATE SET hidden = EXCLUDED.hidden, updated_at = NOW()
|
|
`)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to prepare statement"})
|
|
return
|
|
}
|
|
defer stmt.Close()
|
|
|
|
updated := 0
|
|
for _, modelID := range req.ModelIDs {
|
|
if _, err := stmt.Exec(userID, modelID, req.Hidden); err != nil {
|
|
log.Printf("[WARN] Failed to save preference for model %s: %v", modelID, err)
|
|
continue
|
|
}
|
|
updated++
|
|
}
|
|
|
|
if err := tx.Commit(); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to commit"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"updated": updated})
|
|
}
|