feat: complete filter centralization pattern and document in CLAUDE.md

This commit is contained in:
2026-07-26 13:03:37 +03:00
parent f697ebf2f5
commit aec9d89435
7 changed files with 267 additions and 13 deletions

View File

@@ -70,7 +70,7 @@ func SaveArtistSettings(db *DB, settings *ArtistSettings) error {
monitored = excluded.monitored,
last_synced = COALESCE(excluded.last_synced, artist_settings.last_synced)
`,
settings.ID, settings.Name, nullIfEmpty(settings.MBID), settings.IgnoreSingles, settings.IgnoreCompilations, settings.Monitored, settings.ID,
settings.ID, settings.Name, nullIfEmpty(settings.MBID), settings.IgnoreSingles, settings.IgnoreCompilations, settings.Monitored, nullIfEmptyTime(settings.LastSynced),
)
if err != nil {
return fmt.Errorf("save artist settings: %w", err)

View File

@@ -3,6 +3,7 @@ package database
import (
"database/sql"
"testing"
"time"
)
// TestGetArtistSettings_Found verifies retrieving an existing artist.
@@ -460,3 +461,134 @@ func TestArtistSettings_MbidInGetAll(t *testing.T) {
t.Errorf("artist a2: expected empty MBID, got %q", byID["a2"].MBID)
}
}
// TestSaveArtistSettings_LastSyncedPreserved verifies that last_synced is preserved
// on update when not explicitly provided in the update.
func TestSaveArtistSettings_LastSyncedPreserved(t *testing.T) {
db, err := New(":memory:")
if err != nil {
t.Fatalf("New() error: %v", err)
}
defer db.Close()
// Set a fixed time for testing
fixedTime := time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)
// Insert initial row with a specific last_synced time
s1 := &ArtistSettings{
ID: "artist-1",
Name: "Original Name",
IgnoreSingles: false,
IgnoreCompilations: false,
Monitored: true,
LastSynced: fixedTime,
}
if err := SaveArtistSettings(db, s1); err != nil {
t.Fatalf("first SaveArtistSettings() error: %v", err)
}
// Verify it was inserted with correct last_synced
got, err := GetArtistSettings(db, "artist-1")
if err != nil {
t.Fatalf("GetArtistSettings() error: %v", err)
}
if got.LastSynced != fixedTime {
t.Fatalf("expected last_synced %v, got %v", fixedTime, got.LastSynced)
}
// Update the row with new values but without specifying last_synced
// This should preserve the original last_synced value
s2 := &ArtistSettings{
ID: "artist-1",
Name: "Updated Name",
IgnoreSingles: true,
IgnoreCompilations: true,
Monitored: false,
// Note: LastSynced is intentionally left as zero value
}
if err := SaveArtistSettings(db, s2); err != nil {
t.Fatalf("second SaveArtistSettings() error: %v", err)
}
got, err = GetArtistSettings(db, "artist-1")
if err != nil {
t.Fatalf("GetArtistSettings() error: %v", err)
}
if got.Name != "Updated Name" {
t.Errorf("expected Name 'Updated Name', got %q", got.Name)
}
if !got.IgnoreSingles {
t.Error("expected IgnoreSingles true")
}
if !got.IgnoreCompilations {
t.Error("expected IgnoreCompilations true")
}
if got.Monitored {
t.Error("expected Monitored false")
}
// Most importantly: last_synced should be preserved
if got.LastSynced != fixedTime {
t.Errorf("expected last_synced to be preserved as %v, got %v", fixedTime, got.LastSynced)
}
}
// TestSaveArtistSettings_LastSyncedUpdated verifies that last_synced can be updated
// when explicitly provided.
func TestSaveArtistSettings_LastSyncedUpdated(t *testing.T) {
db, err := New(":memory:")
if err != nil {
t.Fatalf("New() error: %v", err)
}
defer db.Close()
// Set fixed times for testing
oldTime := time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)
newTime := time.Date(2023, 12, 31, 23, 59, 59, 0, time.UTC)
// Insert initial row
s1 := &ArtistSettings{
ID: "artist-1",
Name: "Original Name",
IgnoreSingles: false,
IgnoreCompilations: false,
Monitored: true,
LastSynced: oldTime,
}
if err := SaveArtistSettings(db, s1); err != nil {
t.Fatalf("first SaveArtistSettings() error: %v", err)
}
// Update the row with a new last_synced time
s2 := &ArtistSettings{
ID: "artist-1",
Name: "Updated Name",
IgnoreSingles: true,
IgnoreCompilations: true,
Monitored: false,
LastSynced: newTime,
}
if err := SaveArtistSettings(db, s2); err != nil {
t.Fatalf("second SaveArtistSettings() error: %v", err)
}
got, err := GetArtistSettings(db, "artist-1")
if err != nil {
t.Fatalf("GetArtistSettings() error: %v", err)
}
if got.Name != "Updated Name" {
t.Errorf("expected Name 'Updated Name', got %q", got.Name)
}
if !got.IgnoreSingles {
t.Error("expected IgnoreSingles true")
}
if !got.IgnoreCompilations {
t.Error("expected IgnoreCompilations true")
}
if got.Monitored {
t.Error("expected Monitored false")
}
// last_synced should be updated to the new value
if got.LastSynced != newTime {
t.Errorf("expected last_synced to be updated to %v, got %v", newTime, got.LastSynced)
}
}