-- +goose Up CREATE TABLE metadata_lookup_cache ( cache_key text PRIMARY KEY, payload bytea NOT NULL, expires_at timestamptz NOT NULL ); CREATE INDEX metadata_lookup_cache_expiry ON metadata_lookup_cache(expires_at); CREATE TABLE upload_release_groups ( id uuid PRIMARY KEY, batch_id uuid NOT NULL REFERENCES upload_batches(id) ON DELETE CASCADE, grouping_key text NOT NULL, artist text NOT NULL DEFAULT '', album text NOT NULL DEFAULT '', cover_path text, UNIQUE(batch_id,grouping_key) ); ALTER TABLE upload_files ADD COLUMN release_group_id uuid REFERENCES upload_release_groups(id) ON DELETE SET NULL; CREATE INDEX upload_files_release_group ON upload_files(release_group_id); CREATE TABLE upload_release_jobs ( batch_id uuid NOT NULL REFERENCES upload_batches(id) ON DELETE CASCADE, group_key text NOT NULL DEFAULT '', state text NOT NULL DEFAULT 'queued' CHECK (state IN ('queued','searching','ready','not_found','needs_input','error')), request jsonb NOT NULL DEFAULT '{}', input_hash text NOT NULL DEFAULT '', candidates jsonb NOT NULL DEFAULT '[]', audio_results jsonb NOT NULL DEFAULT '[]', selected_release uuid, lease uuid, attempts int NOT NULL DEFAULT 0, updated_at timestamptz NOT NULL DEFAULT now(), PRIMARY KEY(batch_id,group_key) ); -- +goose StatementBegin CREATE FUNCTION queue_upload_release_lookup() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN IF NEW.status IN ('pending_review','import_failed','withdrawn') AND (OLD.status IS DISTINCT FROM NEW.status OR OLD.metadata IS DISTINCT FROM NEW.metadata OR OLD.tags IS DISTINCT FROM NEW.tags OR OLD.duration_ms IS DISTINCT FROM NEW.duration_ms) THEN INSERT INTO upload_release_jobs(batch_id,group_key) VALUES (NEW.batch_id,coalesce(NEW.release_group_id::text,'')) ON CONFLICT (batch_id,group_key) DO UPDATE SET state='queued', request='{}', audio_results='[]', lease=NULL, attempts=0, selected_release=NULL, updated_at=now(); END IF; RETURN NEW; END; $$; -- +goose StatementEnd CREATE TRIGGER upload_release_lookup_changed AFTER UPDATE OF status, metadata, tags, duration_ms ON upload_files FOR EACH ROW EXECUTE FUNCTION queue_upload_release_lookup(); INSERT INTO upload_release_jobs(batch_id) SELECT DISTINCT batch_id FROM upload_files WHERE status IN ('pending_review','import_failed'); -- +goose Down DROP TRIGGER upload_release_lookup_changed ON upload_files; DROP FUNCTION queue_upload_release_lookup(); DROP TABLE upload_release_jobs; ALTER TABLE upload_files DROP COLUMN release_group_id; DROP TABLE upload_release_groups; DROP TABLE metadata_lookup_cache;