chore: import maquina-comercial-pessoal history via subtree

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

git-subtree-dir: maquina-comercial-pessoal
git-subtree-mainline: f5af038e19
git-subtree-split: a9ef4d776d
This commit is contained in:
Gustavo
2026-09-28 15:50:17 -03:00
co-authored by Claude Sonnet 5
150 changed files with 33449 additions and 0 deletions
@@ -0,0 +1,125 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { openDb } from '../src/db.mjs';
import { createRouter } from '../src/server/router.mjs';
import { registerCaptureRoutes } from '../src/server/routes/capture.mjs';
import { registerExtractionRoutes } from '../src/server/routes/extractions.mjs';
function setup() {
const db = openDb(':memory:');
db.prepare("INSERT INTO municipios (codigo_ibge, nome, nome_clean, uf) VALUES ('1','Salvador','salvador','BA')").run();
db.prepare("INSERT INTO segments (name,label,active) VALUES ('restaurantes','Restaurantes',1)").run();
db.prepare("INSERT INTO cnaes (codigo,descricao) VALUES ('5611201','Restaurantes')").run();
const router = createRouter();
let started;
registerCaptureRoutes(router, { db, jobs: { startJob: (options) => { started = options; return 'job-1'; } } });
return { db, handler: router.match('POST', '/api/capture/runs').handler, get started() { return started; } };
}
async function invoke(handler, body) {
let result;
await handler({}, {}, { body, json: (status, data) => { result = { status, data }; } });
return result;
}
const valid = {
sources: ['mock'], uf: 'BA', cities: ['Salvador'], segments: ['restaurantes'],
limits: { maxPerQuery: 10, queryLimit: 0, googlePages: 1 }
};
test('captura aceita apenas selecoes reais e persiste parametros normalizados', async () => {
const fixture = setup();
const { db, handler } = fixture;
const result = await invoke(handler, valid);
assert.equal(result.status, 202);
assert.deepEqual(JSON.parse(db.prepare('SELECT params_json FROM capture_runs').get().params_json), valid);
const row = db.prepare('SELECT job_id, owner_token, heartbeat_at FROM capture_runs').get();
assert.equal(row.job_id, 'job-1');
assert.ok(row.owner_token);
assert.ok(row.heartbeat_at);
assert.equal(fixture.started.ownerToken, row.owner_token);
db.close();
});
test('captura rejeita arrays vazios, duplicados, excessivos e strings longas', async () => {
for (const patch of [
{ sources: [] },
{ cities: [] },
{ segments: [] },
{ sources: ['mock', 'mock'] },
{ sources: Array(11).fill('mock') },
{ cities: Array(1001).fill('Salvador') },
{ segments: Array(251).fill('restaurantes') },
{ cities: ['x'.repeat(101)] }
]) {
const { db, handler } = setup();
assert.equal((await invoke(handler, { ...valid, ...patch })).status, 400);
db.close();
}
});
test('captura rejeita cidade, segmento, CNAE e limites inexistentes ou fora da faixa', async () => {
for (const patch of [
{ cities: ['Feira de Santana'] },
{ cities: ['all', 'Salvador'] },
{ segments: ['inativo'] },
{ segments: ['cnae:123'] },
{ segments: ['cnae:1234567'] },
{ limits: { maxPerQuery: 0, queryLimit: 0, googlePages: 1 } },
{ limits: { maxPerQuery: 101, queryLimit: 0, googlePages: 1 } },
{ limits: { maxPerQuery: 10, queryLimit: 10001, googlePages: 1 } },
{ limits: { maxPerQuery: 10, queryLimit: 0, googlePages: 4 } }
]) {
const { db, handler } = setup();
assert.equal((await invoke(handler, { ...valid, ...patch })).status, 400);
db.close();
}
});
test('captura converte corrida de constraint em 409 sem row parcial', async () => {
const db = openDb(':memory:');
db.prepare("INSERT INTO municipios (codigo_ibge, nome, nome_clean, uf) VALUES ('1','Salvador','salvador','BA')").run();
db.prepare("INSERT INTO segments (name,label,active) VALUES ('restaurantes','Restaurantes',1)").run();
const raceDb = {
prepare(sql) {
if (/INSERT INTO capture_runs/.test(sql)) {
const error = new Error('UNIQUE constraint failed: active capture');
error.errcode = 2067;
throw error;
}
return db.prepare(sql);
}
};
const router = createRouter();
let started = false;
registerCaptureRoutes(router, { db: raceDb, jobs: { startJob: () => { started = true; } } });
const result = await invoke(router.match('POST', '/api/capture/runs').handler, valid);
assert.equal(result.status, 409);
assert.match(result.data.erro, /simultaneamente/i);
assert.equal(db.prepare('SELECT COUNT(*) total FROM capture_runs').get().total, 0);
assert.equal(started, false);
db.close();
});
test('extracao converte corrida de constraint em 409 sem row parcial', async () => {
const db = openDb(':memory:');
const raceDb = {
prepare(sql) {
if (/INSERT INTO extractions/.test(sql)) {
const error = new Error('UNIQUE constraint failed: active extraction');
error.errcode = 2067;
throw error;
}
return db.prepare(sql);
}
};
const router = createRouter();
let started = false;
registerExtractionRoutes(router, { db: raceDb, jobs: { startJob: () => { started = true; } } });
const result = await invoke(router.match('POST', '/api/extractions').handler, { uf: 'BA' });
assert.equal(result.status, 409);
assert.match(result.data.erro, /simultaneamente/i);
assert.equal(db.prepare('SELECT COUNT(*) total FROM extractions').get().total, 0);
assert.equal(started, false);
db.close();
});