Changeset 0.29.0 (#195)

This commit is contained in:
2026-03-17 16:28:47 +00:00
parent 128cbb8174
commit 5d637d3a90
129 changed files with 9418 additions and 3016 deletions

View File

@@ -15,7 +15,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
)
const avatarSize = 128
@@ -76,10 +77,7 @@ func (h *SettingsHandler) UploadAvatar(c *gin.Context) {
dataURI := "data:image/png;base64," + base64.StdEncoding.EncodeToString(buf.Bytes())
// Store in DB
_, err = database.DB.Exec(
database.Q(`UPDATE users SET avatar_url = $1, updated_at = NOW() WHERE id = $2`),
dataURI, userID,
)
err = h.stores.Users.Update(c.Request.Context(), userID, map[string]interface{}{"avatar_url": dataURI})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to save avatar"})
return
@@ -93,10 +91,7 @@ func (h *SettingsHandler) UploadAvatar(c *gin.Context) {
func (h *SettingsHandler) DeleteAvatar(c *gin.Context) {
userID := getUserID(c)
_, err := database.DB.Exec(
database.Q(`UPDATE users SET avatar_url = NULL, updated_at = NOW() WHERE id = $1`),
userID,
)
err := h.stores.Users.Update(c.Request.Context(), userID, map[string]interface{}{"avatar_url": nil})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to remove avatar"})
return
@@ -166,7 +161,9 @@ func bilinearMix(c00, c10, c01, c11 color.Color, xf, yf float64) color.Color {
// ── Persona Avatar Upload ────────────────────
// POST /api/v1/personas/:id/avatar (user) or /api/v1/admin/personas/:id/avatar (admin)
func UploadPersonaAvatar(c *gin.Context) {
// UploadPersonaAvatar uploads and resizes a persona avatar.
// v0.29.0: accepts PersonaStore instead of using database.DB directly.
func UploadPersonaAvatar(personas store.PersonaStore, c *gin.Context) {
personaID := c.Param("id")
var req uploadAvatarRequest
@@ -206,40 +203,26 @@ func UploadPersonaAvatar(c *gin.Context) {
dataURI := "data:image/png;base64," + base64.StdEncoding.EncodeToString(buf.Bytes())
result, err := database.DB.Exec(
database.Q(`UPDATE personas SET avatar = $1, updated_at = NOW() WHERE id = $2`),
dataURI, personaID,
)
err = personas.Update(c.Request.Context(), personaID, models.PersonaPatch{Avatar: &dataURI})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to save avatar"})
return
}
rows, _ := result.RowsAffected()
if rows == 0 {
c.JSON(http.StatusNotFound, gin.H{"error": "persona not found"})
return
}
c.JSON(http.StatusOK, gin.H{"avatar": dataURI})
}
// DeletePersonaAvatar clears a persona's avatar.
func DeletePersonaAvatar(c *gin.Context) {
// v0.29.0: accepts PersonaStore instead of using database.DB directly.
func DeletePersonaAvatar(personas store.PersonaStore, c *gin.Context) {
personaID := c.Param("id")
result, err := database.DB.Exec(
database.Q(`UPDATE personas SET avatar = '', updated_at = NOW() WHERE id = $1`),
personaID,
)
empty := ""
err := personas.Update(c.Request.Context(), personaID, models.PersonaPatch{Avatar: &empty})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to remove avatar"})
return
}
rows, _ := result.RowsAffected()
if rows == 0 {
c.JSON(http.StatusNotFound, gin.H{"error": "persona not found"})
return
}
c.JSON(http.StatusOK, gin.H{"message": "avatar removed"})
}