import fs from 'node:fs';import assert from 'node:assert/strict';import crypto from 'node:crypto';import {session} from './sgf-single-http.mjs'; const run=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json')),root=run.root+'/private/receipt-composition-cc50a276c10c',file=root+'/iva-http-20261110.json';let progress=fs.existsSync(file)?JSON.parse(fs.readFileSync(file)):{operations:{},checks:[]};if(progress.passed){console.log(JSON.stringify({passed:true,reused:true,proof:file}));process.exit();}const save=()=>fs.writeFileSync(file,JSON.stringify(progress,null,2));const ok=(v,n)=>{assert(v,n);if(!progress.checks.includes(n))progress.checks.push(n);save();};const prep=await session('sgf:finance_prepare','accounting'),review=await session('sgf:finance_review','accounting');const get=async(s=prep,query='')=>{const r=await s.get('/api/fiscal-assessments'+query);assert.equal(r.status,200);return r.json();};let state=await get();ok(prep.identity.context.fiscal_qa_enabled===true,'authorized feature in selected context');ok(state.source.base==='862.07'&&state.source.vat==='137.93'&&state.source.total==='1000.00','actual bound frozen FR source'); const command=async(name,s,kind,action,version)=>{if(progress.operations[name]?.result)return progress.operations[name].result;let op=progress.operations[name];if(!op){op=progress.operations[name]={key:crypto.randomUUID(),input:{kind,action,version,reason:'Conferência individual QA explícita da origem e versão do livro/mapa.',data:action==='prepare'?{source_output_id:state.source.output_id,period:state.period,classification:'qa_output_only',evidence:'Factura-recibo QA existente, conferida individualmente para este mapa interno.'}:{decision:'reviewed'}}};save();}if(!op.cut){const p=await s.command('/api/fiscal-assessments/preview',op.input,op.key);assert.equal(p.status,200,JSON.stringify(p.value));op.cut=p.value.preview;ok(p.value.impact.new_journals===0&&p.value.impact.tax_payable===null,'preview no journals or invented tax payable');save();}const r=await s.command('/api/fiscal-assessments/confirm',{preview:op.cut});assert.equal(r.status,200,JSON.stringify(r.value));op.result=r.value;save();const replay=await s.command('/api/fiscal-assessments/confirm',{preview:op.cut});ok(replay.status===200&&replay.value.replayed&&replay.value.id===op.result.id,'repeat '+name+' no duplicate');return op.result;}; const prepared=await command('prepare-book',prep,'assessment','prepare',0);state=await get();ok(state.assessment.state==='prepared'&&!state.assessment_current_review,'prepared book not yet reviewed');const tooSoon=await prep.command('/api/fiscal-assessments/preview',{kind:'form',action:'prepare',version:0,reason:'Mapa antes da revisão do livro deve ser recusado.',data:{source_output_id:state.source.output_id,period:state.period,classification:'qa_output_only',evidence:'Origem QA explicitamente escolhida mas ainda não revista.'}});ok(tooSoon.status===409,'map blocked before book review');await command('review-book',review,'assessment','review',1);state=await get();ok(state.assessment_current_review,'book reviewed by distinct person');const form=await command('prepare-map',prep,'form','prepare',0);const unpublished=await prep.get('/api/fiscal-assessments/forms/'+form.id+'/export');ok(unpublished.status===409,'unreviewed map export refused');const final=await command('review-map',review,'form','review',1);state=await get();ok(state.form_current_review&&state.events.total===4,'exact four retained versions, reviewed map current'); const csv=await prep.get('/api/fiscal-assessments/forms/'+final.id+'/export');ok(csv.status===200&&csv.headers.get('content-type').includes('text/csv'),'reviewed internal CSV downloadable');const bytes=Buffer.from(await csv.arrayBuffer());ok(crypto.createHash('sha256').update(bytes).digest('hex')===csv.headers.get('x-content-sha256'),'frozen bytes/checksum match');ok(bytes.toString().includes('862.07;137.93;1000.00')&&bytes.toString().includes('INDETERMINADO')&&bytes.toString().includes('SEM VALIDADE FISCAL'),'map exact and clearly incomplete/synthetic'); const read=await session('sgf:read_only','accounting');const readState=await get(read,'?kind=form&per_page=100');ok(readState.events.total===2&&readState.capabilities.form_prepare===false&&readState.capabilities.form_review===false,'filtered history and read-only role');const denied=await read.command('/api/fiscal-assessments/preview',progress.operations['prepare-book'].input);ok(denied.status===403,'read-only write refused');const extra=await prep.get('/api/fiscal-assessments?tenant_id=2');ok(extra.status===422,'client tenant override refused');const foreign=await prep.command('/api/fiscal-assessments/preview',{...progress.operations['prepare-book'].input,version:2,data:{...progress.operations['prepare-book'].input.data,source_output_id:2147483647}});ok(foreign.status===403,'unbound source refused');const fresh=await session('sgf:finance_prepare','accounting');const receipt=await fresh.get('/api/fiscal-assessments/receipts/'+progress.operations['prepare-book'].key);const recovered=await receipt.json();ok(receipt.status===200&&recovered.result.id===prepared.id&&recovered.operation_executed===false,'own historical receipt recovered in fresh session');const other=await review.get('/api/fiscal-assessments/receipts/'+progress.operations['prepare-book'].key);ok(other.status===404,'other actor cannot read command receipt');const wrong=await session('sgf:finance_prepare','finance');const blocked=await wrong.get('/api/fiscal-assessments');ok([403,409].includes(blocked.status),'wrong module refused');const s=await read.get('/fiscal/iva',{headers:{Accept:'text/html'}});ok(s.status===200&&(await s.text()).includes('Ensaio sintético'),'actual screen reachable to authorized reader');progress.passed=true;progress.business_confirmations=4;progress.new_journals=0;progress.new_demo=false;progress.browser_visual_review=false;save();console.log(JSON.stringify({passed:true,checks:progress.checks.length,proof:file}));