Como foi construído

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 o NOT NULL, PK como id()/bigIncrements) ou models do Sequelize com allowNull correto.