Conn2Flow
Navegação das docs

Referência / Bibliotecas

Biblioteca modulo-distribuido.php

Arquitetura central/distribuído: um módulo roda no Conn2Flow central e grava os dados no banco da instalação do cliente por um canal HMAC, com login e permissão decididos pelo central.

Caminho no Gestor bibliotecas/modulo-distribuido.php

Permite que um módulo tenha duas metades:

  • central ("scope": "central-module" no <modulo>.json): roda na instalação central (a do fornecedor), onde ficam o código, os usuários e as permissões;

  • distribuído ("scope": "distributed-module"): roda no site do cliente e guarda os dados no banco do cliente.

O código do módulo central continua usando banco_select(), banco_insert()… normalmente; dentro do canal distribuído, banco_query() empacota a SQL e a executa na instalação do cliente. O cliente vê o módulo como uma tela embutida (iframe) do central, liberada só depois de o central confirmar login e permissão.

Configuração

No .env (variáveis globais): MODULO_DISTRIBUIDO_SECRET (segredo HMAC compartilhado), MODULO_DISTRIBUIDO_CENTRAL_URL (no distribuído: a URL do central) e MODULO_DISTRIBUIDO_ENDPOINT (no central: a URL da API do distribuído). Por módulo, $_CONFIG['modulo-distribuido']['secrets'][<slug>] e ['endpoints'][<slug>] sobrepõem os valores gerais (modulo_distribuido_config_get('modulo-distribuido.secrets.<slug>')).

modulo_distribuido_scope($manifesto), modulo_distribuido_scope_central(), modulo_distribuido_scope_distribuido() e modulo_distribuido_resolver_manifesto() leem o escopo do manifesto (constantes C2F_SCOPE_CENTRAL e C2F_SCOPE_DISTRIBUIDO).

O canal de dados

// No módulo central, envolvendo só as operações de dados do cliente:
// o manifesto do módulo central declara "distributed": {"target-slug": "meu-modulo"}
$config = modulo_distribuido_canal_central($_GESTOR['modulo#'.$_GESTOR['modulo-id']]);
$pedidos = modulo_distribuido_com_canal(function () {
    return banco_select(['tabela' => 'pedidos', 'campos' => ['id', 'total']]);
}, $config);
// ou, à mão: banco_distribuido_iniciar($config); … banco_distribuido_finalizar();
  1. banco_distribuido_ativo() faz banco_query() desviar para banco_distribuido_query().

  2. modulo_distribuido_montar_payload() empacota a SQL (operacao, modulo, linguagem, timestamp, nonce), e modulo_distribuido_enviar() a manda por modulo_distribuido_http_post() para <endpoint>/modulo-distribuido/<slug>/db, com X-C2F-Signature = HMAC-SHA256 do corpo (modulo_distribuido_assinar()).

  3. No distribuído, a API confere a assinatura (modulo_distribuido_verificar_assinatura(), tempo constante) e modulo_distribuido_executar_local() roda a SQL via PDO: SELECT devolve colunas e linhas; escrita devolve affected_rows e insert_id.

  4. modulo_distribuido_resposta_para_resultado() converte a resposta num BancoResultadoRemoto, que imita o mysqli_result para as funções da banco.php.

Autenticação, variáveis e o resto da requisição continuam no banco local do central: só o que estiver dentro do canal vai para o cliente. modulo_distribuido_canal_central($manifesto, $overrides) monta a configuração do lado central a partir de distributed.target-slug (e, opcionalmente, endpoint-config/secret-config, caminhos de chaves em $_CONFIG) do manifesto; modulo_distribuido_canal_distribuido() faz o mesmo no distribuído, para falar com o central; modulo_distribuido_detectar_operacao() e modulo_distribuido_operacao_leitura() classificam a SQL; modulo_distribuido_parse_rota() lê {slug}/{acao} da URL.

Login, permissão e tela

O distribuído não decide acesso: pergunta ao central.

  • O login é o do perfil-usuario do central: sem token, o host distribuído manda o navegador para /signin/ do central com um contexto assinado; depois do login completo (inclusive segundo fator) o gancho login.distribuido devolve um código de uso único, trocado entre servidores pelos tokens (ação exchange). modulo_distribuido_token_sessao() e modulo_distribuido_persistir_token() guardam e renovam os tokens na sessão. Não existe login por usuário e senha neste canal.

  • modulo_distribuido_guardiao() (no distribuído) consulta o central, onde modulo_distribuido_middleware_central() valida o token e a permissão do usuário no módulo e responde nao-autenticado, sem-permissao ou autorizado. Qualquer falha resolve para o estado mais restritivo.

  • modulo_distribuido_estado_renderizacao() traduz isso em login, sem-permissao ou iframe; modulo_distribuido_montar_url_iframe() monta a URL da tela do central.

  • modulo_distribuido_app() faz tudo numa chamada: token, guardião e a tela do estado, trocando #modulo-distribuido-app# na página pelo componente modulo-distribuido-app (modulo_distribuido_render_estado(), modulo_distribuido_render_componente(), modulo_distribuido_textos()).

