buildDataQualityReview extracts an auditable record per INSUFFICIENT_CONTEXT ticket (ticket_id, title, ai_reason, context_size, has_description, followup_count, task_count, has_solution, last_interaction_at) -- not sent anywhere, just for calibration. Also tightened validateAiClassification to reject an empty/whitespace-only next_action (was previously accepted). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
47 lines
1.9 KiB
JavaScript
47 lines
1.9 KiB
JavaScript
const { test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const { buildDataQualityReview } = require('./dataQuality');
|
|
|
|
function scoredItem(overrides) {
|
|
return Object.assign({
|
|
ticket: {
|
|
id: 33492, titulo: 'Instalar novo servidor', descricao: 'Descricao do chamado',
|
|
followups: [{ id: 1, texto: 'ok' }], tasks: [], ultima_interacao_em: '2025-11-06 15:49:15',
|
|
},
|
|
aiClassification: { classification: 'INSUFFICIENT_CONTEXT', reason: 'Sem evidencia de proxima acao.' },
|
|
}, overrides);
|
|
}
|
|
|
|
test('inclui apenas chamados INSUFFICIENT_CONTEXT', () => {
|
|
const items = [
|
|
scoredItem({}),
|
|
scoredItem({ aiClassification: { classification: 'ACTIONABLE_NOW', reason: 'x' } }),
|
|
];
|
|
const review = buildDataQualityReview(items);
|
|
assert.equal(review.length, 1);
|
|
assert.equal(review[0].ticket_id, 33492);
|
|
});
|
|
|
|
test('registro traz os campos minimos pedidos para auditoria', () => {
|
|
const review = buildDataQualityReview([scoredItem({})]);
|
|
const entry = review[0];
|
|
assert.equal(entry.ticket_id, 33492);
|
|
assert.equal(entry.title, 'Instalar novo servidor');
|
|
assert.equal(entry.ai_reason, 'Sem evidencia de proxima acao.');
|
|
assert.equal(entry.has_description, true);
|
|
assert.equal(entry.followup_count, 1);
|
|
assert.equal(entry.task_count, 0);
|
|
assert.equal(entry.last_interaction_at, '2025-11-06 15:49:15');
|
|
assert.ok(typeof entry.context_size === 'number' && entry.context_size > 0);
|
|
});
|
|
|
|
test('has_description e false quando nao ha descricao real', () => {
|
|
const review = buildDataQualityReview([scoredItem({ ticket: { ...scoredItem({}).ticket, descricao: '' } })]);
|
|
assert.equal(review[0].has_description, false);
|
|
});
|
|
|
|
test('lista vazia quando nao ha nenhum INSUFFICIENT_CONTEXT', () => {
|
|
const items = [scoredItem({ aiClassification: { classification: 'ACTIONABLE_NOW', reason: 'x' } })];
|
|
assert.deepEqual(buildDataQualityReview(items), []);
|
|
});
|