> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Portas do Fetcher Engine

> Referência das oito portas de capacidade do Fetcher Engine: o que cada contrato exige, se é obrigatória e exatamente o que o Engine faz sem ela.

O [Fetcher Engine](/pt/fetcher/fetcher-engine-overview) não é dono de nenhuma infraestrutura. Ele alcança o mundo externo apenas por **portas** — interfaces Go que a sua aplicação hospedeira implementa e passa para `engine.New`.

Esta página é a referência das oito. A coluna **Sem ela** é o ponto central da página. A degradação controlada é o contrato com o qual você planeja, então leia-a antes de pular uma porta.

## As portas em resumo

***

| Porta                    | Obrigatória                    | Sem ela                                                                                                                                  |
| ------------------------ | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `ConnectorRegistry`      | **Sempre**                     | `engine.New` falha. Nenhum Engine existe.                                                                                                |
| `CredentialProtector`    | Com persistência criptografada | `engine.New` falha quando a persistência criptografada está ligada. Caso contrário, as credenciais chegam ao armazenamento sem proteção. |
| `ConnectionStore`        | Opcional                       | Toda operação exceto `Limits()` falha.                                                                                                   |
| `ExecutionStore`         | Opcional                       | Sem rastreamento durável do estado de execução.                                                                                          |
| `ResultSink`             | Opcional                       | O modo store fica indisponível. A extração roda em modo direct.                                                                          |
| `SchemaCache`            | Opcional                       | A descoberta de esquema sempre consulta a fonte de dados ao vivo.                                                                        |
| `ActiveExecutionChecker` | Opcional                       | Sem bloqueio por conflito. Atualizações e exclusões de conexão sempre seguem adiante.                                                    |
| `Observability`          | Opcional                       | Os ganchos de tracing viram no-ops.                                                                                                      |

<Note>
  `engine.New` rejeita uma porta passada como **nil tipado**, e não apenas um nil literal. Um valor de interface que envolve um ponteiro nulo falha na construção com um erro de validação claro, em vez de quebrar no primeiro uso.
</Note>

## ConnectorRegistry

***

**Obrigatória: sempre.** Esta é a única porta que o Engine valida incondicionalmente.

O registro resolve uma factory de conector pelo tipo de fonte de dados. Ele não faz I/O, resolve de forma determinística pelo tipo e reporta `ok=false` para um tipo que ninguém registrou. Construir e conectar um conector acontece depois, pela factory que ele retornou.

**Sem ela:** `engine.New` retorna um erro de validação com a mensagem `connector registry is required`. Você não obtém valor de Engine algum, então a extração é impossível.

## CredentialProtector

***

**Obrigatória: apenas com `WithEncryptedPersistence(true)`.**

O protetor criptografa e descriptografa material de credencial para um tenant. A chamada `Protect` retorna os bytes protegidos mais a versão da chave que os protegeu. A chamada `Reveal` descriptografa com uma dada versão de chave, para que o seu hospedeiro possa resolver uma chave rotacionada.

O seu hospedeiro é dono da derivação, da rotação e do armazenamento de chaves. O Engine apenas chama o ponto de extensão e registra a versão de chave retornada como metadado livre de segredos.

**Sem ela:**

* Com a persistência criptografada **ligada**, `engine.New` falha com `credential protector is required when encrypted persistence is enabled`. O Engine se recusa a construir em vez de persistir credenciais em texto claro.
* Com a persistência criptografada **desligada**, a porta é genuinamente opcional, e as credenciais chegam ao `ConnectionStore` sem proteção.

## ConnectionStore

***

**Obrigatória: opcional na construção, indispensável em tempo de execução.**

O armazenamento persiste e resolve descritores de conexão que pertencem a um tenant. Ele é o único ponto de persistência que as operações de conexão usam — o Engine não embute MongoDB, nem SQL, nem repositório do hospedeiro. Ele expõe nove operações: create, find, find-by-id, update, update-by-id, delete, delete-by-id, list e list-paged.

Duas obrigações recaem sobre a sua implementação. Ela **precisa** escopar todo registro pelo ID de tenant, para que um tenant nunca veja as conexões de outro. Ela **não pode** retornar material secreto — o descritor de conexão não carrega nenhum.

**Sem ela:** `engine.New` tem sucesso, e depois quase tudo falha. Toda operação que toca uma conexão retorna o erro de validação `connection store is not configured`. Isso cobre as nove operações de conexão mais planejar, executar, descobrir esquema, descoberta de esquema sempre atualizada, validar esquema e testar conexão. Um Engine sem armazenamento de conexões consegue reportar apenas os próprios limites.

<Warning>
  Não leia o `ConnectionStore` como uma conveniência apenas de CRUD. Pular essa porta também desativa a extração e a descoberta de esquema.
