fix(backend): propagate user renames to artist and harden migration backfill
Code review of the Artist/ownership refactor surfaced three gaps: - SyncUser updated User.Name on every login but never the linked Artist row, so renames never reached track credits - defeating the point of centralizing names in Artist. - YouTubeTrackProvisioner looked up artists by ExternalId only when a browseId was known, so it could never reuse the ExternalId-less rows the migration backfilled from legacy Artist strings, creating duplicate Artist rows for the same person. It now adopts the backfilled row (assigning it the browseId) when one matches by normalized name. - AddArtistsAndTrackOwnership deduped legacy YouTube artist strings case-sensitively before hashing them into a case-insensitive unique index, and never guarded against local tracks with no UserHasTrack row - either would abort the migration on real data. Backfill now dedupes via DISTINCT ON over the normalized name and drops orphaned local tracks before the ownership check constraint is added.
This commit is contained in:
+12
-2
@@ -108,6 +108,11 @@ namespace Musify.Infrastructure.Persistence.Migrations
|
||||
WHERE t."Source" = 0 AND ut."TrackId" = t."Id";
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
DELETE FROM "Tracks" WHERE "Source" = 0 AND "OwnerUserId" IS NULL;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
INSERT INTO "Artists" ("Id", "Name", "NormalizedName", "UserId", "ExternalId", "CreatedAt", "UpdatedAt")
|
||||
@@ -120,7 +125,12 @@ namespace Musify.Infrastructure.Persistence.Migrations
|
||||
"""
|
||||
INSERT INTO "Artists" ("Id", "Name", "NormalizedName", "UserId", "ExternalId", "CreatedAt", "UpdatedAt")
|
||||
SELECT gen_random_uuid(), s."Artist", upper(s."Artist"), NULL, NULL, now(), now()
|
||||
FROM (SELECT DISTINCT "Artist" FROM "Tracks" WHERE "Source" = 1 AND "Artist" IS NOT NULL) s;
|
||||
FROM (
|
||||
SELECT DISTINCT ON (upper("Artist")) "Artist"
|
||||
FROM "Tracks"
|
||||
WHERE "Source" = 1 AND "Artist" IS NOT NULL
|
||||
ORDER BY upper("Artist"), "Artist"
|
||||
) s;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
@@ -135,7 +145,7 @@ namespace Musify.Infrastructure.Persistence.Migrations
|
||||
"""
|
||||
INSERT INTO "TrackArtist" ("TrackId", "ArtistId", "Position")
|
||||
SELECT t."Id", a."Id", 0 FROM "Tracks" t
|
||||
JOIN "Artists" a ON a."UserId" IS NULL AND a."ExternalId" IS NULL AND a."Name" = t."Artist"
|
||||
JOIN "Artists" a ON a."UserId" IS NULL AND a."ExternalId" IS NULL AND a."NormalizedName" = upper(t."Artist")
|
||||
WHERE t."Source" = 1 AND t."Artist" IS NOT NULL;
|
||||
""");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user