-- Add slug (public unique ID) to tracks ALTER TABLE tracks ADD COLUMN slug TEXT; -- Generate slugs for existing tracks UPDATE tracks SET slug = encode(gen_random_uuid()::text::bytea, 'hex') WHERE slug IS NULL; ALTER TABLE tracks ALTER COLUMN slug SET NOT NULL; CREATE UNIQUE INDEX idx_tracks_slug ON tracks (slug); -- Add slug to albums ALTER TABLE albums ADD COLUMN slug TEXT; UPDATE albums SET slug = encode(gen_random_uuid()::text::bytea, 'hex') WHERE slug IS NULL; ALTER TABLE albums ALTER COLUMN slug SET NOT NULL; CREATE UNIQUE INDEX idx_albums_slug ON albums (slug); -- Add slug to artists ALTER TABLE artists ADD COLUMN slug TEXT; UPDATE artists SET slug = encode(gen_random_uuid()::text::bytea, 'hex') WHERE slug IS NULL; ALTER TABLE artists ALTER COLUMN slug SET NOT NULL; CREATE UNIQUE INDEX idx_artists_slug ON artists (slug); -- Album artwork table CREATE TABLE album_images ( id BIGSERIAL PRIMARY KEY, album_id BIGINT NOT NULL REFERENCES albums(id) ON DELETE CASCADE, image_type TEXT NOT NULL DEFAULT 'cover', -- 'cover', 'back', 'booklet', 'other' file_path TEXT NOT NULL, -- relative path in storage file_hash TEXT NOT NULL, mime_type TEXT NOT NULL, width INT, height INT, file_size BIGINT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_album_images_album ON album_images (album_id); CREATE UNIQUE INDEX idx_album_images_hash ON album_images (file_hash);