diff --git a/packages/v1/administrativo/services/log/log_show_database_service.py b/packages/v1/administrativo/services/log/log_show_database_service.py index 2231037..57adc1d 100644 --- a/packages/v1/administrativo/services/log/log_show_database_service.py +++ b/packages/v1/administrativo/services/log/log_show_database_service.py @@ -16,12 +16,20 @@ def is_ignored(name: str) -> bool: # 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) --- + +def normalize_element_for_comparison(item: Dict) -> Dict: + """Remove SOURCE_CODE para comparação e debug, 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 + # --- 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. - (Mantida sem alteração, pois SOURCE_CODE não é um campo de tabela, mas de triggers/procedures). """ discrepancies = [] @@ -65,7 +73,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) --- +# --- FUNÇÃO PRINCIPAL DE COMPARAÇÃO DE ESTRUTURAS (AJUSTADA: Ignorando SOURCE_CODE em LOGS) --- def compare_structures(standard_structure: Dict[str, Any], client_structure: Dict[str, Any]) -> Dict[str, Any]: @@ -100,26 +108,16 @@ 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 --- - # ... (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 + "estrutura_completa": normalize_element_for_comparison(t) # Removendo SOURCE_CODE }) elif table_name: standard_tables_filtered.append(t) @@ -135,7 +133,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 + "estrutura_completa": normalize_element_for_comparison(t) # Removendo SOURCE_CODE }) elif table_name: client_tables_map[table_name] = t @@ -177,13 +175,15 @@ 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": normalize_element_for_comparison(item) # Removendo SOURCE_CODE }) else: standard_elements_filtered.append(item) @@ -193,12 +193,15 @@ 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": normalize_element_for_comparison(item) # Removendo SOURCE_CODE }) else: client_elements_filtered.append(item) - # 2.2 Normalização (Remoção de SOURCE_CODE) e Criação de Sets + # 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] @@ -210,7 +213,6 @@ def compare_structures(standard_structure: Dict[str, Any], client_structure: Dic 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,9 +231,24 @@ def compare_structures(standard_structure: Dict[str, Any], client_structure: Dic return audit_log -# --- CLASSE PRINCIPAL DE SERVIÇO (MANTIDA PARA DEBUG) --- +# --- CLASSE PRINCIPAL DE SERVIÇO (APLICA FILTRO EM DEBUG STRUCTURES) --- 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)) + + keys_to_filter = ['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]] + + return filtered_structure def execute(self, client_id_schema: LogClientIdSchema): @@ -259,7 +276,11 @@ class ShowDatabaseService: client_structure # Estrutura do cliente ) - # Monta o JSON final (INCLUINDO ESTRUTURAS PARA DEBUG) + # 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) + + # Monta o JSON final data = { "cns": dados_json.get("cns"), "cartorio": dados_json.get("cartorio"), @@ -271,10 +292,10 @@ class ShowDatabaseService: "db_accessible": database_data.get("db_accessible", {}), "last_modified": database_data.get("last_modified", {}), - # --- CAMPOS DE DEBUG SOLICITADOS --- - "estrutura_cliente_debug": client_structure, - "estrutura_padrao_debug": standard_structure_data, - # ---------------------------------- + # --- CAMPOS DE DEBUG (AGORA FILTRADOS) --- + "estrutura_cliente_debug": debug_cliente, + "estrutura_padrao_debug": debug_padrao, + # ---------------------------------------- "auditoria_do_banco": auditoria_do_banco }