From 570190c5f14a595082da6d360f449b2dacfef19c Mon Sep 17 00:00:00 2001 From: admtracksteel Date: Wed, 24 Jun 2026 10:36:19 +0000 Subject: [PATCH] =?UTF-8?q?Atualiza=C3=A7=C3=A3o=20autom=C3=A1tica=20-=202?= =?UTF-8?q?026-06-24=2010:36:19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/standards.json | 61 ++++++++++++++++++++++++++++++++++++ services/aiService.ts | 57 ++++++++++++++++++++++++++++++--- services/validationEngine.ts | 14 +++++++-- 3 files changed, 125 insertions(+), 7 deletions(-) create mode 100644 data/standards.json diff --git a/data/standards.json b/data/standards.json new file mode 100644 index 0000000..27d36d7 --- /dev/null +++ b/data/standards.json @@ -0,0 +1,61 @@ +[ + { + "id": "1719225251000", + "id_norma": "ASTM_A572M", + "codigo": "ASTM A572/A572M", + "grau": "50", + "produto_especifico": "Chapas, perfis estruturais e barras de aço de alta resistência e baixa liga", + "limites_quimicos_corrida": { + "produtos_gerais": [ + { + "espessura_max_mm": 100, + "carbono_max": 0.23, + "manganes_max": 1.35 + }, + { + "espessura_max_mm": 150, + "carbono_max": 0.26, + "manganes_max": 1.35 + } + ] + }, + "tolerancias_analise_produto_astma6": { + "carbono": { + "tabela": [ + { + "limite_corrida_ate": 0.15, + "tolerancia_mais": 0.02 + }, + { + "limite_corrida_ate": 0.4, + "tolerancia_mais": 0.03 + } + ] + }, + "manganes": { + "tabela": [ + { + "limite_corrida_ate": 0.6, + "tolerancia_mais": 0.03 + }, + { + "limite_corrida_ate": 0.9, + "tolerancia_mais": 0.04 + }, + { + "limite_corrida_ate": 1.4, + "tolerancia_mais": 0.05 + } + ] + } + }, + "parametros_controle": { + "mecanicos": { + "limite_escoamento_min": 345, + "resistencia_tracao_min": 450, + "resistencia_tracao_max": 530, + "alongamento_min_50mm": 18 + } + } + } +] diff --git a/services/aiService.ts b/services/aiService.ts index 9845bd3..0a09bc7 100644 --- a/services/aiService.ts +++ b/services/aiService.ts @@ -221,8 +221,19 @@ export const analyzeWithGemini = async (file: File, apiKey: string, model: strin // Apply programmatic validation if (standardsContext && standardsContext.length > 0) { - // Assume the first standard matched is the main one for now - return data.map(report => validateCertificateAgainstStandard(report, standardsContext[0] as Standard)); + let matchedStandard = standardsContext[0] as Standard; + if (data[0] && data[0].identification && data[0].identification.standards) { + const certNorm = data[0].identification.standards.toLowerCase(); + const found = standardsContext.find(s => + (s.codigo && certNorm.includes(s.codigo.toLowerCase())) || + (s.id_norma && certNorm.includes(s.id_norma.toLowerCase().replace(/_/g, ' '))) + ); + if (found) matchedStandard = found; + } + return data.map(report => { + report.analysisSource = 'Banco Local'; + return validateCertificateAgainstStandard(report, matchedStandard); + }); } return data; } catch (e) { @@ -286,7 +297,19 @@ export const analyzeWithOpenAI = async (file: File, apiKey: string, model: strin const dataJson = cleanAndParseJson(content) as ReportData[]; if (standardsContext && standardsContext.length > 0) { - return dataJson.map(report => validateCertificateAgainstStandard(report, standardsContext[0] as Standard)); + let matchedStandard = standardsContext[0] as Standard; + if (dataJson[0] && dataJson[0].identification && dataJson[0].identification.standards) { + const certNorm = dataJson[0].identification.standards.toLowerCase(); + const found = standardsContext.find(s => + (s.codigo && certNorm.includes(s.codigo.toLowerCase())) || + (s.id_norma && certNorm.includes(s.id_norma.toLowerCase().replace(/_/g, ' '))) + ); + if (found) matchedStandard = found; + } + return dataJson.map(report => { + report.analysisSource = 'Banco Local'; + return validateCertificateAgainstStandard(report, matchedStandard); + }); } return dataJson; }; @@ -380,7 +403,19 @@ export const analyzeWithOllama = async (file: File, endpoint: string, model: str const dataJson = cleanAndParseJson(content) as ReportData[]; if (standardsContext && standardsContext.length > 0) { - return dataJson.map(report => validateCertificateAgainstStandard(report, standardsContext[0] as Standard)); + let matchedStandard = standardsContext[0] as Standard; + if (dataJson[0] && dataJson[0].identification && dataJson[0].identification.standards) { + const certNorm = dataJson[0].identification.standards.toLowerCase(); + const found = standardsContext.find(s => + (s.codigo && certNorm.includes(s.codigo.toLowerCase())) || + (s.id_norma && certNorm.includes(s.id_norma.toLowerCase().replace(/_/g, ' '))) + ); + if (found) matchedStandard = found; + } + return dataJson.map(report => { + report.analysisSource = 'Banco Local'; + return validateCertificateAgainstStandard(report, matchedStandard); + }); } return dataJson; }; @@ -444,7 +479,19 @@ export const analyzeWithOpenRouter = async (file: File, apiKey: string, model: s const dataJson = cleanAndParseJson(content) as ReportData[]; if (standardsContext && standardsContext.length > 0) { - return dataJson.map(report => validateCertificateAgainstStandard(report, standardsContext[0] as Standard)); + let matchedStandard = standardsContext[0] as Standard; + if (dataJson[0] && dataJson[0].identification && dataJson[0].identification.standards) { + const certNorm = dataJson[0].identification.standards.toLowerCase(); + const found = standardsContext.find(s => + (s.codigo && certNorm.includes(s.codigo.toLowerCase())) || + (s.id_norma && certNorm.includes(s.id_norma.toLowerCase().replace(/_/g, ' '))) + ); + if (found) matchedStandard = found; + } + return dataJson.map(report => { + report.analysisSource = 'Banco Local'; + return validateCertificateAgainstStandard(report, matchedStandard); + }); } return dataJson; }; diff --git a/services/validationEngine.ts b/services/validationEngine.ts index 54cad2f..683a439 100644 --- a/services/validationEngine.ts +++ b/services/validationEngine.ts @@ -5,7 +5,8 @@ import { ReportData, Standard, ComplianceItem } from '../types'; */ function extractNumber(val: string): number | null { if (!val) return null; - const match = val.match(/-?\d+(\.\d+)?/); + const cleanVal = val.replace(/,/g, '.'); + const match = cleanVal.match(/-?\d+(\.\d+)?/); return match ? parseFloat(match[0]) : null; } @@ -15,7 +16,16 @@ function extractNumber(val: string): number | null { */ function parseThickness(productDesc: string): number { if (!productDesc) return 0; - const match = productDesc.match(/(\d+(\.\d+)?)\s*(mm)/i); + + const cleanDesc = productDesc.replace(/,/g, '.'); + + // Try to find the pattern "num x num x num" (Thickness x Width x Length) + const matchDimensions = cleanDesc.match(/(\d+(?:\.\d+)?)\s*(?:x|X|\*)\s*\d+(?:\.\d+)?\s*(?:x|X|\*)\s*\d+(?:\.\d+)?/); + if (matchDimensions) { + return parseFloat(matchDimensions[1]); + } + + const match = cleanDesc.match(/(\d+(\.\d+)?)\s*(mm)/i); if (match) return parseFloat(match[1]); return 0; // Default or unknown }