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=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/[",\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));