From b4a39d82af5706c6beb257a58c3f460ce99d8b90 Mon Sep 17 00:00:00 2001 From: Kenio de Souza Date: Sat, 15 Nov 2025 11:04:51 -0300 Subject: [PATCH] feat(): Criando auditoria de banco de dados --- .../log/log_show_database_repository.py | 28 +++++++- .../services/log/log_show_database_service.py | 70 ++++++++++++++++++- 2 files changed, 93 insertions(+), 5 deletions(-) diff --git a/packages/v1/administrativo/repositories/log/log_show_database_repository.py b/packages/v1/administrativo/repositories/log/log_show_database_repository.py index 0a32a47..348c71a 100644 --- a/packages/v1/administrativo/repositories/log/log_show_database_repository.py +++ b/packages/v1/administrativo/repositories/log/log_show_database_repository.py @@ -1,5 +1,4 @@ from abstracts.repository import BaseRepository - from packages.v1.administrativo.schemas.log_schema import LogClientIdSchema @@ -27,4 +26,29 @@ class ShowDatabaseRepository(BaseRepository): } # Execução da instrução sql para buscar um único registro - return self.fetch_one(sql, params) \ No newline at end of file + log_database = self.fetch_one(sql, params) + + # Se não encontrar o log, retorna None para o Service lidar com o 404 + if not log_database: + return None + + # 2. Busca da estrutura de referência (padrão) + # Assumindo que a estrutura mais recente é a última inserida (ou a única) + sql_standard_structure = """ + SELECT structure FROM firebird_schema ORDER BY id DESC LIMIT 1 + """ + + # Execução para buscar a estrutura padrão (sem parâmetros) + structure_database = self.fetch_one(sql_standard_structure) + + # O campo 'structure' contém o JSON da estrutura padrão (como string) + standard_structure_json = structure_database.get('structure') if structure_database else None + + # 3. Combinação dos resultados + # Adiciona a string JSON da estrutura padrão ao dicionário de dados do log + data = { + **log_database, + "standard_structure_json": standard_structure_json + } + + return data \ No newline at end of file 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 0a65830..56e3dce 100644 --- a/packages/v1/administrativo/services/log/log_show_database_service.py +++ b/packages/v1/administrativo/services/log/log_show_database_service.py @@ -7,6 +7,51 @@ import json from packages.v1.administrativo.schemas.log_schema import LogClientIdSchema from packages.v1.administrativo.actions.log.log_show_database_action import ShowDatabaseAction + +# --- NOVA FUNÇÃO AUXILIAR DE COMPARAÇÃO --- +def compare_structures(standard_structure: dict, client_structure: dict) -> dict: + """ + Compara a estrutura do cliente com a estrutura padrão e lista as discrepâncias. + ESTA FUNÇÃO DEVE SER IMPLEMENTADA COM A LÓGICA DE NEGÓCIO COMPLETA. + O exemplo abaixo é uma simulação básica de comparação de tabelas. + """ + discrepancies = { + "discrepancias_encontradas": False, + "detalhes": {} + } + + # Se a estrutura padrão estiver vazia, não há como comparar. + if not standard_structure: + discrepancies["detalhes"]["erro_comparacao"] = "Estrutura padrão de referência não encontrada ou está vazia." + return discrepancies + + # 1. Comparação de Tabelas + try: + standard_tables = {item["TABLE_NAME"]: item for item in standard_structure.get("tables", [])} + client_tables = {item["TABLE_NAME"]: item for item in client_structure.get("tables", [])} + + missing_tables = standard_tables.keys() - client_tables.keys() + + if missing_tables: + discrepancies["discrepancias_encontradas"] = True + discrepancies["detalhes"]["tabelas_faltando"] = list(missing_tables) + + # Adicione aqui a lógica para verificar campos, PKs, FKs, etc. + # Exemplo: Verificar se os campos da tabela 'CLIENTES' estão no cliente + # if 'CLIENTES' in standard_tables and 'CLIENTES' in client_tables: + # standard_fields = standard_tables['CLIENTES']['FIELDS'] # Assumindo um formato mais detalhado + # client_fields = client_tables['CLIENTES']['FIELDS'] + # # ... lógica de comparação de campos + + except Exception as e: + # Em caso de erro na estrutura JSON (malformada) + discrepancies["discrepancias_encontradas"] = True + discrepancies["detalhes"]["erro_processamento"] = f"Erro ao processar estruturas para comparação: {e}" + + + return discrepancies +# --- FIM DA NOVA FUNÇÃO AUXILIAR DE COMPARAÇÃO --- + class ShowDatabaseService: # O método execute deve receber o esquema que contém a ID do log a ser buscado @@ -16,7 +61,7 @@ class ShowDatabaseService: log_show_database_action = ShowDatabaseAction() # Executa a ação em questão (buscando pelo log_id) - dados = log_show_database_action.execute(client_id_schema) + dados = log_show_database_action.execute(client_id_schema) # verifica se 'dados' não é None e contém 'file' if dados and dados.get("file"): @@ -24,6 +69,19 @@ class ShowDatabaseService: # Converte a string JSON armazenada no campo 'file' de volta para um dicionário dados_json = json.loads(dados["file"]) + # Informações da estrutura de referência (JSON em formato string) + standard_structure_json_string = dados.get("standard_structure_json") + + # Converte a string JSON da estrutura padrão para dicionário, se existir + standard_structure_data = {} + if standard_structure_json_string: + try: + # O 'structure' já é um JSON que foi salvo pelo FirebirdSchemaExtractor + standard_structure_data = json.loads(standard_structure_json_string) + except json.JSONDecodeError as e: + print(f"[ERRO] Falha ao decodificar JSON da estrutura padrão: {e}") + # Pode-se forçar um erro ou continuar com um dict vazio, dependendo da regra de negócio + """ Separa as informações de database em: - 'partition': informações de disco do database @@ -46,7 +104,13 @@ class ShowDatabaseService: last_modified = database_data.get("last_modified", {}) # 6 Separa o campo 'structure' das demais chaves - structure = database_data.get("structure", {}) + client_structure = database_data.get("structure", {}) + + # 7️ Efetua a auditoria comparando as duas estruturas + audit = compare_structures( + standard_structure_data, # Estrutura padrão (atualizada) + client_structure # Estrutura do cliente + ) # 7 Monta o JSON final data = { @@ -59,7 +123,7 @@ class ShowDatabaseService: "file_size_mb": file_size_mb, "db_accessible": db_accessible, "last_modified": last_modified, - "structure": structure + "audit": audit } }