chore: import coordenador (subtree)
git-subtree-dir: coordenador git-subtree-mainline:facbe2e340git-subtree-split:ce7af94d55
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
function selectTop(scored, topN, config) {
|
||||
const eligible = scored.filter((item) => !item.excludedFromTop10);
|
||||
const excluded = scored.filter((item) => item.excludedFromTop10);
|
||||
|
||||
// BUG REAL comprovado em execucao ao vivo (missao "correcao final", secao 14): Array.sort e
|
||||
// estavel, e muitos chamados empatam em score -- sem um criterio de desempate deterministico,
|
||||
// a ordem de chegada de $input.all() (que o n8n NAO garante entre branches paralelos --
|
||||
// cache/ia/fallback se juntam de novo antes daqui) decidia o desempate. Duas execucoes
|
||||
// seguidas com os MESMOS dados produziram Top10 DIFERENTES so por causa disso, gerando duas
|
||||
// mensagens reais distintas pro Slack no mesmo dia. ticket.id como criterio secundario
|
||||
// garante o mesmo resultado sempre que os scores forem os mesmos -- nao muda QUEM vence
|
||||
// (isso continua sendo so o score), so desempata de forma reproduzivel.
|
||||
const sorted = [...eligible].sort((a, b) => {
|
||||
if (b.score !== a.score) return b.score - a.score;
|
||||
return String(a.ticket.id).localeCompare(String(b.ticket.id));
|
||||
});
|
||||
|
||||
const groupCap = Math.max(1, Math.ceil(topN * 0.5));
|
||||
const groupCounts = {};
|
||||
const firstPass = [];
|
||||
const deferred = [];
|
||||
|
||||
for (const item of sorted) {
|
||||
const count = groupCounts[item.group] || 0;
|
||||
if (count < groupCap && firstPass.length < topN) {
|
||||
firstPass.push(item);
|
||||
groupCounts[item.group] = count + 1;
|
||||
} else {
|
||||
deferred.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
let selected = firstPass;
|
||||
if (selected.length < topN) {
|
||||
selected = selected.concat(deferred.slice(0, topN - selected.length));
|
||||
}
|
||||
selected = selected.slice(0, topN);
|
||||
|
||||
const selectedIds = new Set(selected.map((item) => item.ticket.id));
|
||||
const notSelected = sorted.filter((item) => !selectedIds.has(item.ticket.id));
|
||||
|
||||
return { selected, excluded: excluded.concat(notSelected) };
|
||||
}
|
||||
|
||||
module.exports = { selectTop };
|
||||
Reference in New Issue
Block a user