yao/openapi/setting/preference.go
Max 01daa783e0 feat(chat): improve error handling for chat operations
- Added centralized error handling for "not found" scenarios in GetChat, UpdateChat, DeleteChat, and GetMessages functions, enhancing user feedback for missing resources.
- Introduced isNotFoundError and respondNotFound utility functions to streamline error responses across chat-related operations.
- Updated the setting package to include new endpoints for setup status and user preferences, improving API functionality and user experience.
2026-05-04 21:53:26 +08:00

92 lines
2.4 KiB
Go

package setting
import (
"encoding/json"
"net/http"
"github.com/gin-gonic/gin"
"github.com/yaoapp/yao/openapi/oauth/authorized"
oauthTypes "github.com/yaoapp/yao/openapi/oauth/types"
"github.com/yaoapp/yao/openapi/response"
"github.com/yaoapp/yao/setting"
)
const preferenceNS = "preference"
func preferenceScope(info *oauthTypes.AuthorizedInfo) setting.ScopeID {
return setting.ScopeID{Scope: setting.ScopeUser, UserID: info.UserID}
}
// handlePreferenceGet returns the current user's preference.
// GET /setting/preference
func handlePreferenceGet(c *gin.Context) {
info := authorized.GetInfo(c)
if setting.Global == nil {
response.RespondWithSuccess(c, http.StatusOK, PreferenceData{})
return
}
merged, _ := setting.Global.GetMerged(info.UserID, info.TeamID, preferenceNS)
data := preferenceFromMap(merged)
response.RespondWithSuccess(c, http.StatusOK, data)
}
// handlePreferenceUpdate partially updates the current user's preference.
// PUT /setting/preference
func handlePreferenceUpdate(c *gin.Context) {
info := authorized.GetInfo(c)
var body PreferenceData
if err := c.ShouldBindJSON(&body); err != nil {
respondError(c, http.StatusBadRequest, "invalid request body")
return
}
if setting.Global == nil {
respondError(c, http.StatusInternalServerError, "setting registry not initialized")
return
}
scope := preferenceScope(info)
existing, _ := setting.Global.Get(scope, preferenceNS)
m := make(map[string]interface{})
for k, v := range existing {
m[k] = v
}
// Marshal the body to a map so only non-nil fields are included
bodyBytes, _ := json.Marshal(body)
var bodyMap map[string]interface{}
json.Unmarshal(bodyBytes, &bodyMap)
for k, v := range bodyMap {
m[k] = v
}
if _, err := setting.Global.Set(scope, preferenceNS, m); err != nil {
respondError(c, http.StatusInternalServerError, err.Error())
return
}
merged, _ := setting.Global.GetMerged(info.UserID, info.TeamID, preferenceNS)
result := preferenceFromMap(merged)
response.RespondWithSuccess(c, http.StatusOK, result)
}
func preferenceFromMap(m map[string]interface{}) PreferenceData {
data := PreferenceData{}
if m == nil {
return data
}
if v, ok := m["email_notification"].(bool); ok {
data.EmailNotification = &v
}
if v, ok := m["banner_dismissed"].(bool); ok {
data.BannerDismissed = &v
}
if v, ok := m["onboarding_completed"].(bool); ok {
data.OnboardingCompleted = &v
}
return data
}