</Warning>

## ExecutionStore

***

**Obrigatória: opcional.**

O armazenamento faz upsert do estado do ciclo de vida da execução para um tenant. O Engine escreve as transições de forma síncrona e inline: `running`, depois `completed`, `failed` ou `canceled`.

Essas escritas são **best-effort por desenho**. O Engine descarta um erro de gravação, para que a persistência opcional nunca corrompa um resultado de extração. Uma falha de escrita no result sink se comporta de outra forma e realmente faz a execução falhar. As duas são deliberadamente distintas.

**Sem ela:** o Engine roda sem rastreamento durável de execução, e o seu hospedeiro é dono do estado de execução externamente.

## ResultSink

***

**Obrigatória: opcional. Ela seleciona o modo de resultado.**

O sink persiste os payloads de resultado no storage gerenciado pelo hospedeiro. A extração em modo store chama `OpenResultStream`, de modo que o Engine escreve o resultado de forma incremental, com memória constante. `PersistResult` continua disponível para escritas do payload inteiro.

O formato do stream é NDJSON contratual — um objeto JSON por linha, terminado por quebra de linha, sem array envolvente:

```json theme={null}
{"config":"<configName>","table":"<qualifiedTable>","row":{"<col>":"<val>"}}
```

As linhas saem em ordem determinística: os passos pela ordem crescente do ordinal no plano, e as linhas dentro de um passo na ordem do cursor. A mesma entrada, portanto, produz um NDJSON idêntico byte a byte e o mesmo digest SHA-256 a cada execução.

Em um aborto — um erro de escrita, um limite de tamanho excedido ou um contexto cancelado — o Engine abandona o escritor e nunca chama `Close`. Trate um escritor não fechado como uma escrita descartada, porque um resultado parcial nunca pode virar uma referência retornada.

**Sem ela:** o modo store fica indisponível. O modo padrão `auto` resolve para direct, então a extração retorna bytes inline e não persiste nada. Um pedido explícito de modo store falha logo no início com `store mode requires a configured result sink`, antes de o Engine construir qualquer conector.

## SchemaCache

***

**Obrigatória: opcional.**

O cache guarda e devolve snapshots de esquema por tenant e por nome de configuração.

O Engine o trata como um acelerador, nunca como fonte da verdade. Uma leitura de cache que falha degrada para descoberta ao vivo. Uma escrita de cache que falha ainda assim devolve o esquema descoberto a quem chamou. A chamada de descoberta sempre atualizada ignora o cache em toda invocação, mesmo quando você ligou um, para que o contrato de fonte de dados ao vivo do endpoint de esquema do Manager se mantenha.

**Sem ela:** o Engine descobre o esquema ao vivo na fonte de dados a cada chamada.

## ActiveExecutionChecker

***

**Obrigatória: opcional.**

O verificador informa se uma conexão tem execuções ativas no momento. O Engine o consulta **antes** de mutar uma conexão. Um hospedeiro pode, assim, manter o comportamento do Manager, que bloqueia uma mudança enquanto há jobs rodando contra aquela conexão.

A porta é deliberadamente **lógica**, e não um armazenamento durável de jobs. O seu hospedeiro decide como responder: um repositório de jobs, um rastreador em memória, um lock distribuído ou sempre falso. O Engine nunca importa um repositório de jobs para fazer a pergunta. A identidade de conexão que ele passa é o nome da configuração dentro do escopo do tenant. A sua resposta **precisa** ter escopo de tenant, para que o trabalho em andamento de um tenant nunca bloqueie a mutação de outro.

**Sem ela:** o Engine não faz bloqueio por conflito, e atualizações e exclusões de conexão seguem adiante incondicionalmente.

## Observability

***

**Obrigatória: opcional.**

O contrato tem um único método. `StartSpan` recebe um contexto e um nome de operação, e retorna um contexto derivado mais uma função de encerramento que o Engine adia. Um único método é justamente o ponto: o núcleo do Engine nunca importa uma biblioteca de tracing, e o seu hospedeiro adapta o próprio tracer por trás desse ponto de extensão.

**Sem ela:** a criação de span retorna o contexto recebido e uma função de encerramento no-op. Os ganchos de tracing desaparecem sem nenhuma outra mudança de comportamento.

## Próximos passos

***

<CardGroup cols={2}>
  <Card title="Incorporar o Engine" icon="code" href="/pt/fetcher/fetcher-embedding-the-engine">
    Importe, forneça as portas e construa com um exemplo executável.
  </Card>

  <Card title="Visão geral do Engine" icon="cube" href="/pt/fetcher/fetcher-engine-overview">
    O modelo de três camadas, a fronteira de importação e os dois modos de resultado.
  </Card>
</CardGroup>
