/** * 🤖 AGENTE DE INTEGRIDADE DE DADOS * * Implementação programática do agente de validação de integridade de dados */ export class DataIntegrityAgent { constructor() { this.name = 'DataIntegrityAgent'; this.description = 'Valida integridade e mapeamento de dados front-back'; // Personalidade e Background this.personality = { name: 'Dr. Data "The Mapper"', traits: [ 'Analítico e preciso', 'Obsessivo com detalhes de dados', 'Sistemático e organizado', 'Cético até provar o contrário', 'Valoriza documentação e tipos' ], quirks: [ 'Sempre verifica null/undefined antes de confiar', 'Tem uma memória fotográfica de estruturas de dados', 'Fica incomodado quando vê dados sem tipagem', 'Prefere JSDoc detalhado a código sem documentação' ], catchphrases: [ 'E se esse campo vier null?', 'Onde está a tipagem disso?', 'Isso está mapeado corretamente?', 'Precisamos validar esse dado antes de usar' ] }; this.background = { origin: 'Ex-backend developer que migrou para frontend e viu o caos de dados não tipados', motivation: 'Garantir que nenhum dado seja perdido ou corrompido na jornada front-back', experience: '8 anos trabalhando com APIs e mapeamento de dados', turningPoint: 'Perdeu um fim de semana inteiro debugando um bug causado por um campo null não tratado', philosophy: 'Dados são sagrados - devem ser tratados com respeito e precisão', relationships: { withBrowserValidation: 'Trabalham em parceria - ele valida o fluxo, eu valido os dados', withSecurity: 'Compartilha a preocupação com integridade, mas foca em dados, não em segurança', withDocumentation: 'Aprecia muito a documentação que ele mantém' } }; } /** * Valida um componente * @param {string|Object} component - Componente ou caminho * @param {Object} context - Contexto * @returns {Promise} */ async validate(component, context = {}) { const errors = []; const warnings = []; const metadata = {}; const componentPath = typeof component === 'string' ? component : component.path; const componentCode = context.code || await this.readComponent(componentPath); if (!componentCode) { return { passed: false, errors: ['Não foi possível ler o componente'], warnings: [], metadata: {} }; } // 1. Verificar null-safety const hasNullSafety = this.hasNullSafetyChecks(componentCode); if (!hasNullSafety && this.usesApiData(componentCode)) { warnings.push('Componente pode não estar tratando valores null/undefined da API'); } // 2. Verificar formatação de dados const needsFormatting = this.needsDataFormatting(componentCode); if (needsFormatting && !this.hasFormatting(componentCode)) { warnings.push('Dados podem precisar de formatação (datas, moedas, CPF/CNPJ)'); } // 3. Verificar uso de Service para mapeamento const usesDirectApi = this.usesDirectApi(componentCode); if (usesDirectApi) { warnings.push('Comunicação com API deve ser feita via Services para melhor mapeamento de dados'); } // 4. Verificar tratamento de valores falsy const hasFalsyIssues = this.hasFalsyValueIssues(componentCode); if (hasFalsyIssues) { warnings.push('Pode haver problemas com valores 0 ou false sendo ocultados erroneamente'); } // 5. Verificar sincronização de estado const hasStateSync = this.hasStateSynchronization(componentCode); if (!hasStateSync && this.hasDataUpdates(componentCode)) { warnings.push('Atualizações de dados podem não estar sincronizando com a interface'); } // 6. Verificar JSDoc/types const hasTypeDocumentation = this.hasTypeDocumentation(componentCode); if (!hasTypeDocumentation && this.usesComplexData(componentCode)) { warnings.push('Componente pode se beneficiar de documentação de tipos (JSDoc)'); } const passed = errors.length === 0; return { passed, errors, warnings, metadata: { hasNullSafety, hasFormatting, hasTypeDocumentation, ...metadata } }; } /** * Verifica se tem checks de null-safety * @param {string} code - Código * @returns {boolean} */ hasNullSafetyChecks(code) { const nullSafetyPatterns = [ '?.', '??', 'optional chaining', 'nullish', '||', 'if (', '&&', '?.map', '?.filter' ]; return nullSafetyPatterns.some(pattern => code.includes(pattern)); } /** * Verifica se usa dados de API * @param {string} code - Código * @returns {boolean} */ usesApiData(code) { return code.includes('data') || code.includes('response') || code.includes('api') || code.includes('fetch') || code.includes('axios'); } /** * Verifica se precisa de formatação * @param {string} code - Código * @returns {boolean} */ needsDataFormatting(code) { return code.includes('date') || code.includes('Date') || code.includes('price') || code.includes('value') || code.includes('cpf') || code.includes('cnpj') || code.includes('CPF') || code.includes('CNPJ'); } /** * Verifica se tem formatação * @param {string} code - Código * @returns {boolean} */ hasFormatting(code) { return code.includes('format') || code.includes('Format') || code.includes('toLocaleString') || code.includes('toFixed') || code.includes('Intl') || code.includes('mask'); } /** * Verifica se usa API diretamente * @param {string} code - Código * @returns {boolean} */ usesDirectApi(code) { return (code.includes('axios') || code.includes('fetch')) && !code.includes('Service') && !code.includes('service'); } /** * Verifica problemas com valores falsy * @param {string} code - Código * @returns {boolean} */ hasFalsyValueIssues(code) { // Padrões problemáticos: && data.value (oculta 0), !data (oculta false) const problematicPatterns = [ '&& data.', '&& item.', '&& value.', '!data &&', '!item &&', '!value &&' ]; return problematicPatterns.some(pattern => code.includes(pattern)); } /** * Verifica sincronização de estado * @param {string} code - Código * @returns {boolean} */ hasStateSynchronization(code) { return code.includes('useState') || code.includes('useEffect') || code.includes('refetch') || code.includes('invalidate') || code.includes('setState') || code.includes('update'); } /** * Verifica se tem atualizações de dados * @param {string} code - Código * @returns {boolean} */ hasDataUpdates(code) { return code.includes('update') || code.includes('edit') || code.includes('save') || code.includes('submit') || code.includes('create') || code.includes('delete'); } /** * Verifica se usa dados complexos * @param {string} code - Código * @returns {boolean} */ usesComplexData(code) { return code.includes('object') || code.includes('array') || code.includes('interface') || code.includes('type ') || code.includes('{') && code.includes('}'); } /** * Verifica se tem documentação de tipos * @param {string} code - Código * @returns {boolean} */ hasTypeDocumentation(code) { return code.includes('/**') || code.includes('@typedef') || code.includes('@param') || code.includes('@property') || code.includes('interface') || code.includes('type '); } /** * Lê o conteúdo do componente * @param {string} path - Caminho do arquivo * @returns {Promise} */ async readComponent(path) { try { const fs = await import('fs/promises'); return await fs.readFile(path, 'utf-8'); } catch (error) { return null; } } }