Configuração
Toda a configuração do Extrator é feita através de variáveis de ambiente em um arquivo .env na raiz do projeto.
Início rápido
O Extrator é distribuído pelo CTC como um arquivo .zip. Após recebê-lo:
# 1. Extrair o pacote
unzip ctc-extrator.zip
cd ctc-extrator
# 2. Copiar o template de configuração
cp .env.example .env
# 3. Preencher com as credenciais e parâmetros do seu ambiente
nano .env
# 4. Iniciar
docker compose up --build
Estrutura das variáveis
O .env é dividido em dois grupos:
- Variáveis compartilhadas — sem prefixo. Valem para todos os domínios (autenticação OAuth2, URL da API, conexão Oracle padrão).
- Variáveis por domínio — com prefixo. Configuram o agendamento, queries e, opcionalmente, uma conexão Oracle própria para aquele domínio.
Prefixos por domínio
| Domínio | Prefixo |
|---|---|
| Produtividade | PROD |
| Plantio | PLANT |
| CTT | CTT |
| Ordem de Serviço | ORDEM |
| Pragas | PRAGAS |
| Clima | CLIMA |
Variáveis compartilhadas
Logging
| Variável | Obrigatório | Padrão | Descrição |
|---|---|---|---|
LOG_LEVEL |
❌ | info |
Nível de log: debug, info, warn, error |
Autenticação OAuth2
Credenciais fornecidas pelo CTC para autenticar no Azure Entra ID.
| Variável | Obrigatório | Descrição |
|---|---|---|
AUTH_URL |
✅ | URL completa do endpoint de token — ex: https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token |
CLIENT_ID |
✅ | Client ID da aplicação registrada |
CLIENT_SECRET |
✅ | Client Secret da aplicação |
API de destino
| Variável | Obrigatório | Descrição |
|---|---|---|
API_BASE_URL |
✅ | URL base da API CTC — ex: https://api.ctc.com.br/v1/integrations/{partnerId} |
Conexão Oracle padrão
Usada por todos os domínios que não definem conexão própria (ver Cenários de banco Oracle).
| Variável | Obrigatório | Descrição |
|---|---|---|
SRC_TYPE |
✅ | Tipo da fonte de dados. Use oracle |
SRC_CONNECTION_STR |
✅ | String de conexão no formato host:port/service_name |
SRC_USER |
✅ | Usuário Oracle |
SRC_PASSWORD |
✅ | Senha do usuário Oracle |
Variáveis por domínio
Cada domínio usa o padrão {PREFIXO}_VARIAVEL. As variáveis abaixo se repetem para cada domínio ativo — substitua {PREFIXO} pelo prefixo correspondente.
Agendamento e extração
| Variável | Obrigatório | Descrição |
|---|---|---|
{PREFIXO}_CRON |
✅ | Expressão cron (5 campos) para agendamento |
{PREFIXO}_SRC_QUERY_LIMIT |
❌ | Registros por batch (padrão: 100) |
{PREFIXO}_QUERY_CTRL_MIN_DEFAULT |
✅ | Data de início da extração — usada apenas na primeira execução. Defina uma data anterior ao menor registro existente no banco |
{PREFIXO}_LOG_QUERIES |
❌ | Loga as queries executadas (true/false) |
Queries
| Variável | Obrigatório | Descrição |
|---|---|---|
{PREFIXO}_QUERY_CTRL_MAX |
✅ | Query que retorna o timestamp máximo disponível no banco |
{PREFIXO}_QUERY_TEMPLATE |
✅ | Query principal de extração com suporte a paginação |
Veja Queries e Templates SQL para detalhes e exemplos.
Conexão Oracle por domínio (opcional)
Quando um domínio usa um banco diferente do padrão, defina as variáveis abaixo apenas para esse domínio. As demais continuam usando as variáveis compartilhadas.
| Variável | Descrição |
|---|---|
{PREFIXO}_SRC_TYPE |
Substitui SRC_TYPE para este domínio |
{PREFIXO}_SRC_CONNECTION_STR |
Substitui SRC_CONNECTION_STR para este domínio |
{PREFIXO}_SRC_USER |
Substitui SRC_USER para este domínio |
{PREFIXO}_SRC_PASSWORD |
Substitui SRC_PASSWORD para este domínio |
Cenários de banco Oracle
Cenário A — Banco único (todos os domínios no mesmo banco)
Defina apenas as variáveis compartilhadas. Todos os domínios usarão a mesma conexão automaticamente.
SRC_TYPE="oracle"
SRC_CONNECTION_STR="host:1521/service_name"
SRC_USER="usuario"
SRC_PASSWORD="senha"
Cenário B — Bancos separados por domínio
Mantenha as variáveis compartilhadas como fallback e defina as variáveis específicas apenas para os domínios que usam banco diferente.
# Banco compartilhado (fallback para todos os domínios)
SRC_TYPE="oracle"
SRC_CONNECTION_STR="host-principal:1521/DB_PRINCIPAL"
SRC_USER="usuario"
SRC_PASSWORD="senha"
# Produtividade usa banco próprio
PROD_SRC_CONNECTION_STR="host-prod:1521/DB_PROD"
PROD_SRC_USER="usuario_prod"
PROD_SRC_PASSWORD="senha_prod"
# Plantio usa outro banco
PLANT_SRC_CONNECTION_STR="host-plant:1521/DB_PLANT"
PLANT_SRC_USER="usuario_plant"
PLANT_SRC_PASSWORD="senha_plant"
Defina apenas as variáveis dos domínios que realmente usam banco diferente. Os demais herdam automaticamente as variáveis compartilhadas.
Exemplo completo de .env
LOG_LEVEL=info
# OAuth2
AUTH_URL=https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
CLIENT_ID=seu-client-id
CLIENT_SECRET=seu-client-secret
# API CTC
API_BASE_URL=https://api.ctc.com.br/v1/integrations/{partnerId}
# Oracle compartilhado
SRC_TYPE=oracle
SRC_CONNECTION_STR=meu-oracle.empresa.com.br:1521/PROD
SRC_USER=ctc_extrator
SRC_PASSWORD=senha_segura
# Produtividade
PROD_CRON=0 5 * * *
PROD_SRC_QUERY_LIMIT=1000
PROD_QUERY_CTRL_MIN_DEFAULT=2020-03-01
PROD_LOG_QUERIES=true
PROD_QUERY_CTRL_MAX=SELECT MAX(DT_DATA_REALIZADO) AS CTRL_MAX FROM VW_CTC_PRODUCAO WHERE DT_DATA_REALIZADO > TO_DATE('{{ctrl_min}}', 'YYYY-MM-DD HH24:MI:SS')
PROD_QUERY_TEMPLATE=SELECT * FROM ( SELECT inner_query.*, ROWNUM rn FROM ( SELECT * FROM VW_CTC_PRODUCAO WHERE DT_DATA_REALIZADO > TO_DATE('{{ctrl_min}}', 'YYYY-MM-DD HH24:MI:SS') AND DT_DATA_REALIZADO <= TO_DATE('{{ctrl_max}}', 'YYYY-MM-DD HH24:MI:SS') ORDER BY DT_DATA_REALIZADO ASC ) inner_query WHERE ROWNUM <= {{offset}} + {{limit}} ) WHERE rn > {{offset}}
# Plantio
PLANT_CRON=0 5 * * *
PLANT_SRC_QUERY_LIMIT=1000
PLANT_QUERY_CTRL_MIN_DEFAULT=2024-01-01
PLANT_LOG_QUERIES=true
PLANT_QUERY_CTRL_MAX=SELECT MAX(DT_DATA_PLANTIO) AS CTRL_MAX FROM VW_CTC_PLANTIO WHERE DT_DATA_PLANTIO > TO_DATE('{{ctrl_min}}', 'YYYY-MM-DD HH24:MI:SS')
PLANT_QUERY_TEMPLATE=SELECT * FROM ( SELECT inner_query.*, ROWNUM rn FROM ( SELECT * FROM VW_CTC_PLANTIO WHERE DT_DATA_PLANTIO > TO_DATE('{{ctrl_min}}', 'YYYY-MM-DD HH24:MI:SS') AND DT_DATA_PLANTIO <= TO_DATE('{{ctrl_max}}', 'YYYY-MM-DD HH24:MI:SS') ORDER BY DT_DATA_PLANTIO ASC ) inner_query WHERE ROWNUM <= {{offset}} + {{limit}} ) WHERE rn > {{offset}}
# CTT
CTT_CRON=0 5 * * *
CTT_SRC_QUERY_LIMIT=1000
CTT_QUERY_CTRL_MIN_DEFAULT=2020-01-01
CTT_LOG_QUERIES=true
CTT_QUERY_CTRL_MAX=SELECT MAX(DT_DATA_COLHEITA) AS CTRL_MAX FROM VW_CTC_CTT WHERE DT_DATA_COLHEITA > TO_DATE('{{ctrl_min}}', 'YYYY-MM-DD HH24:MI:SS')
CTT_QUERY_TEMPLATE=SELECT * FROM ( SELECT inner_query.*, ROWNUM rn FROM ( SELECT * FROM VW_CTC_CTT WHERE DT_DATA_COLHEITA > TO_DATE('{{ctrl_min}}', 'YYYY-MM-DD HH24:MI:SS') AND DT_DATA_COLHEITA <= TO_DATE('{{ctrl_max}}', 'YYYY-MM-DD HH24:MI:SS') ORDER BY DT_DATA_COLHEITA ASC ) inner_query WHERE ROWNUM <= {{offset}} + {{limit}} ) WHERE rn > {{offset}}
# Ordem de Serviço
ORDEM_CRON=0 5 * * *
ORDEM_SRC_QUERY_LIMIT=1000
ORDEM_QUERY_CTRL_MIN_DEFAULT=2020-01-01
ORDEM_LOG_QUERIES=true
ORDEM_QUERY_CTRL_MAX=SELECT MAX(DT_DATA_ORDEM) AS CTRL_MAX FROM VW_CTC_ORDEM WHERE DT_DATA_ORDEM > TO_DATE('{{ctrl_min}}', 'YYYY-MM-DD HH24:MI:SS')
ORDEM_QUERY_TEMPLATE=SELECT * FROM ( SELECT inner_query.*, ROWNUM rn FROM ( SELECT * FROM VW_CTC_ORDEM WHERE DT_DATA_ORDEM > TO_DATE('{{ctrl_min}}', 'YYYY-MM-DD HH24:MI:SS') AND DT_DATA_ORDEM <= TO_DATE('{{ctrl_max}}', 'YYYY-MM-DD HH24:MI:SS') ORDER BY DT_DATA_ORDEM ASC ) inner_query WHERE ROWNUM <= {{offset}} + {{limit}} ) WHERE rn > {{offset}}
# Pragas
PRAGAS_CRON=0 5 * * *
PRAGAS_SRC_QUERY_LIMIT=1000
PRAGAS_QUERY_CTRL_MIN_DEFAULT=2020-01-01
PRAGAS_LOG_QUERIES=true
PRAGAS_QUERY_CTRL_MAX=SELECT MAX(DT_DATA_PRAGA) AS CTRL_MAX FROM VW_CTC_PRAGAS WHERE DT_DATA_PRAGA > TO_DATE('{{ctrl_min}}', 'YYYY-MM-DD HH24:MI:SS')
PRAGAS_QUERY_TEMPLATE=SELECT * FROM ( SELECT inner_query.*, ROWNUM rn FROM ( SELECT * FROM VW_CTC_PRAGAS WHERE DT_DATA_PRAGA > TO_DATE('{{ctrl_min}}', 'YYYY-MM-DD HH24:MI:SS') AND DT_DATA_PRAGA <= TO_DATE('{{ctrl_max}}', 'YYYY-MM-DD HH24:MI:SS') ORDER BY DT_DATA_PRAGA ASC ) inner_query WHERE ROWNUM <= {{offset}} + {{limit}} ) WHERE rn > {{offset}}
# Clima
CLIMA_CRON=0 5 * * *
CLIMA_SRC_QUERY_LIMIT=1000
CLIMA_QUERY_CTRL_MIN_DEFAULT=2020-01-01
CLIMA_LOG_QUERIES=true
CLIMA_QUERY_CTRL_MAX=SELECT MAX(DT_DATA_CLIMA) AS CTRL_MAX FROM VW_CTC_CLIMA WHERE DT_DATA_CLIMA > TO_DATE('{{ctrl_min}}', 'YYYY-MM-DD HH24:MI:SS')
CLIMA_QUERY_TEMPLATE=SELECT * FROM ( SELECT inner_query.*, ROWNUM rn FROM ( SELECT * FROM VW_CTC_CLIMA WHERE DT_DATA_CLIMA > TO_DATE('{{ctrl_min}}', 'YYYY-MM-DD HH24:MI:SS') AND DT_DATA_CLIMA <= TO_DATE('{{ctrl_max}}', 'YYYY-MM-DD HH24:MI:SS') ORDER BY DT_DATA_CLIMA ASC ) inner_query WHERE ROWNUM <= {{offset}} + {{limit}} ) WHERE rn > {{offset}}
Exemplos de cron:
PROD_CRON=0 */6 * * * # A cada 6 horas
PROD_CRON=0 2 * * * # Diariamente às 02:00
PROD_CRON=*/30 * * * * # A cada 30 minutos
PROD_CRON=0 8 * * 1-5 # Segunda a sexta às 08:00
Segurança
O arquivo .env contém credenciais sensíveis e não deve ser versionado.
# Certifique-se que .env está no .gitignore
echo ".env" >> .gitignore
# Versione apenas o template
git add .env.example
Verificando a inicialização
Após docker compose up, os logs devem mostrar conexão confirmada para cada domínio ativo:
{"domain":"productivity","msg":"Connected to db"}
{"domain":"planting","msg":"Connected to db"}
{"domain":"ctt","msg":"Connected to db"}
{"domain":"ordem","msg":"Connected to db"}
{"domain":"pragas","msg":"Connected to db"}
{"domain":"clima","msg":"Connected to db"}
Se o Oracle Instant Client não for encontrado, o Extrator faz fallback automático para Thin mode:
Solução de problemas
Invalid environment variables — alguma variável obrigatória não foi definida ou tem formato inválido. Verifique o .env e compare com o .env.example.
Failed to connect to Oracle Database — verifique credenciais, string de conexão e conectividade de rede entre o container e o banco Oracle.
Authentication failed — teste as credenciais OAuth2 manualmente:
curl -X POST "$AUTH_URL" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&scope=.default"
NJS-138: connections not supported in Thin mode — o banco Oracle é legado e requer Thick mode. Verifique se o container está usando a imagem correta (com Instant Client incluído).