From aefe92c02e81a61aaf63cea2f94d5b1782996561 Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 13 Aug 2026 12:26:05 -0700 Subject: [PATCH] fix(genesis-writer): emit release_date as RFC3339, not Postgres text The tracks query selected release_date::text, which yields Postgres's own "2026-09-06 22:06:00". The indexer's parseReleaseDate accepts RFC3339, RFC3339Nano and "Mon Jan 02 2006 15:04:05 GMT-0700" -- none of which match -- so releaseDateOrDefault silently fell back to block time, i.e. the source row's created_at. That is not a cosmetic date difference. A track whose release_date lands in the past is then picked up by ScheduledReleasePublisher, which sets is_unlisted = false and updated_at = now(). Measured on the 2026-08-07 snapshot: 372 unlisted tracks with a future release_date had the date rewritten 368 of them were published early 498 -> 136 tracks still holding a future release_date Verified end to end on track 2073330890: source release_date 2026-09-06 22:06:00 and is_unlisted true, the transaction carried both correctly, and the indexed row came out release_date 2025-08-10 20:57:26 (exactly its created_at) with is_unlisted false. Every other timestamp the writer emits already goes out as RFC3339; this one was the outlier. --- cmd/genesis-writer/entities_track.go | 21 ++++++++++-- .../release_date_format_test.go | 32 +++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 cmd/genesis-writer/release_date_format_test.go diff --git a/cmd/genesis-writer/entities_track.go b/cmd/genesis-writer/entities_track.go index 2ab90525..4ea15927 100644 --- a/cmd/genesis-writer/entities_track.go +++ b/cmd/genesis-writer/entities_track.go @@ -94,7 +94,7 @@ type sourceTrack struct { IsUnlisted bool IsDownloadable bool IsOriginalAvailable bool - ReleaseDate *string + ReleaseDate *time.Time License *string ISRC *string ISWC *string @@ -157,7 +157,7 @@ func buildTrackMetadata(t sourceTrack, collaborators []int64) trackMetadataInner IsUnlisted: t.IsUnlisted, IsDownloadable: t.IsDownloadable, IsOriginalAvail: t.IsOriginalAvailable, - ReleaseDate: deref(t.ReleaseDate), + ReleaseDate: fmtReleaseDate(t.ReleaseDate), License: deref(t.License), ISRC: deref(t.ISRC), ISWC: deref(t.ISWC), @@ -211,6 +211,21 @@ func buildTrackMetadata(t sourceTrack, collaborators []int64) trackMetadataInner return inner } +// fmtReleaseDate emits RFC3339, the format the indexer's parseReleaseDate +// accepts. Selecting release_date::text instead yields Postgres's own +// "2026-09-06 22:06:00", which matches none of the accepted layouts, so the +// indexer silently fell back to block time. That is not a cosmetic date +// difference: a track whose release_date lands in the past is picked up by the +// scheduled-release publisher, which sets is_unlisted = false. On the +// 2026-08-07 snapshot 372 unlisted tracks with a future release date had the +// date rewritten and 368 of them were published early. +func fmtReleaseDate(t *time.Time) string { + if t == nil { + return "" + } + return t.UTC().Format(time.RFC3339) +} + func (w *Writer) writeTracks(ctx context.Context) error { // Pre-load collaborator lists so Track:Create metadata includes them, // which causes the ETL to create pending invites automatically. @@ -231,7 +246,7 @@ func (w *Writer) writeTracks(ctx context.Context) error { t.track_cid, t.cover_art, t.cover_art_sizes, t.preview_cid, t.is_unlisted, t.is_downloadable, t.is_original_available, - t.release_date::text, t.license, t.isrc, t.iswc, t.bpm, t.musical_key, + t.release_date, t.license, t.isrc, t.iswc, t.bpm, t.musical_key, t.is_custom_bpm, t.is_custom_musical_key, t.remix_of, t.stem_of, t.is_stream_gated, t.stream_conditions, diff --git a/cmd/genesis-writer/release_date_format_test.go b/cmd/genesis-writer/release_date_format_test.go new file mode 100644 index 00000000..1977fa10 --- /dev/null +++ b/cmd/genesis-writer/release_date_format_test.go @@ -0,0 +1,32 @@ +package main + +import ( + "testing" + "time" +) + +// The indexer's parseReleaseDate accepts RFC3339, RFC3339Nano and +// "Mon Jan 02 2006 15:04:05 GMT-0700" -- and nothing else. Selecting +// release_date::text yields Postgres's "2026-09-06 22:06:00", which matches +// none of them, so the indexer silently fell back to block time. A future +// release date rewritten into the past is then picked up by the +// scheduled-release publisher, which sets is_unlisted = false: on the +// 2026-08-07 snapshot that rewrote 372 dates and published 368 unlisted +// tracks early. +func TestReleaseDateIsEmittedInAnAcceptedLayout(t *testing.T) { + rd := time.Date(2026, 9, 6, 22, 6, 0, 0, time.UTC) + got := fmtReleaseDate(&rd) + + if _, err := time.Parse(time.RFC3339, got); err != nil { + t.Fatalf("fmtReleaseDate produced %q, which the indexer cannot parse: %v", got, err) + } + if got != "2026-09-06T22:06:00Z" { + t.Errorf("fmtReleaseDate = %q, want %q", got, "2026-09-06T22:06:00Z") + } + if got == "2026-09-06 22:06:00" { + t.Error("emitted Postgres text format, which no accepted layout matches") + } + if fmtReleaseDate(nil) != "" { + t.Errorf("nil release_date = %q, want empty so omitempty drops it", fmtReleaseDate(nil)) + } +}