As variantes modulo_distribuido_estado_por_token_ativo(), modulo_distribuido_estado_por_permissao_central() e modulo_distribuido_middleware_permissao() são as peças puras (testáveis) desse fluxo.

Funções

Gerado a partir de gestor/bibliotecas/modulo-distribuido.php · 36 funções

36 de 36

modulo_distribuido_scope

ver no código · linha 140 ↗
modulo_distribuido_scope(array|string $modulo, string|null $slug = null): string|null

Lê o valor da chave "scope" do manifesto <slug>.json de um módulo.

Parâmetros

$moduloarray|string
Manifesto decodificado, caminho do .json ou do diretório do módulo.
$slugstring|null
Slug do módulo (necessário quando $modulo é um diretório).

Retorno

string|null
Valor de scope ('central-module' / 'distributed-module') ou null.

modulo_distribuido_resolver_manifesto

ver no código · linha 170 ↗
modulo_distribuido_resolver_manifesto(array|string $modulo, string|null $slug = null): array|null

Resolve o manifesto (array) de um módulo a partir de array, caminho de .json ou diretório.

Parâmetros

$moduloarray|string
Manifesto decodificado, caminho do .json ou do diretório do módulo.
$slugstring|null
Slug do módulo (usado para achar <slug>.json quando $modulo é diretório).

Retorno

array|null
Manifesto decodificado ou null.

modulo_distribuido_assinar

ver no código · linha 209 ↗
modulo_distribuido_assinar(string $corpo, string $secret, string $algo = 'sha256'): string

Gera a assinatura HMAC de um corpo de requisição.

Parâmetros

$corpostring
Corpo cru (string JSON) a ser assinado.
$secretstring
Segredo compartilhado entre central e distribuído.
$algostring
Algoritmo de hash (padrão sha256).

Retorno

string
Assinatura em hexadecimal.

modulo_distribuido_verificar_assinatura

ver no código · linha 223 ↗
modulo_distribuido_verificar_assinatura(string $corpo, string $assinatura, string $secret, string $algo = 'sha256'): bool

Verifica, de forma resistente a ataques de timing, a assinatura HMAC de um corpo.

Parâmetros

$corpostring
Corpo cru recebido.
$assinaturastring
Assinatura recebida (header X-C2F-Signature).
$secretstring
Segredo compartilhado.
$algostring
Algoritmo de hash (padrão sha256).

Retorno

bool
true se a assinatura confere.

modulo_distribuido_montar_payload

ver no código · linha 267 ↗
modulo_distribuido_montar_payload(string $sql, array $opcoes = []): array

Monta o payload (array) que empacota a instrução SQL para trânsito via API.

Parâmetros

$sqlstring
Instrução SQL já montada.
$opcoesarray
Opções: 'modulo' (slug), 'linguagem'.

Retorno

array
Payload com sql, operacao, modulo, timestamp e nonce.

modulo_distribuido_enviar

ver no código · linha 298 ↗
modulo_distribuido_enviar(array $payload, array $config): array

Envia um payload de banco distribuído para a instalação remota e decodifica a resposta.

Parâmetros

$payloadarray
Payload montado por modulo_distribuido_montar_payload().
$configarray
Configuração do canal distribuído.

Retorno

array
Resposta decodificada. Em erro retorna ['status' => 'error', 'message' => ...].

modulo_distribuido_http_post

ver no código · linha 374 ↗
modulo_distribuido_http_post($url, $corpo, array $headers, $timeout = 15): string|false

POST HTTP simples via cURL. Isolado para permitir mock nos testes.

Parâmetros

$url
$corpo
$headersarray
$timeout

Retorno

string|false
Corpo da resposta ou false em falha de transporte.

modulo_distribuido_executar_local

ver no código · linha 457 ↗
modulo_distribuido_executar_local(array $payload, PDO $pdo): array

Executa localmente, no banco do cliente, a instrução SQL recebida da central.

Parâmetros

$payloadarray
Payload recebido (deve conter 'sql').
$pdoPDO
Conexão PDO com o banco local do cliente.

Retorno

array
Resposta pronta para json_encode: {status, tipo, fields, rows, ...}.

modulo_distribuido_parse_rota

