Files
SLACK_COORD_RELATORIO/n8n/nodes/merge-context-hash.node.js
T
GustavoandClaude Sonnet 5 edecd271b9 fix(v2): fix missing transitive dependency (normalize.js) in 3 node drivers
Found while syncing this cycle's fixes to the live DEV workflow and
preparing Run A: tools/build-workflow.js's readLogicSource() only inlines
whatever a node's own `@requires` header lists -- it does not resolve
transitive dependencies. context.js started doing `require('./normalize')`
earlier this cycle, but the three node drivers that need normalizeTicket/
buildAiContextText (which call normalizeGlpiText internally) still only
declared `@requires context.js`, never `normalize.js` itself.

The result compiles fine (new Function(...) syntax-checks pass -- a
ReferenceError is a runtime error, not a syntax error) but would throw
"normalizeGlpiText is not defined" the moment any of these three nodes
actually ran:
- Code - Mesclar Contexto e Calcular Hash (merge-context-hash.node.js)
- Code - Normalizar Candidatos Base (normalize-candidates.node.js)
- Code - Preparar Prompt IA (prepare-ai-prompt.node.js)

This never surfaced in Run 1 (prior session) because normalize.js/the
descricao field didn't exist yet at that point, and it didn't surface in
this cycle's local test suite because node--test only exercises the pure
logic/*.js modules directly (with real requires), never the inlined,
concatenated jsCode a node actually runs in n8n.

Fixed by adding normalize.js explicitly to each of the three headers,
matching the codebase's existing convention for multi-file deps (e.g.
compute-score.node.js already lists `@requires cooldown.js score.js`
together instead of relying on any transitive resolution).

Added a regression test that scans every generated Code node for calls to
normalizeGlpiText/normalizeTicket/buildAiContextText and asserts the
normalizeGlpiText function definition is actually present in that same
inlined source -- would have caught this before it ever reached DEV.

102/102 tests passing (was 101/101 -- +1 new regression test).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 20:01:14 -03:00

29 lines
1.1 KiB
JavaScript

// @requires normalize.js context.js hash.js
const candidatosBase = $('Code - Normalizar Candidatos Base').all().map((item) => item.json);
const contextRows = $input.all().map((item) => item.json);
function groupBy(rows, key) {
const map = {};
for (const row of rows) {
const k = String(row[key]);
if (!map[k]) map[k] = [];
map[k].push(row);
}
return map;
}
const followupRows = contextRows.filter((row) => row.tipo === 'followup');
const taskRows = contextRows.filter((row) => row.tipo === 'task');
const followupsByTicket = groupBy(followupRows, 'tickets_id');
const tasksByTicket = groupBy(taskRows, 'tickets_id');
return candidatosBase.map((base) => {
const idKey = String(base.id);
const followups = (followupsByTicket[idKey] || []).map((f) => ({ id: f.id, date: f.date, texto: f.texto }));
const tasks = (tasksByTicket[idKey] || []).map((t) => ({ id: t.id, date: t.date, status: t.status, texto: t.texto }));
const ticket = normalizeTicket(base, { followups, tasks });
const contextHash = buildContextFingerprint(ticket);
return { json: { ticket, contextHash } };
});