Commit inicial: GTI Maquina Comercial
App local (Node + SQLite) para captura, tratamento e exportacao de leads comerciais, com dashboard de gestao, login/usuarios e integracao Z-PRO. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { openDb, createLeadInserter, transaction, getSetting, setSetting, seedSegments, seedMunicipios, seedGeoCache, seedSettings } from '../src/db.mjs';
|
||||
|
||||
function sampleLead(overrides = {}) {
|
||||
return {
|
||||
lead_uid: 'GTI-TEST-1',
|
||||
dedup_key: 'cnpj:57557263000113',
|
||||
empresa: 'PREMIUM EXPRESS',
|
||||
legal_name: 'PREMIUM EXPRESS LTDA',
|
||||
whatsapp: '557193335451',
|
||||
ddd: '71',
|
||||
email: '',
|
||||
cidade: 'Salvador',
|
||||
uf: 'BA',
|
||||
segmento: 'restaurantes',
|
||||
segmento_label: 'Restaurantes',
|
||||
interesse: 'Autoatendimento para WhatsApp',
|
||||
cnpj: '57557263000113',
|
||||
cnae: '5611203',
|
||||
endereco: 'RUA X, 1',
|
||||
website: '',
|
||||
pains_json: '["atendimento"]',
|
||||
origem: 'cnpj-base',
|
||||
telefone_valido: 1,
|
||||
cnpj_valido: 1,
|
||||
empresa_valida: 1,
|
||||
score: 100,
|
||||
classificacao: 'bom',
|
||||
motivo_classificacao: 'ok',
|
||||
capture_run_id: null,
|
||||
captured_at: '2026-07-09T14:26:18.560Z',
|
||||
exported_at: null,
|
||||
...overrides
|
||||
};
|
||||
}
|
||||
|
||||
test('openDb cria esquema e aplica migrations uma unica vez', () => {
|
||||
const db = openDb(':memory:');
|
||||
const version = db.prepare('SELECT MAX(version) AS v FROM schema_migrations').get().v;
|
||||
assert.ok(version >= 1);
|
||||
const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table'").all().map((r) => r.name);
|
||||
for (const table of ['leads', 'capture_runs', 'extractions', 'exports', 'export_leads', 'segments', 'municipios', 'geo_cache', 'settings']) {
|
||||
assert.ok(tables.includes(table), `tabela ${table} ausente`);
|
||||
}
|
||||
db.close();
|
||||
});
|
||||
|
||||
test('createLeadInserter insere e ignora duplicata pela dedup_key', () => {
|
||||
const db = openDb(':memory:');
|
||||
const insert = createLeadInserter(db);
|
||||
|
||||
assert.equal(insert(sampleLead()), 'inserted');
|
||||
assert.equal(insert(sampleLead({ empresa: 'OUTRO NOME' })), 'duplicate');
|
||||
|
||||
const total = db.prepare('SELECT COUNT(*) AS t FROM leads').get().t;
|
||||
assert.equal(total, 1);
|
||||
db.close();
|
||||
});
|
||||
|
||||
test('transaction faz rollback em erro', () => {
|
||||
const db = openDb(':memory:');
|
||||
const insert = createLeadInserter(db);
|
||||
|
||||
assert.throws(() =>
|
||||
transaction(db, () => {
|
||||
insert(sampleLead());
|
||||
throw new Error('boom');
|
||||
})
|
||||
);
|
||||
|
||||
assert.equal(db.prepare('SELECT COUNT(*) AS t FROM leads').get().t, 0);
|
||||
db.close();
|
||||
});
|
||||
|
||||
test('settings: get/set e seed com defaults Z-PRO', () => {
|
||||
const db = openDb(':memory:');
|
||||
seedSettings(db);
|
||||
|
||||
assert.equal(getSetting(db, 'zpro.pipelineId'), '1');
|
||||
assert.equal(getSetting(db, 'zpro.stageId'), '1');
|
||||
assert.equal(getSetting(db, 'zpro.responsibleId'), '15');
|
||||
|
||||
setSetting(db, 'zpro.pipelineId', '9');
|
||||
assert.equal(getSetting(db, 'zpro.pipelineId'), '9');
|
||||
|
||||
// seed nao sobrescreve valor ja definido pelo usuario
|
||||
seedSettings(db);
|
||||
assert.equal(getSetting(db, 'zpro.pipelineId'), '9');
|
||||
db.close();
|
||||
});
|
||||
|
||||
test('seeds de segments, municipios e geo_cache', () => {
|
||||
const db = openDb(':memory:');
|
||||
|
||||
seedSegments(db, [
|
||||
{ name: 'clinicas_medicas', queries: ['clinica'], cnaeCodes: ['8630501'], overpassTags: [{ key: 'amenity', value: 'clinic' }], interest: 'gestao de TI', pains: ['agenda'] }
|
||||
]);
|
||||
const segment = db.prepare('SELECT * FROM segments WHERE name = ?').get('clinicas_medicas');
|
||||
assert.equal(segment.label, 'Clinicas Medicas');
|
||||
assert.deepEqual(JSON.parse(segment.cnae_codes_json), ['8630501']);
|
||||
|
||||
seedMunicipios(db, [{ codigo_ibge: '2928703', nome: 'Santo Antônio de Jesus', uf: 'BA' }]);
|
||||
const municipio = db.prepare('SELECT * FROM municipios WHERE uf = ?').get('BA');
|
||||
assert.equal(municipio.nome_clean, 'santo antonio de jesus');
|
||||
|
||||
seedGeoCache(db, [{ name: 'Santo Antonio de Jesus', state: 'BA', bbox: [-12.995, -39.325, -12.925, -39.225] }]);
|
||||
const bbox = db.prepare('SELECT * FROM geo_cache WHERE key = ?').get('bbox:BA:santo antonio de jesus');
|
||||
assert.equal(bbox.south, -12.995);
|
||||
assert.equal(bbox.provider, 'config-legacy');
|
||||
db.close();
|
||||
});
|
||||
Reference in New Issue
Block a user