ver no código · linha 570 ↗
modulo_distribuido_parse_rota(array $caminho): array|null

Faz o parse da rota da API distribuída: api/v1/modulo-distribuido/{slug}/{acao}.

Parâmetros

$caminhoarray
Segmentos do caminho da URL.

Retorno

array|null
['slug' => ..., 'acao' => ..., 'resto' => [...]] ou null se não casar.

modulo_distribuido_estado_renderizacao

ver no código · linha 640 ↗
modulo_distribuido_estado_renderizacao(bool $token_ativo, bool $tem_permissao): string

Decide o estado de renderização considerando autenticação E permissão por módulo.

Parâmetros

$token_ativobool
Usuário autenticado (token válido).
$tem_permissaobool
Usuário autorizado ao módulo alvo.

Retorno

string
'login' | 'sem-permissao' | 'iframe'.

modulo_distribuido_estado_por_permissao_central

ver no código · linha 658 ↗
modulo_distribuido_estado_por_permissao_central(string $estado_central): string

Traduz o 'estado' devolvido pelo middleware central (endpoint 'permissao') no estado de renderização do ambiente distribuído.

Parâmetros

$estado_centralstring
'nao-autenticado' | 'sem-permissao' | 'permitido'.

Retorno

string
'login' | 'sem-permissao' | 'iframe'.

modulo_distribuido_middleware_permissao

ver no código · linha 682 ↗
modulo_distribuido_middleware_permissao(array $config, string $token, string|null $slug = null): array

Middleware de permissão (lado distribuído): consulta o central e devolve o estado.

Parâmetros

$configarray
Config do canal (endpoint, slug, secret, transporte).
$tokenstring
Access token do usuário (obtido no signin).
$slugstring|null
Slug do módulo alvo (default: $config['slug']).

Retorno

array
['estado' => 'login'|'sem-permissao'|'iframe', 'resposta' => array].

modulo_distribuido_guardiao

ver no código · linha 732 ↗
modulo_distribuido_guardiao(array $config, array $opcoes = []): array

Guardião de módulo distribuído — fachada obrigatória de controle de acesso.

Parâmetros

$configarray
Config do canal (endpoint, slug, secret, transporte, central-url).
$opcoesarray
'token', 'central-url', 'opcao', 'params-iframe', 'slug'.

Retorno

