This commit is contained in:
Kenio 2025-11-16 10:58:51 -03:00
parent 89dca4881a
commit 81a1c04934

View file

@ -13,13 +13,15 @@ def is_ignored(name: str) -> bool:
"""Verifica se o nome contém a substring de filtro (case-insensitive)."""
if name is None:
return False
# Garante que a comparação é feita em caixa alta para robustez
return FILTER_SUBSTRING in str(name).upper()
# --- FUNÇÃO HELPER PARA NORMALIZAÇÃO (REMOÇÃO DE SOURCE_CODE) ---
# --- FUNÇÃO HELPER PARA REMOÇÃO DE SOURCE_CODE ---
def normalize_element_for_comparison(item: Dict) -> Dict:
"""Remove SOURCE_CODE para comparação e debug, usando uma cópia para proteger o original."""
def _remove_source_code(item: Dict) -> Dict:
"""
Remove o campo 'SOURCE_CODE' de um item de dicionário.
Usado para garantir que o código-fonte nunca seja retornado/comparado.
"""
item_copy = item.copy()
if 'SOURCE_CODE' in item_copy:
del item_copy['SOURCE_CODE']
@ -73,7 +75,7 @@ def compare_fields(standard_fields: List[Dict], client_fields: List[Dict], table
return discrepancies
# --- FUNÇÃO PRINCIPAL DE COMPARAÇÃO DE ESTRUTURAS (AJUSTADA: Ignorando SOURCE_CODE em LOGS) ---
# --- FUNÇÃO PRINCIPAL DE COMPARAÇÃO DE ESTRUTURAS ---
def compare_structures(standard_structure: Dict[str, Any], client_structure: Dict[str, Any]) -> Dict[str, Any]:
@ -117,7 +119,7 @@ def compare_structures(standard_structure: Dict[str, Any], client_structure: Dic
if is_ignored(table_name):
audit_log["elementos_ignorados"]["tabelas_padrao"].append({
"identificador": table_name,
"estrutura_completa": normalize_element_for_comparison(t) # Removendo SOURCE_CODE
"estrutura_completa": _remove_source_code(t) # Limpeza de SOURCE_CODE
})
elif table_name:
standard_tables_filtered.append(t)
@ -133,7 +135,7 @@ def compare_structures(standard_structure: Dict[str, Any], client_structure: Dic
if is_ignored(table_name):
audit_log["elementos_ignorados"]["tabelas_cliente"].append({
"identificador": table_name,
"estrutura_completa": normalize_element_for_comparison(t) # Removendo SOURCE_CODE
"estrutura_completa": _remove_source_code(t) # Limpeza de SOURCE_CODE
})
elif table_name:
client_tables_map[table_name] = t
@ -183,7 +185,7 @@ def compare_structures(standard_structure: Dict[str, Any], client_structure: Dic
"origem": "padrao",
"tipo": element_key,
"identificador": identifier,
"estrutura_completa": normalize_element_for_comparison(item) # Removendo SOURCE_CODE
"estrutura_completa": _remove_source_code(item) # Limpeza de SOURCE_CODE
})
else:
standard_elements_filtered.append(item)
@ -196,14 +198,15 @@ def compare_structures(standard_structure: Dict[str, Any], client_structure: Dic
"origem": "cliente",
"tipo": element_key,
"identificador": identifier,
"estrutura_completa": normalize_element_for_comparison(item) # Removendo SOURCE_CODE
"estrutura_completa": _remove_source_code(item) # Limpeza de SOURCE_CODE
})
else:
client_elements_filtered.append(item)
# Criação de Sets a partir dos elementos normalizados (sem SOURCE_CODE)
standard_elements_normalized = [normalize_element_for_comparison(item) for item in standard_elements_filtered]
client_elements_normalized = [normalize_element_for_comparison(item) for item in client_elements_filtered]
# Usamos _remove_source_code para a comparação (como "normalizer")
standard_elements_normalized = [_remove_source_code(item) for item in standard_elements_filtered]
client_elements_normalized = [_remove_source_code(item) for item in client_elements_filtered]
try:
standard_set = {json.dumps(item, sort_keys=True) for item in standard_elements_normalized}
@ -231,24 +234,31 @@ def compare_structures(standard_structure: Dict[str, Any], client_structure: Dic
return audit_log
# --- CLASSE PRINCIPAL DE SERVIÇO (APLICA FILTRO EM DEBUG STRUCTURES) ---
# --- CLASSE PRINCIPAL DE SERVIÇO ---
class ShowDatabaseService:
# NEW HELPER: Filtra SOURCE_CODE das estruturas de DEBUG
def _filter_source_code_recursively(self, structure: Dict[str, Any]) -> Dict[str, Any]:
"""Remove SOURCE_CODE de qualquer elemento em um dicionário de estrutura."""
# Usa json.dumps/loads para uma cópia profunda eficiente
filtered_structure = json.loads(json.dumps(structure))
# Novo Helper: Função dedicada para limpar a estrutura completa de debug antes do retorno
def _clean_full_structure_for_output(self, structure: Dict[str, Any]) -> Dict[str, Any]:
"""Cria uma cópia limpa da estrutura, removendo 'SOURCE_CODE' em todos os elementos relevantes."""
# Garante deep copy de toda a estrutura
cleaned = json.loads(json.dumps(structure))
keys_to_filter = ['tables', 'views', 'procedures', 'triggers', 'primary_keys', 'foreign_keys', 'indexes']
keys_to_clean = ['tables', 'views', 'procedures', 'triggers', 'primary_keys', 'foreign_keys', 'indexes']
for key in keys_to_filter:
if key in filtered_structure and isinstance(filtered_structure[key], list):
# Filtra a lista inteira, usando normalize_element_for_comparison que já lida com SOURCE_CODE
filtered_structure[key] = [normalize_element_for_comparison(item) for item in filtered_structure[key]]
for key in keys_to_clean:
if key in cleaned and isinstance(cleaned[key], list):
# Aplica a limpeza a cada item da lista usando a função helper _remove_source_code
cleaned[key] = [_remove_source_code(item) for item in cleaned[key]]
return filtered_structure
# Garante que, se houver campos (FIELDS) aninhados, eles também sejam limpos (apesar de SOURCE_CODE
# não ser comum em FIELDS, é uma camada extra de segurança)
if 'tables' in cleaned and isinstance(cleaned['tables'], list):
for table in cleaned['tables']:
if 'FIELDS' in table and isinstance(table['FIELDS'], list):
table['FIELDS'] = [_remove_source_code(field) for field in table['FIELDS']]
return cleaned
def execute(self, client_id_schema: LogClientIdSchema):
@ -272,13 +282,13 @@ class ShowDatabaseService:
# Efetua a auditoria
auditoria_do_banco = compare_structures(
standard_structure_data, # Estrutura padrão
client_structure # Estrutura do cliente
standard_structure_data,
client_structure
)
# Filtra SOURCE_CODE das estruturas de DEBUG antes de retornar
debug_cliente = self._filter_source_code_recursively(client_structure)
debug_padrao = self._filter_source_code_recursively(standard_structure_data)
# Filtra SOURCE_CODE das estruturas de DEBUG usando o novo helper
debug_cliente = self._clean_full_structure_for_output(client_structure)
debug_padrao = self._clean_full_structure_for_output(standard_structure_data)
# Monta o JSON final
data = {
@ -292,10 +302,10 @@ class ShowDatabaseService:
"db_accessible": database_data.get("db_accessible", {}),
"last_modified": database_data.get("last_modified", {}),
# --- CAMPOS DE DEBUG (AGORA FILTRADOS) ---
# --- CAMPOS DE DEBUG (AGORA TOTALMENTE FILTRADOS) ---
"estrutura_cliente_debug": debug_cliente,
"estrutura_padrao_debug": debug_padrao,
# ----------------------------------------
# ----------------------------------------------------
"auditoria_do_banco": auditoria_do_banco
}