Fallback (ai_disabled, ai_error, invalid_json, ai_max_candidates_cap -- any candidate the AI never actually analyzed) now produces classification 'AI_FALLBACK', an explicit technical state that is never part of the 11-class enum sent to OpenAI (the AI itself can never legitimately return it). Previously it silently claimed ACTIONABLE_NOW with confidence 0, which made unanalyzed tickets indistinguishable from genuinely confirmed ones at the classification-label level. Also normalizes blocker_type/waiting_for when the model returns the literal string "null"/"none"/"n/a"/"" instead of JSON null -- done once, in the validation layer (logic/classification.js), not scattered around the workflow. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
25 lines
1.1 KiB
JavaScript
25 lines
1.1 KiB
JavaScript
const { test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
test('SQL de candidatos V2 preserva a exclusao administrativa do V1', () => {
|
|
const sql = fs.readFileSync(path.join(__dirname, '..', '..', 'sql', 'candidatos_v2_glpi.sql'), 'utf8');
|
|
assert.ok(sql.includes("NOT LIKE 'ADMINISTRATIVO%'"));
|
|
assert.ok(sql.includes("NOT LIKE 'DESENVOLVIMENTO%'"));
|
|
assert.ok(sql.includes("NOT LIKE 'INFRA%'"));
|
|
assert.ok(sql.includes('is_deleted = false'));
|
|
assert.ok(sql.includes('status NOT IN (5, 6)'));
|
|
});
|
|
|
|
test('SQL de candidatos V2 NAO tem mais LIMIT fixo em 10 (funil maior)', () => {
|
|
const sql = fs.readFileSync(path.join(__dirname, '..', '..', 'sql', 'candidatos_v2_glpi.sql'), 'utf8');
|
|
assert.ok(sql.includes('LIMIT {CANDIDATE_POOL_SIZE}'));
|
|
assert.ok(!sql.includes('LIMIT 10'));
|
|
});
|
|
|
|
test('SQL de candidatos V2 traz a descricao real do chamado (t.content) para a IA', () => {
|
|
const sql = fs.readFileSync(path.join(__dirname, '..', '..', 'sql', 'candidatos_v2_glpi.sql'), 'utf8');
|
|
assert.ok(sql.includes('t.content AS descricao'));
|
|
});
|