refactor: centralize avatar URL generation and backfill existing users

This commit is contained in:
2026-05-28 12:18:03 +02:00
parent dd4c7f80f3
commit fe0de5a214
3 changed files with 60 additions and 2 deletions

View File

@@ -14,6 +14,7 @@ import (
"mal/internal/database"
"mal/internal/db"
"mal/internal/observability"
"mal/internal/users"
)
func main() {
@@ -91,7 +92,7 @@ func main() {
}
id := uuid.New().String()
avatarURL := fmt.Sprintf("https://api.dicebear.com/9.x/dylan/svg?seed=%s", username)
avatarURL := users.DefaultAvatarURL(username)
_, err = dbConn.Exec("INSERT INTO user (id, username, password_hash, avatar_url) VALUES (?, ?, ?, ?)", id, username, string(hash), avatarURL)
if err != nil {
observability.Error("cli_user_create_failed", "cmd/user", "", map[string]any{"username": username}, err)
@@ -117,7 +118,7 @@ func updateAvatars(dbConn *sql.DB) {
os.Exit(1)
}
avatarURL := fmt.Sprintf("https://api.dicebear.com/9.x/dylan/svg?seed=%s", username)
avatarURL := users.DefaultAvatarURL(username)
_, err := dbConn.Exec("UPDATE user SET avatar_url = ? WHERE id = ?", avatarURL, id)
if err != nil {
observability.Error("cli_user_avatar_update_failed", "cmd/user", "", map[string]any{"username": username}, err)

View File

@@ -0,0 +1,46 @@
package fixes
import (
"context"
"database/sql"
"fmt"
"mal/internal/users"
)
func init() {
Register(Fix{
ID: "20260528_backfill_avatar_url",
Apply: func(ctx context.Context, sqlDB *sql.DB) error {
rows, err := sqlDB.QueryContext(ctx, `SELECT id, username FROM user WHERE avatar_url = ''`)
if err != nil {
return err
}
defer func() { _ = rows.Close() }()
type userRow struct {
id string
username string
}
toUpdate := make([]userRow, 0, 64)
for rows.Next() {
var r userRow
if err := rows.Scan(&r.id, &r.username); err != nil {
return err
}
toUpdate = append(toUpdate, r)
}
if err := rows.Err(); err != nil {
return err
}
for _, u := range toUpdate {
avatarURL := users.DefaultAvatarURL(u.username)
if _, err := sqlDB.ExecContext(ctx, `UPDATE user SET avatar_url = ? WHERE id = ?`, avatarURL, u.id); err != nil {
return fmt.Errorf("update avatar_url for user %s: %w", u.id, err)
}
}
return nil
},
})
}

11
internal/users/avatar.go Normal file
View File

@@ -0,0 +1,11 @@
package users
import (
"net/url"
"strings"
)
func DefaultAvatarURL(username string) string {
seed := url.QueryEscape(strings.TrimSpace(username))
return "https://api.dicebear.com/9.x/dylan/svg?seed=" + seed
}