Este lote de trabalho (BATCH-047) define a correção necessária no compilador de recursos (atualizacao-dados-recursos.php) para garantir que, quando executado no modo projeto (parâmetro --project-path), os metadados e regras de sincronização das tabelas globais e módulos do núcleo (gestor/) sejam herdados e mesclados no schema-metadata.json do projeto. Isso impede falhas de integridade em chaves naturais (como na tabela modulos) durante o deploy.
1. Arquivo Alvo: gestor/controladores/agents/arquitetura/atualizacao-dados-recursos.php
1.1 Modificação na função gerarSchemaMetadata
Localizar a função gerarSchemaMetadata() e alterar a lógica de leitura das tabelas globais e dos módulos para carregar as definições do núcleo (gestor/) caso a execução seja no modo projeto, mesclando e sobrescrevendo as tabelas sequencialmente.
Código Original:
function gerarSchemaMetadata(): void {
global $RESOURCES_DIR, $MODULES_DIR, $DB_DATA_DIR, $LOG_FILE;
$tables = [];
$deletar = [];
$registrar = function (array $meta, string $source) use (&$tables, &$deletar) {
$norm = normalizarConfigTabela($meta);
if ($norm === null) return;
$nome = $norm['nome'];
$del = $norm['deletar'];
unset($norm['deletar']);
$norm['source'] = $source;
$tables[$nome] = $norm; // registro posterior (módulo) sobrescreve anterior (global)
if ($del) {
$deletar[$nome] = array_merge($deletar[$nome] ?? [], $del);
}
};
// 1) Tabelas globais (sem módulo dono): gestor/resources/tables_config.json
$globalFile = $RESOURCES_DIR . 'tables_config.json';
if (is_file($globalFile)) {
$g = jsonRead($globalFile);
if (is_array($g) && isset($g['tabelas']) && is_array($g['tabelas'])) {
foreach ($g['tabelas'] as $meta) {
if (is_array($meta)) $registrar($meta, 'global:tables_config.json');
}
} else {
log_disco_local('SCHEMA_META_WARN tables_config.json invalido ou sem chave "tabelas"', $LOG_FILE);
}
} else {
log_disco_local('SCHEMA_META_INFO tables_config.json ausente em ' . $globalFile, $LOG_FILE);
}
// 2) Blocos locais "tabela.config" de cada módulo
if (is_dir($MODULES_DIR)) {
foreach (glob($MODULES_DIR . '*', GLOB_ONLYDIR) ?: [] as $modPath) {
$modId = basename($modPath);
$jsonFile = $modPath . DIRECTORY_SEPARATOR . $modId . '.json';
$data = jsonRead($jsonFile);
if (!is_array($data)) continue;
$tabela = $data['tabela'] ?? null;
if (is_array($tabela) && !empty($tabela['config'])) {
$registrar($tabela, 'module:' . $modId);
}
}
}Código Modificado:
function gerarSchemaMetadata(): void {
global $RESOURCES_DIR, $MODULES_DIR, $DB_DATA_DIR, $LOG_FILE, $SYSTEM_PATH;
$tables = [];
$deletar = [];
$registrar = function (array $meta, string $source) use (&$tables, &$deletar) {
$norm = normalizarConfigTabela($meta);
if ($norm === null) return;
$nome = $norm['nome'];
$del = $norm['deletar'];
unset($norm['deletar']);
$norm['source'] = $source;
$tables[$nome] = $norm; // registro posterior (módulo) sobrescreve anterior (global)
if ($del) {
$deletar[$nome] = array_merge($deletar[$nome] ?? [], $del);
}
};
// 1) Tabelas globais (sem módulo dono): gestor/resources/tables_config.json
// Se estiver em modo projeto, carrega primeiro os arquivos do núcleo/sistema (gestor/)
$arquivosGlobais = [];
if (!empty($GLOBALS['CLI_ARGS']['project-path'])) {
$coreGlobal = $SYSTEM_PATH . 'gestor' . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'tables_config.json';
if (is_file($coreGlobal)) {
$arquivosGlobais[] = [$coreGlobal, 'core:tables_config.json'];
}
}
$arquivosGlobais[] = [$RESOURCES_DIR . 'tables_config.json', 'global:tables_config.json'];
foreach ($arquivosGlobais as [$globalFile, $srcLabel]) {
if (is_file($globalFile)) {
$g = jsonRead($globalFile);
if (is_array($g) && isset($g['tabelas']) && is_array($g['tabelas'])) {
foreach ($g['tabelas'] as $meta) {
if (is_array($meta)) $registrar($meta, $srcLabel);
}
} else {
log_disco_local('SCHEMA_META_WARN ' . basename($globalFile) . ' invalido ou sem chave "tabelas"', $LOG_FILE);
}
} else {
log_disco_local('SCHEMA_META_INFO ' . basename($globalFile) . ' ausente em ' . $globalFile, $LOG_FILE);
}
}
// 2) Blocos locais "tabela.config" de cada módulo
// Se estiver em modo projeto, também varre os módulos do núcleo/sistema (gestor/modulos/)
$pastasModulos = [];
if (!empty($GLOBALS['CLI_ARGS']['project-path'])) {
$coreModDir = $SYSTEM_PATH . 'gestor' . DIRECTORY_SEPARATOR . 'modulos' . DIRECTORY_SEPARATOR;
if (is_dir($coreModDir)) {
$pastasModulos[] = [$coreModDir, 'core:'];
}
}
$pastasModulos[] = [$MODULES_DIR, 'module:'];
foreach ($pastasModulos as [$mDir, $srcPrefix]) {
if (is_dir($mDir)) {
foreach (glob($mDir . '*', GLOB_ONLYDIR) ?: [] as $modPath) {
$modId = basename($modPath);
$jsonFile = $modPath . DIRECTORY_SEPARATOR . $modId . '.json';
$data = jsonRead($jsonFile);
if (!is_array($data)) continue;
$tabela = $data['tabela'] ?? null;
if (is_array($tabela) && !empty($tabela['config'])) {
$registrar($tabela, $srcPrefix . $modId);
}
}
}
}2. Verificação de Sucesso para o Executor
-
Executar o compilador de recursos apontando para o site local de testes:
php gestor/controladores/agents/arquitetura/atualizacao-dados-recursos.php --project-path=dev-environment/data/sites/localhost/photon -
Validar que o arquivo
dev-environment/data/sites/localhost/photon/db/data/schema-metadata.jsonfoi gerado/atualizado e contém as tabelas do núcleo com a estratégia correta (ex:moduloscom"strategy": "natural_key"e as"natural_key_columns"correspondentes). -
Executar o atualizador no ambiente docker em modo dry-run e debug para a tabela modulos:
docker exec [REDACTED] php [REDACTED] --dry-run --debug --tables=modulos -
Verificar que a sincronização ocorre no modo correto (
SYNC_INI tabela=modulos modo=natural) e é finalizada com sucesso sem gerar erros de constraint de integridade.