Documentação técnica
A engenharia por trás do Insight: um motor que lê SQL e produz diagrama, auditoria e código — rodando inteiramente no navegador, em JavaScript vanilla, sem backend nem banco no caminho do usuário.
1. Por que client-side
O esquema de um banco é propriedade intelectual sensível — diz como o produto funciona por dentro. Mandar isso pra um servidor seria lento e desnecessário. Então tudo acontece na máquina do usuário: parser.js lê o SQL, canvas.js desenha, auditor.js analisa, calculator.js estima e generator.js exporta. O único armazenamento é o localStorage do próprio navegador (pra não perder o trabalho). Não há login, não há API, não há banco.
2. O parser (parênteses balanceados)
Parsear SQL com um único regex é frágil: ele quebra com ) ENGINE=InnoDB;, com ) e ; em linhas separadas, com parênteses aninhados (DECIMAL(10,2)) e com a última tabela sem ;. Por isso o parser acha o CREATE TABLE nome ( por regex e então varre o corpo contando a profundidade de parênteses até o fecho — robusto a todos esses casos.
const head = /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?[`"\[]?(\w+)[`"\]]?\s*\(/gim;
// ...acha o "(" e varre contando profundidade:
let depth = 1, i = head.lastIndex;
while (i < clean.length && depth > 0) {
const ch = clean[i];
if (ch === '(') depth++;
else if (ch === ')') depth--;
i++;
}
As relações vêm de FKs explícitas (FOREIGN KEY (x) REFERENCES y, inclusive inline) e da convenção x_id → x / xs.
3. O auditor (LGPD-first)
O auditor.js casa os nomes de coluna por substring (não match exato) — assim user_email, senha_hash e numero_cartao são pegos. Ele sinaliza: credencial em campo curto demais pra hash forte, dado pessoal (CPF, e-mail, telefone, endereço — LGPD), dado financeiro/CVV (PCI-DSS) e tabela sem chave primária. Cada achado pesa no security score.
4. Infra & geração de código
- Volumetria: soma os bytes primitivos por tipo (INT 4, DATETIME 8, VARCHAR(N) ≈ N × 0,6 + overhead) pra estimar o tamanho por linha e dimensionar o servidor.
- Laravel / Sequelize: as tabelas viram migrations (
Schema::create, tipos mapeados,nullable()conforme oNOT NULL, PK comoid()/bigIncrements) ou models do Sequelize comallowNullcorreto.