/** Informe de paridad tras migrar artistas, versiones y representaciones. */ import pg from 'pg'; const cliente = new pg.Client({ connectionString: process.env.DATABASE_URL, query_timeout: 30_000 }); await cliente.connect(); const { rows: [n] } = await cliente.query(` select (select count(*) from cancion where version_de_id is null)::int as canciones, (select count(*) from cancion where version_de_id is not null)::int as versiones, (select count(*) from cancion where codigo is null)::int as canciones_sin_codigo, (select count(*) from artista)::int as artistas, (select count(*) from cancion_persona where rol = 'interprete')::int as creditos_anteriores, (select count(*) from cancion_interprete)::int as creditos_nuevos, (select count(*) from cancion_audio where uso = 'master')::int as masters, (select count(*) from cancion_audio where uso = 'stream')::int as streams, (select count(*) from cancion c where c.estado = 'publicado' and not exists (select 1 from cancion_audio ca where ca.cancion_id = c.id and ca.uso = 'stream'))::int as publicadas_sin_stream `); const { rows: problemas } = await cliente.query(` select 'intérprete sin migrar' as tipo, c.slug as referencia from cancion_persona cp join cancion c on c.id = cp.cancion_id where cp.rol = 'interprete' and not exists (select 1 from cancion_interprete ci where ci.cancion_id = cp.cancion_id) union all select 'publicación sin intérpretes', slug from cancion c where c.estado = 'publicado' and not exists (select 1 from cancion_interprete ci where ci.cancion_id = c.id) union all select 'venta sin entrega MP3', slug from cancion c where c.estado = 'publicado' and c.ala_venta and not exists (select 1 from cancion_audio ca where ca.cancion_id = c.id and ca.uso in ('descarga','master') and ca.formato = 'mp3') union all select 'artista sin código', slug from artista where codigo is null or btrim(codigo) = '' union all select 'versión sin código', slug from cancion where version_de_id is not null and (version_codigo is null or btrim(version_codigo) = '') order by tipo, referencia `); console.table(n); if (problemas.length) console.table(problemas); await cliente.end(); if (problemas.length || n.canciones_sin_codigo || n.publicadas_sin_stream) { console.error('La migración todavía no cumple la paridad requerida.'); process.exit(1); } console.log('Dominio musical íntegro: códigos, créditos y streams completos.');