Files
Investidor-V2/tools/portal-workflow-execution-matrix.mjs
nala 287e991486
tests / ci (push) Waiting to run
oportunidades 7
2026-10-13 11:40:29 +02:00

39 lines
3.2 KiB
JavaScript

import fs from 'node:fs/promises';
import path from 'node:path';
import assert from 'node:assert/strict';
import {createRequire} from 'node:module';
import {pathToFileURL,fileURLToPath} from 'node:url';
const R=path.dirname(path.dirname(fileURLToPath(import.meta.url))),P=path.join(R,'storage/app/private/investmoz-v2/portal-audit');
const runtime=path.join(P,'legacy-sector-reconciliation-20261010');
const requireRuntime=createRequire(path.join(runtime,'package.json'));
const {Workbook}=await import(pathToFileURL(requireRuntime.resolve('@oai/artifact-tool')).href);
const file=path.join(R,'docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv');
const prefix=process.argv[2]??'workflow-execution';
assert(['workflow-execution','workflow-activation','onboarding','onboarding-release','internal-designation'].includes(prefix));
const baseline=JSON.parse(await fs.readFile(path.join(P,prefix+'-matrix-baseline.json'),'utf8'));
const {rows,updates}=baseline,headers=rows[0],text=await fs.readFile(file,'utf8');
const workbook=await Workbook.fromCSV(text.replace(/^\ufeff/,''),{sheetName:'Requisitos'}),sheet=workbook.worksheets.getItem('Requisitos');
const matches=(value,literal)=>value instanceof Date?value.getTime()===Date.parse(literal):(value==null?'':String(value))===literal;
const initial=sheet.getRangeByIndexes(0,0,rows.length,headers.length).values;
assert(initial.every((row,i)=>row.every((v,c)=>matches(v,rows[i][c]))),'Existing matrix import must preserve all source strings');
if(process.argv.includes('--preview')) {
const preview=await workbook.render({sheetName:'Requisitos',range:'A3356:C3360',scale:1,format:'png'});
await fs.writeFile(path.join(P,prefix+'-matrix-preview.png'),new Uint8Array(await preview.arrayBuffer()));
console.log(JSON.stringify({result:'source_rendered',rows:rows.length-1,columns:headers.length,edit_performed:false}));
process.exit(0);
}
const final=rows.map(row=>[...row]),changes=[];
for(let i=1;i<rows.length;i++){const update=updates[rows[i][0]];if(!update)continue;for(const [column,value]of Object.entries(update)){assert.equal(column,'Evidência funcional');const c=headers.indexOf(column);assert(c>=0);sheet.getCell(i,c).values=[[value]];final[i][c]=value;changes.push({id:rows[i][0],row:i+1,column});}}
workbook.recalculate();
const observed=sheet.getRangeByIndexes(0,0,rows.length,headers.length).values;
assert(observed.every((row,i)=>row.every((v,c)=>matches(v,final[i][c]))),'Authored cells must match intended literal strings');
assert.equal(changes.length,3);
for(let i=0;i<rows.length;i++)for(let c=0;c<headers.length;c++)if(rows[i][c]!==final[i][c])assert(updates[rows[i][0]]&&headers[c]==='Evidência funcional');
const quote=v=>/[",\r\n]/.test(v)?'"'+v.replaceAll('"','""')+'"':v;
const output='\ufeff'+final.map(row=>row.map(quote).join(',')).join('\r\n')+'\r\n';
await fs.writeFile(path.join(P,prefix+'-matrix-before.csv'),text,'utf8');
// CSV has no chart/layout/style/formula changes. Serialize only verified strings, preserving every unrelated field.
await fs.writeFile(file,output,'utf8');
const counts={rows:rows.length-1,new_ids:0,changes,states_unchanged:true,sources_and_versions_unchanged:true};
await fs.writeFile(path.join(P,prefix+'-matrix-proof.json'),JSON.stringify(counts,null,2));console.log(JSON.stringify(counts));