array
{

modulo_distribuido_middleware_central

ver no código · linha 778 ↗
modulo_distribuido_middleware_central(string $token, string $slug, array $opcoes = []): array

Middleware central — avalia autenticação e permissão como AUTORIDADE do sistema.

Parâmetros

$tokenstring
Access token do usuário.
$slugstring
Slug do módulo alvo.
$opcoesarray
'resolver_usuario' (callable(token):?int), 'verificar_permissao' (callable(id,slug):bool).

Retorno

array
['estado' => 'nao-autenticado'|'sem-permissao'|'permitido', 'id_usuarios' => int|null, 'modulo' => string].

modulo_distribuido_montar_url_iframe

ver no código · linha 818 ↗
modulo_distribuido_montar_url_iframe(string $endpoint_central, string $slug, array $opcoes = []): string

Monta a URL administrativa do módulo no central para renderização em Iframe.

Parâmetros

$endpoint_centralstring
URL base do central (ex.: https://conn2flow.com/).
$slugstring
Slug do módulo (central) a ser embutido.
$opcoesarray
'modulo' (override do slug na URL), 'opcao', 'token', 'params' (extra).

Retorno

string
URL absoluta para o src do Iframe.

banco_distribuido_query

ver no código · linha 885 ↗
banco_distribuido_query(string $sql): BancoResultadoRemoto|bool

Executa uma query no modo distribuído: empacota, envia e converte a resposta.

Parâmetros

$sqlstring
Instrução SQL montada pelas funções de banco.php.

Retorno

BancoResultadoRemoto|bool

modulo_distribuido_config_get

ver no código · linha 922 ↗
modulo_distribuido_config_get(string $path, mixed $default = null): mixed

Lê um valor de $_CONFIG por caminho em dot-notation (ex.: 'modulo-distribuido.secret').

Parâmetros

$pathstring
Caminho em dot-notation.
$defaultmixed
Valor padrão quando o caminho não existe.

Retorno

mixed

modulo_distribuido_canal_central

ver no código · linha 951 ↗
modulo_distribuido_canal_central(array $modulo_config, array $overrides = []): array

Resolve a config do canal para um MÓDULO CENTRAL (que delega banco ao distribuído).

Parâmetros

$modulo_configarray
Manifesto do módulo central.
$overridesarray
endpoint, secret, slug, token, timeout, transporte.

Retorno

array

modulo_distribuido_canal_distribuido

ver no código · linha 991 ↗
modulo_distribuido_canal_distribuido(array $modulo_config, array $overrides = []): array

Resolve a config do canal para um MÓDULO DISTRIBUÍDO (que consulta o central).

Parâmetros

$modulo_configarray
Manifesto do módulo distribuído.
$overridesarray
central-url, secret, slug, transporte.

Retorno

array
Inclui 'endpoint' (central-url/_api) e 'central-url'.

modulo_distribuido_com_canal

ver no código · linha 1026 ↗
modulo_distribuido_com_canal(callable $operacao, array $config): mixed

Executa uma operação de dados dentro do canal distribuído, garantindo o fechamento.

Parâmetros

$operacaocallable
Função com as chamadas de banco (delegadas ao distribuído).
$configarray
Config do canal (de modulo_distribuido_canal_central()).

Retorno

mixed
Retorno de $operacao.

modulo_distribuido_persistir_token

ver no código · linha 1079 ↗
modulo_distribuido_persistir_token(string $chave, array $tokens, callable|null $persistir = null): void

Persiste os tokens obtidos no login/ativação distribuído.

Parâmetros

$chavestring
Chave base da variável de sessão do token.
$tokensarray
Tokens retornados pelo central (access_token, refresh_token, ...).
$persistircallable|null
Persistência customizada: function($chave, array $tokens): void.

Retorno

void

modulo_distribuido_textos

ver no código · linha 1107 ↗
modulo_distribuido_textos(string|null $lang = null, array $overrides = [], $resolver = null): array

Dicionário de textos (i18n) do componente global de estados distribuídos.

Parâmetros

$langstring|null
Idioma (default: $_GESTOR['linguagem-codigo']).
$overridesarray
Sobrescritas de texto por chave (#c2f-md-*# sem as cercas).
$resolver

Retorno

array
Mapa chave => texto.

modulo_distribuido_render_componente

ver no código · linha 1128 ↗
modulo_distribuido_render_componente(string $html, string $estado, string|null $iframe_url = null, array $textos = []): string

Processa o HTML do componente de estados segundo o estado de acesso (função pura).

Parâmetros

$htmlstring
HTML do componente (de gestor_componente()).
$estadostring
'login' | 'sem-permissao' | 'iframe'.
$iframe_urlstring|null
URL do Iframe (quando 'iframe').
$textosarray
Mapa de textos (de modulo_distribuido_textos()).

Retorno

string
HTML final pronto para injeção.

modulo_distribuido_render_estado

ver no código · linha 1172 ↗
modulo_distribuido_render_estado(string $estado, string|null $iframe_url = null): string

Aplica a renderização por estado diretamente sobre a página do módulo ($_GESTOR['pagina']).

Parâmetros

$estadostring
'login' | 'sem-permissao' | 'iframe'.
$iframe_urlstring|null
URL do Iframe (quando 'iframe').

Retorno

string
O próprio estado.

modulo_distribuido_app

ver no código · linha 1207 ↗
modulo_distribuido_app(array $config, array $opcoes = []): array

Orquestração completa do "app" de um módulo distribuído (fachada de alto nível).

Parâmetros

$configarray
Config do canal (de modulo_distribuido_canal_distribuido()).
$opcoesarray
'token', 'token-chave', 'opcao', 'params-iframe', 'central-url',

Retorno

array
Resultado do guardião + 'html' (componente renderizado).

Cadastro de instalações no central

O central reconhece cada instalação distribuída pelo app_id. A leitura é de modulo_distribuido_instalacao($app, $slug), que devolve url, secret, modules e tables, ou false.

  • Sem mais nada, o cadastro é a variável MODULO_DISTRIBUIDO_INSTALLATIONS do .env (JSON por app_id).

  • Um projeto pode manter o cadastro fora do .env e declarar o leitor em $_CONFIG['modulo-distribuido']['installations-provider']: callable(string $app): array|false|null. array é a instalação; false diz que ela existe e está desativada (o .env não é consultado); null diz que o provedor não a conhece, e o .env responde. Falha do provedor recusa a instalação.

Custo por consulta

Cada consulta do módulo original que alcança uma tabela da instalação vira uma chamada HTTP assinada. A conexão é reaproveitada dentro da requisição (modulo_distribuido_http_post() mantém o handle do cURL), e a faxina dos nonces vencidos no banco do cliente é amostrada, de modo que cada consulta custa uma gravação lá, não duas.

O Futuro é Híbrido: Humano + IA.

O Conn2Flow é a ferramenta. Se você precisa do Arquiteto para desenhar a estratégia da sua empresa usando essa tecnologia...

Contrate Consultoria Especializada