docs: query comments say what each query selects and why, not how it came to be (#6277)
Rewrites the internal/db/queries comments to rule 32 and regenerates dbq, whose doc comments and embedded SQL carry them. The bugs behind the tiered mixes, the md5 order seed, the score bands and the round-robin arms are restated as the constraint each one enforces; counts from one library and stale cross-references are gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
-- Candidate queries for the discovery system-playlist mixes
|
||||
-- (#419-423). Each returns (id, album_id, artist_id) rows; the Go
|
||||
--. Each returns (id, album_id, artist_id) rows; the Go
|
||||
-- producer caps + truncates and converts to rankedCandidate. Daily-
|
||||
-- deterministic md5(id||dateStr) ordering (where used) keeps a mix
|
||||
-- stable within a day while rotating across days; shuffle-on-play
|
||||
-- gives per-play variety on top.
|
||||
|
||||
-- name: ListDeepCutsTracks :many
|
||||
-- #419 Deep Cuts: low-play tracks (<=2 plays) from artists the user
|
||||
-- Deep Cuts: low-play tracks (<=2 plays) from artists the user
|
||||
-- has liked OR played heavily (>=5 non-skip plays across the artist).
|
||||
-- Tracks the user has skipped twice or more don't qualify (#1257):
|
||||
-- eligibility used to count only unskipped plays, so the most actively
|
||||
-- rejected tracks read as "barely heard" and kept being re-offered.
|
||||
-- Threshold 2 so a single accidental skip doesn't banish a track;
|
||||
-- passive-signal only (no dislike UI, rule #101).
|
||||
-- Tracks the user has skipped twice or more don't qualify: counting only
|
||||
-- unskipped plays would make the most actively rejected tracks read as
|
||||
-- "barely heard" and keep re-offering them. Threshold 2 so a single
|
||||
-- accidental skip doesn't banish a track; passive signal only (there is no
|
||||
-- dislike button).
|
||||
-- $1 user_id, $2 date string.
|
||||
WITH affinity_artists AS (
|
||||
SELECT artist_id FROM general_likes_artists WHERE user_id = $1
|
||||
@@ -40,7 +40,7 @@ SELECT t.id, t.album_id, t.artist_id
|
||||
JOIN affinity_artists aa ON aa.artist_id = t.artist_id
|
||||
LEFT JOIN play_counts pc ON pc.track_id = t.id
|
||||
LEFT JOIN skip_counts sc ON sc.track_id = t.id
|
||||
WHERE t.missing_since IS NULL -- #2523: never offer a file that is gone
|
||||
WHERE t.missing_since IS NULL -- never offer a file that is gone
|
||||
AND COALESCE(pc.c, 0) <= 2
|
||||
AND COALESCE(sc.c, 0) < 2
|
||||
AND NOT EXISTS (
|
||||
@@ -51,11 +51,10 @@ SELECT t.id, t.album_id, t.artist_id
|
||||
LIMIT 200;
|
||||
|
||||
-- name: ListRediscoverTracks :many
|
||||
-- #420 Rediscover: tracks the user played a lot but has drifted away
|
||||
-- from. One blended pool (issue #1246: the old two-tier UNION was
|
||||
-- all-or-nothing — a single ">=6 months cold" row suppressed the whole
|
||||
-- ">=30 days" tier, which is how a one-song playlist shipped; the 6mo
|
||||
-- tier was also a strict subset of the 30d tier). Eligibility is >=3
|
||||
-- Rediscover: tracks the user played a lot but has drifted away
|
||||
-- from. One blended pool, not a two-tier UNION: the ">=6 months cold" tier is
|
||||
-- a strict subset of the ">=30 days" one, and a UNION that let one row of it
|
||||
-- suppress the wider tier would ship a one-song playlist. Eligibility is >=3
|
||||
-- non-skip plays and >=30 days cold; the bar sits at 3 rather than 5
|
||||
-- so a weeks-old library still fields a pool — on young histories the
|
||||
-- >=5-play tracks are precisely the ones still in rotation. Ordering
|
||||
@@ -71,18 +70,18 @@ WITH stats AS (
|
||||
SELECT t.id, t.album_id, t.artist_id
|
||||
FROM tracks t
|
||||
JOIN stats s ON s.track_id = t.id
|
||||
WHERE t.missing_since IS NULL -- #2523: never offer a file that is gone
|
||||
WHERE t.missing_since IS NULL -- never offer a file that is gone
|
||||
AND s.c >= 3
|
||||
AND s.last_at <= now() - interval '30 days'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM quarantine q
|
||||
WHERE q.user_id = $1 AND q.track_id = t.id
|
||||
)
|
||||
-- Declined-resurfacing cooldown (#1258): a skip on a
|
||||
-- Declined-resurfacing cooldown: a skip on a
|
||||
-- rediscover-sourced play is the user explicitly saying "I've moved
|
||||
-- on" to the exact invitation this mix extends — such tracks sit
|
||||
-- out ~90 days instead of re-qualifying the next day. Passive
|
||||
-- signal only (rule #101).
|
||||
-- signal only.
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM play_events rp
|
||||
WHERE rp.user_id = $1
|
||||
@@ -97,14 +96,13 @@ SELECT t.id, t.album_id, t.artist_id
|
||||
LIMIT 200;
|
||||
|
||||
-- name: ListNewForYouTracks :many
|
||||
-- #421 New for you, tiered per project rule #131 (#1267). The old
|
||||
-- single hard rule (added <30d AND direct affinity) had two failure
|
||||
-- modes with one root: no notion of consumption — the album you
|
||||
-- devoured in week one crowded the mix for three more weeks, and
|
||||
-- after a quiet month nothing qualified at all.
|
||||
-- New for you, tiered so the mix degrades rather than vanishes. A
|
||||
-- single hard rule (added <30d AND direct affinity) has no notion of
|
||||
-- consumption: the album you devoured in week one would crowd the mix
|
||||
-- for three more weeks, and after a quiet month nothing would qualify.
|
||||
--
|
||||
-- "Consumed" = any track attempted for >=30s (the First Listens
|
||||
-- threshold, #1268): once you've meaningfully engaged, the album is
|
||||
-- threshold): once you've meaningfully engaged, the album is
|
||||
-- no longer news. Applies to every tier — played albums leave the
|
||||
-- mix the next build.
|
||||
--
|
||||
@@ -151,7 +149,7 @@ albums_tiered AS (
|
||||
SELECT t.id, t.album_id, t.artist_id, alt.tier::int AS tier
|
||||
FROM tracks t
|
||||
JOIN albums_tiered alt ON alt.album_id = t.album_id
|
||||
WHERE t.missing_since IS NULL -- #2523: never offer a file that is gone
|
||||
WHERE t.missing_since IS NULL -- never offer a file that is gone
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM quarantine q
|
||||
WHERE q.user_id = $1 AND q.track_id = t.id
|
||||
@@ -161,18 +159,18 @@ SELECT t.id, t.album_id, t.artist_id, alt.tier::int AS tier
|
||||
LIMIT 300;
|
||||
|
||||
-- name: ListOnThisDayTracks :many
|
||||
-- #422 On This Day: tracks the user played around this calendar date
|
||||
-- On This Day: tracks the user played around this calendar date
|
||||
-- (±10 day-of-year) in the past, excluding the very recent (>30 days
|
||||
-- ago) so it's nostalgic, not just "last week". Weighted by how much
|
||||
-- they were played in those windows. Floor relaxed from 60→30 days
|
||||
-- and window ±7→±10 so it surfaces on a months-old library instead
|
||||
-- of needing a full year of history; still skips cleanly (no rows →
|
||||
-- no playlist) when there's no qualifying history yet.
|
||||
-- Day-of-year distance is circular (#1256): plain ABS made Dec 28 vs
|
||||
-- Jan 3 read as 359 days apart, silently gutting the window for ~3
|
||||
-- weeks around every New Year — precisely when holiday nostalgia is
|
||||
-- the point. LEAST(d, 365-d) wraps the boundary; leap-year drift of
|
||||
-- ±1 is absorbed by the ±10 window. The build date ($2, already here
|
||||
-- they were played in those windows. The 30-day floor and ±10 window
|
||||
-- let it surface on a months-old library rather than needing a full
|
||||
-- year of history; it still skips cleanly (no rows → no playlist)
|
||||
-- when there's no qualifying history yet.
|
||||
-- Day-of-year distance is circular: plain ABS would read Dec 28 vs
|
||||
-- Jan 3 as 359 days apart, gutting the window for ~3 weeks around
|
||||
-- every New Year — precisely when holiday nostalgia is the point.
|
||||
-- LEAST(d, 365-d) wraps the boundary; leap-year drift of ±1 is absorbed
|
||||
-- by the ±10 window. The build date ($2, already here
|
||||
-- for the md5 rotation) anchors "today" instead of now() so the
|
||||
-- window is testable and consistent with the mix's daily determinism.
|
||||
-- $1 user_id, $2 date string.
|
||||
@@ -190,7 +188,7 @@ WITH windowed AS (
|
||||
SELECT t.id, t.album_id, t.artist_id
|
||||
FROM tracks t
|
||||
JOIN windowed w ON w.track_id = t.id
|
||||
WHERE t.missing_since IS NULL -- #2523: never offer a file that is gone
|
||||
WHERE t.missing_since IS NULL -- never offer a file that is gone
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM quarantine q
|
||||
WHERE q.user_id = $1 AND q.track_id = t.id
|
||||
@@ -199,11 +197,10 @@ SELECT t.id, t.album_id, t.artist_id
|
||||
LIMIT 200;
|
||||
|
||||
-- name: ListFirstListensTracks :many
|
||||
-- #423 First Listens: songs the user has never heard or even
|
||||
-- attempted. "Attempted" is track-level with a >=30s listen threshold
|
||||
-- (#1268, operator decision 2026-07-03) — the old version disqualified
|
||||
-- a whole album on ANY play_event, so a 2-second accidental brush
|
||||
-- banished it permanently.
|
||||
-- First Listens: songs the user has never heard or even
|
||||
-- attempted. "Attempted" is track-level with a >=30s listen threshold:
|
||||
-- disqualifying a whole album on ANY play_event would let a 2-second
|
||||
-- accidental brush banish it permanently.
|
||||
--
|
||||
-- tier 1 the exact desire: albums with ZERO attempted tracks
|
||||
-- tier 2 step back: barely-attempted albums (<=25% of tracks
|
||||
@@ -244,7 +241,7 @@ SELECT t.id, t.album_id, t.artist_id, alt.tier::int AS tier
|
||||
FROM tracks t
|
||||
JOIN albums al ON al.id = t.album_id
|
||||
JOIN albums_tiered alt ON alt.album_id = al.id
|
||||
WHERE t.missing_since IS NULL -- #2523: never offer a file that is gone
|
||||
WHERE t.missing_since IS NULL -- never offer a file that is gone
|
||||
AND alt.tier IS NOT NULL
|
||||
AND NOT EXISTS (SELECT 1 FROM attempted a WHERE a.track_id = t.id)
|
||||
AND NOT EXISTS (
|
||||
|
||||
Reference in New Issue
Block a user