Files
Investidor-V2/tools/financial-institutions-proof.mjs

43 lines
5.9 KiB
JavaScript

import fs from 'node:fs';
import assert from 'node:assert/strict';
import {compileFunction} from 'node:vm';
import {createRequire} from 'node:module';
import {createHash} from 'node:crypto';
import ts from 'typescript';
import React from 'react';
import {renderToStaticMarkup} from 'react-dom/server';
const require=createRequire(import.meta.url),root=new URL('../',import.meta.url),out=new URL('outputs/funding-directory-20261110/institutions/',root);
const native=JSON.parse(fs.readFileSync(new URL('content.json',out),'utf8'));
const source=JSON.parse(fs.readFileSync(new URL('database/data/funding-institutions-nov2026.json',root),'utf8'));
const records=Object.values(native.records),ids=Object.fromEntries(records.map(r=>[r.id,r.code]));
assert.equal(records.length,270);assert.equal(new Set(records.map(r=>r.payload.institution_key)).size,270);
assert.equal(source.source.sha256,'119bb5514d2777849b70aebfec21d28a41885cbdc7d9827fbebd764fe994c108');
assert.equal(source.source_coverage.length,509);
for(const row of source.source_coverage){if(row.status.startsWith('represented'))assert.ok(row.institutions.every(key=>native.records[key]));else assert.equal(row.status,'aggregate_or_gap_not_an_institution');}
assert.ok(native.nampula_insurers.includes('arko'));assert.ok(!native.nampula_insurers.includes('bci'));
assert.equal(native.dossier_recovered.selections.length,2);
const chosen=native.dossier_recovered.selections[1];assert.equal(chosen.need,'insurance');assert.equal(chosen.institution_key,'arko');assert.equal(chosen.location.source_document_sha256,source.source.sha256);assert.ok(chosen.institution_types.includes('insurer'));
const cache={};
function load(file){
if(cache[file])return cache[file];
const module={exports:{}};cache[file]=module.exports;
const code=ts.transpileModule(fs.readFileSync(new URL('resources/js/'+file,root),'utf8'),{compilerOptions:{module:ts.ModuleKind.CommonJS,target:ts.ScriptTarget.ES2022,jsx:ts.JsxEmit.ReactJSX}}).outputText;
compileFunction(code,['require','module','exports'])(name=>{
if(name==='@inertiajs/react')return {Link:({href,children,...props})=>{let target=href;if(href==='/fundos')target='../catalogo-qa.html';else if(typeof href==='string'&&href.startsWith('/fundos/')){const id=href.split('/')[2].split('?')[0];if(ids[id])target='fichas/'+ids[id]+'.html';}return React.createElement('a',{...props,href:target},children);},useForm:data=>({data,processing:false,setData:()=>{},get:()=>{}}),router:{}};
if(name==='@/pages/investment/shared')return {Frame:({title,children})=>React.createElement('main',{},React.createElement('h1',{},title),children),card:'card',button:'button'};
if(name==='./shared')return {windowLabels:{closed:'Janela encerrada',unknown:'Janela por confirmar',open:'Segundo datas documentadas'}};
if(name==='@/components/funding-classification')return load('components/funding-classification.tsx');
if(name==='@/components/funding-institution')return load('components/funding-institution.tsx');
if(name==='@/components/funding-dossier-choice')return {};
if(name==='@/components/funding-criteria-assessment')return {default:()=>null};
return require(name);
},module,module.exports);cache[file]=module.exports;return module.exports;
}
const wrap=body=>'<!doctype html><html lang="pt"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Instituições por localização categoria e tipo — QA</title><style>body{font:16px/1.5 system-ui;max-width:1100px;margin:auto;padding:24px;color:#172a29;background:#f5f7f6}.card{background:white;border:1px solid #ccd8d1;border-radius:10px;padding:18px;margin:16px 0}a{color:#006546}label{display:block;margin:8px}input,select{padding:8px;max-width:100%}article{overflow-wrap:anywhere}details{margin:16px 0}</style><p><strong>Revisão QA — ainda não instalado/publicado na homologação.</strong> Dados do documento fornecido, com dúvidas, proveniência e histórico conservados; não é confirmação independente de licença ou oferta. Renderização estática dos componentes; os filtros funcionais e a continuidade foram provados pela API QA. Sem candidaturas enviadas.</p>'+body+'</html>';
const Show=load('pages/funding/show.tsx').default,Index=load('pages/funding/index.tsx').default;
fs.mkdirSync(new URL('fichas/',out),{recursive:true});
for(const record of records){const html=renderToStaticMarkup(React.createElement(Show,{record,saved:null,authenticated:false}));fs.writeFileSync(new URL('fichas/'+record.code+'.html',out),wrap(html));}
const catalogue=renderToStaticMarkup(React.createElement(Index,{items:{data:records,links:[]},filters:{location_mode:'physical'},kinds:{institution:'Instituição'},management:false,options:{territories:[],sectors:[]},needs:{investment:'Investimento',insurance:'Seguros'}}));fs.writeFileSync(new URL('catalogo-qa.html',out),wrap(catalogue));
const categories={};for(const r of records)for(const c of r.payload.institution_categories??[])categories[c]=(categories[c]??0)+1;
const proof={source:source.source,institutions:records.length,physical_location_assertions:records.reduce((n,r)=>n+r.payload.locations.length,0),contact_assertions:records.reduce((n,r)=>n+r.payload.contacts.length,0),categories,source_table_rows_accounted:source.source_coverage.length,identity_aliases_and_regulator_numbers_preserved:true,physical_presence_separate_from_product_coverage:true,uncertain_historical_and_unlocated_assertions_explicit:true,no_insurer_presented_as_credit_provider:true,bank_and_insurer_saved_in_same_dossier:true,selected_branch_source_and_type_recovered_after_withdrawal:true,qa_transactions_rolled_back:true,no_new_schema_port_or_rights:true,installed:false,published_live:false,visual_review:'pending; connector unavailable',data_sha256:createHash('sha256').update(fs.readFileSync(new URL('database/data/funding-institutions-nov2026.json',root))).digest('hex')};fs.writeFileSync(new URL('verification.json',out),JSON.stringify(proof,null,2));console.log(JSON.stringify(proof));