ACCEPTANCE CRITERIA (44/44)
☑ AC1.1: Script em `apps/crm/scripts/kommo-import-contacts.js` executavel via `node apps/crm/scripts/kommo-import-contacts.js`
☑ AC1.2: Le token e URL do Kommo de variaveis de ambiente (`KOMMO_ACCESS_TOKEN`, `KOMMO_BASE_URL`)
☑ AC1.3: Le connection string do banco de variaveis de ambiente (`DATABASE_URL` ou parametros individuais)
☑ AC1.4: Aceita flags CLI: `--dry-run` (obrigatorio na primeira execucao), `--resume`, `--verbose`, `--limit N`
☑ AC1.5: Mostra help com `--help`
☑ AC2.1: Puxa contatos de `GET /api/v4/contacts?limit=250&with=leads,companies` com paginacao automatica
☑ AC2.2: Respeita rate limit de 7 req/s (minimo 200ms entre requests)
☑ AC2.3: Retry automatico com backoff exponencial (3 tentativas) em caso de erro 429/5xx
☑ AC2.4: Exibe progresso no terminal (pagina X de Y, contatos processados)
☑ AC2.5: Processa todas as 18 paginas (4.255 contatos) sem interrupcao em condicoes normais
☑ AC3.1: `name` do Kommo → `contact_name` na tabela customers
☑ AC3.2: Campo PHONE dos `custom_fields_values` → `phone_number` (normalizado para formato brasileiro)
☑ AC3.3: Campo EMAIL dos `custom_fields_values` → `email`
☑ AC3.4: `company.name` (se existir) → `business_name`
☑ AC3.5: Campo CNPJ dos `custom_fields_values` → `cnpj` (normalizado XX.XXX.XXX/XXXX-XX)
☑ AC3.6: Campo CPF dos `custom_fields_values` → `cpf`
☑ AC3.7: `id` do Kommo → `metadata.kommo_id` (JSONB)
☑ AC3.8: `created_at` (unix timestamp) → `created_at` (TIMESTAMP)
☑ AC3.9: Custom fields nao mapeados → `metadata.kommo_fields` (JSONB)
☑ AC3.10: Se tem empresa ou CNPJ: `customer_type = 'b2b'`, senao: `customer_type = 'b2c'`
☑ AC4.1: Deduplicacao primaria por `phone_number` (UNIQUE constraint na tabela)
☑ AC4.2: Se telefone ja existe: UPDATE campos vazios do registro existente, NAO sobrescrever campos preenchidos
☑ AC4.3: Se telefone nao existe: INSERT novo registro
☑ AC4.4: Sempre gravar `metadata.kommo_id` (mesmo em updates)
☑ AC4.5: Contatos sem telefone: registrar no log de erros, nao importar (phone_number e NOT NULL)
☑ AC4.6: `source` do registro marcado como `'import'` nos metadados
☑ AC5.1: Com `--dry-run`, script NAO escreve no banco
☑ AC5.2: Dry-run mostra no terminal: total a importar, novos vs updates, erros de validacao
☑ AC5.3: Dry-run gera relatorio em `apps/crm/data/kommo-import-contacts-dryrun-{timestamp}.md`
☑ AC5.4: Primeira execucao DEVE ser com `--dry-run` (script avisa se for a primeira vez sem dry-run)
☑ AC6.1: A cada 250 contatos processados, salva checkpoint na tabela `crm_sync_state` (sync_type = 'kommo_contacts')
☑ AC6.2: Com `--resume`, retoma do ultimo checkpoint salvo
☑ AC6.3: Checkpoint armazena: ultima pagina processada, total processado, timestamp
☑ AC6.4: Ao completar 100%, marca sync como concluido em `crm_sync_state`
☑ AC7.1: Log estruturado em stdout: `[TIMESTAMP] [LEVEL] mensagem` (INFO, WARN, ERROR)
☑ AC7.2: Erros incluem contexto: kommo_id, campo, valor esperado vs obtido
☑ AC7.3: Relatorio final salvo em `apps/crm/data/kommo-import-contacts-report-{timestamp}.md`
☑ AC7.4: Relatorio inclui: total processado, novos, atualizados, erros, tempo total
☑ AC7.5: Contatos sem telefone listados individualmente no relatorio (para correcao manual)
☑ AC8.1: Usa parameterized queries ($1, $2) — NUNCA interpolacao de strings SQL
☑ AC8.2: Usa `crm_user` para conexao ao banco (NAO propek_user)
☑ AC8.3: Bot WhatsApp continua operando normalmente durante a importacao
☑ AC8.4: Zero dependencias externas alem do Node.js stdlib + pg (ja no projeto)
☑ AC8.5: Token do Kommo NUNCA logado ou exibido no terminal