feat(taste): track_tags schema + enrichment queries (Opt 1 foundation)
First step of taste-profile fidelity via metadata enrichment (milestone #160, task #1490) — no ML sidecar, operator's constraint. The taste profile's tag facet is built purely from raw ID3 tracks.genre (splitGenres in internal/taste/profile.go). This lands the data layer for enriching it with track-level folksonomy tags: - track_tags(track_id, tag, weight) — a global cache of style/mood tags, top-K per track, weight = normalized folksonomy strength [0,1]. - tracks.tag_source / tag_sources_version — versioned enrichment bookkeeping mirroring artists.artist_art_source (NULL = eligible, provider name = found, 'none' = settled, version bump = re-process). - Queries: ListTracksMissingTags (batch drainer), DeleteTrackTags + InsertTrackTag (atomic per-track replace), SetTrackTagSource, and ListPlayed/LikedTrackTagsForUser for the recompute to union enriched tags into the tag facet alongside genre. No consumer yet — the enricher (MusicBrainz + Last.fm providers, track-level) and the taste-recompute integration land next. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
-- Reverse 0042_track_tags.up.sql.
|
||||
DROP INDEX IF EXISTS tracks_tag_source_idx;
|
||||
ALTER TABLE tracks DROP COLUMN IF EXISTS tag_sources_version;
|
||||
ALTER TABLE tracks DROP COLUMN IF EXISTS tag_source;
|
||||
DROP TABLE IF EXISTS track_tags;
|
||||
@@ -0,0 +1,26 @@
|
||||
-- Track-level folksonomy tags for taste enrichment (milestone #160, #1490).
|
||||
--
|
||||
-- A global (not per-user) cache of style/mood tags fetched from
|
||||
-- MusicBrainz (keyless) + Last.fm (when a key is configured), keyed by
|
||||
-- track. Feeds the taste recompute's tag facet alongside raw ID3 genre,
|
||||
-- lifting resolution from coarse "Rock" to "post-punk / shoegaze /
|
||||
-- melancholic". The enricher caps to the top-K tags per track at write
|
||||
-- time so a heavily-tagged track can't dominate the profile. weight is a
|
||||
-- normalized folksonomy strength in [0,1]. Mirrors the coverart
|
||||
-- enricher's versioned source-tracking pattern.
|
||||
CREATE TABLE track_tags (
|
||||
track_id uuid NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
|
||||
tag text NOT NULL,
|
||||
weight double precision NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (track_id, tag)
|
||||
);
|
||||
CREATE INDEX track_tags_track_idx ON track_tags (track_id);
|
||||
|
||||
-- Enrichment bookkeeping (mirror artists.artist_art_source):
|
||||
-- tag_source NULL → not yet processed (eligible)
|
||||
-- tag_source 'lastfm' / 'musicbrainz' / 'mixed' → found, cached
|
||||
-- tag_source 'none' → providers returned nothing
|
||||
-- tag_sources_version → bump to re-process none/stale
|
||||
ALTER TABLE tracks ADD COLUMN tag_source text;
|
||||
ALTER TABLE tracks ADD COLUMN tag_sources_version integer NOT NULL DEFAULT 0;
|
||||
CREATE INDEX tracks_tag_source_idx ON tracks (tag_source, tag_sources_version);
|
||||
Reference in New Issue
Block a user