This commit is contained in:
Kenio 2025-11-16 10:44:52 -03:00
parent cc8606ba98
commit 40d39b51f1

View file

@ -13,14 +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 AUXILIAR PARA COMPARAÇÃO DE CAMPOS ---
def compare_fields(standard_fields: List[Dict], client_fields: List[Dict], table_name: str) -> List[Dict]:
"""
Compara os campos de uma tabela entre as estruturas padrão e cliente,
retornando apenas os nomes dos campos/atributos divergentes.
Compara os campos de uma tabela entre as estruturas padrão e cliente.
(Mantida sem alteração, pois SOURCE_CODE não é um campo de tabela, mas de triggers/procedures).
"""
discrepancies = []
@ -64,7 +65,7 @@ def compare_fields(standard_fields: List[Dict], client_fields: List[Dict], table
return discrepancies
# --- FUNÇÃO PRINCIPAL DE COMPARAÇÃO DE ESTRUTURAS (AJUSTADA COM FILTRO E DEBUG) ---
# --- FUNÇÃO PRINCIPAL DE COMPARAÇÃO DE ESTRUTURAS (AJUSTADA: Ignorando SOURCE_CODE) ---
def compare_structures(standard_structure: Dict[str, Any], client_structure: Dict[str, Any]) -> Dict[str, Any]:
@ -76,7 +77,7 @@ def compare_structures(standard_structure: Dict[str, Any], client_structure: Dic
"divergencia_de_campos": [],
"estrutura_malformada_cliente": None
},
"elementos_ignorados": { # Novo campo para armazenar o que foi filtrado
"elementos_ignorados": {
"tabelas_padrao": [],
"tabelas_cliente": [],
"outros_elementos": []
@ -99,24 +100,32 @@ def compare_structures(standard_structure: Dict[str, Any], client_structure: Dic
item.get('PROCEDURE_NAME') or
item.get('TRIGGER_NAME')
)
# --- FUNÇÃO HELPER PARA NORMALIZAR ---
def normalize_element_for_comparison(item: Dict) -> Dict:
"""Remove SOURCE_CODE para comparação, usando uma cópia para proteger o original."""
item_copy = item.copy()
if 'SOURCE_CODE' in item_copy:
del item_copy['SOURCE_CODE']
return item_copy
# --- 1. AUDITORIA DE TABELAS ---
# 1.1 Filtragem e Mapeamento Padrão
# ... (Lógica de filtragem de tabelas 'CONVERSAO' e mapeamento) ...
standard_tables_filtered = []
for t in standard_structure.get('tables', []):
table_name = t.get('TABLE_NAME')
if is_ignored(table_name):
audit_log["elementos_ignorados"]["tabelas_padrao"].append({
"identificador": table_name,
"estrutura_completa": t # Conteúdo completo para debug
"estrutura_completa": t
})
elif table_name:
standard_tables_filtered.append(t)
standard_tables_map = {t['TABLE_NAME']: t for t in standard_tables_filtered}
# 1.2 Mapeamento Cliente (com filtro e tratamento de KeyError)
client_tables_map = {}
malformed_tables_data = []
@ -126,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": t # Conteúdo completo para debug
"estrutura_completa": t
})
elif table_name:
client_tables_map[table_name] = t
@ -140,7 +149,6 @@ def compare_structures(standard_structure: Dict[str, Any], client_structure: Dic
"total_objetos_ignorados": len(malformed_tables_data)
}
# 1.3 Compara e busca divergências de campos nas tabelas filtradas
missing_tables = standard_tables_map.keys() - client_tables_map.keys()
if missing_tables:
audit_log["discrepancias_encontradas"] = True
@ -169,15 +177,13 @@ def compare_structures(standard_structure: Dict[str, Any], client_structure: Dic
standard_elements = standard_structure.get(element_key, [])
client_elements = client_structure.get(element_key, [])
# 2.1 Filtragem de elementos "CONVERSAO"
standard_elements_filtered = []
for item in standard_elements:
identifier = get_element_identifier(item)
if is_ignored(identifier):
audit_log["elementos_ignorados"]["outros_elementos"].append({
"origem": "padrao",
"tipo": element_key,
"identificador": identifier,
"estrutura_completa": item
"origem": "padrao", "tipo": element_key, "identificador": identifier, "estrutura_completa": item
})
else:
standard_elements_filtered.append(item)
@ -187,22 +193,24 @@ def compare_structures(standard_structure: Dict[str, Any], client_structure: Dic
identifier = get_element_identifier(item)
if is_ignored(identifier):
audit_log["elementos_ignorados"]["outros_elementos"].append({
"origem": "cliente",
"tipo": element_key,
"identificador": identifier,
"estrutura_completa": item
"origem": "cliente", "tipo": element_key, "identificador": identifier, "estrutura_completa": item
})
else:
client_elements_filtered.append(item)
# 2.2 Normalização (Remoção de SOURCE_CODE) e Criação de Sets
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]
try:
standard_set = {json.dumps(item, sort_keys=True) for item in standard_elements_filtered}
client_set = {json.dumps(item, sort_keys=True) for item in client_elements_filtered}
standard_set = {json.dumps(item, sort_keys=True) for item in standard_elements_normalized}
client_set = {json.dumps(item, sort_keys=True) for item in client_elements_normalized}
except TypeError:
audit_log["discrepancias_encontradas"] = True
audit_log["detalhes"]["erro_serializacao"] = f"Erro ao comparar {element_key}. Os dados podem estar malformados."
continue
# 2.3 Compara os sets
missing_elements = standard_set - client_set
if missing_elements:
@ -229,15 +237,11 @@ class ShowDatabaseService:
log_show_database_action = ShowDatabaseAction()
# Executa a ação
dados_completos = log_show_database_action.execute(client_id_schema)
if dados_completos and dados_completos.get("file"):
# 1. Parsing do Log do Cliente
dados_json = json.loads(dados_completos["file"])
# 2. Extração e Parsing da Estrutura Padrão
standard_structure_json_string = dados_completos.get("standard_structure_json")
standard_structure_data: Dict[str, Any] = {}
if standard_structure_json_string:
@ -247,17 +251,15 @@ class ShowDatabaseService:
pass
database_data = dados_json.get("database", {})
# 3. Extração da Estrutura do Cliente
client_structure: Dict[str, Any] = database_data.get("structure", {})
# 4. Efetua a auditoria
# Efetua a auditoria
auditoria_do_banco = compare_structures(
standard_structure_data, # Estrutura padrão
client_structure # Estrutura do cliente
)
# 5. Monta o JSON final (INCLUINDO ESTRUTURAS PARA DEBUG)
# Monta o JSON final (INCLUINDO ESTRUTURAS PARA DEBUG)
data = {
"cns": dados_json.get("cns"),
"cartorio": dados_json.get("cartorio"),