import fs from'node:fs';import assert from'node:assert/strict';import crypto from'node:crypto';import{session}from'./sgf-single-http.mjs'; const root=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json')).root+'/private/receipt-composition-cc50a276c10c',file=root+'/assets-http-progress-private.json',saved=fs.existsSync(file)?JSON.parse(fs.readFileSync(file)):{asset:crypto.randomUUID(),plan:crypto.randomUUID(),charge:crypto.randomUUID(),steps:{}},save=()=>fs.writeFileSync(file,JSON.stringify(saved));save();const checks=[],ok=(v,n)=>{assert(v,n);checks.push(n);},prep=await session('sgf:accounting_prepare','accounting'),review=await session('sgf:accounting_review','accounting'),read=await session('sgf:read_only','accounting'); ok(prep.identity.context.fixed_assets_enabled===true,'same installation asset feature enabled');const get=async(path,s=read)=>{const r=await s.get(path);assert.equal(r.status,200,path);return r.json();}; async function command(name,s,body,domain='admin'){const step=saved.steps[name]??={key:crypto.randomUUID(),body};save();assert.equal(JSON.stringify(step.body),JSON.stringify(body),'stable saved command');if(step.result)return step.result;const receiptPath=domain==='ledger'?'/api/general-ledger/receipts/':'/api/fixed-assets/receipts/';let r=await s.get(receiptPath+step.key);if(r.status===200){step.result=(await r.json()).result;save();return step.result;}assert.equal(r.status,404);const base='/api/fixed-assets'+(domain==='ledger'?'/ledger':'');const cut=await s.command(base+'/preview',body,step.key);assert.equal(cut.status,200,cut.value.message);step.cut=cut.value;save();const out=await s.command(base+'/confirm',{preview:cut.value.preview},step.key);assert.equal(out.status,200,out.value.message);step.result=out.value;save();ok(true,name+' once HTTP preview confirm');return out.value;} const input=(kind,key,version,data,action='prepare')=>({kind,record_key:key,version,action,data,reason:'Conferência individual do ciclo de activos QA aprovado, sem operação real.'}); const asset={operation:'establish',code:'QA-ACTIVO-01',description:'Equipamento fictício de apresentação do ciclo de activos','origin_reference':'QA-ABERTURA-ACTIVO-01',cost:'1200.00',residual:'0.00',available_on:'2026-10-01',location:'QA-SALA-A',custodian:'QA-RESPONSAVEL-ACTIVO-01',evidence:'Abertura exclusivamente de ensaio aprovada; sem aquisição, dívida ou Stock.'}; await command('assetPrepare',prep,input('asset',saved.asset,0,asset));const ar=await command('assetReview',review,input('asset',saved.asset,1,{decision:'approved'},'review')); const gl=async(name,kind,source,on,rule)=>{const p=await command(name+'Prepare',prep,{action:'effect-prepare',data:{effect_type:kind,source_id:source,journal_on:on,period_key:'QA-2026-INTEGRADO',rule_key:rule,reason:'Preparação individual QA da origem revista de activos.'}},'ledger');await command(name+'Review',review,{action:'validate',data:{proposal_id:p.proposal_id,revision:p.revision,decision:'approved',reason:'Revisão independente QA da origem de activos e contas.'}},'ledger');return command(name+'Post',prep,{action:'post',data:{proposal_id:p.proposal_id,revision:p.revision,reason:'Aplicação individual QA do impacto de activos conferido.'}},'ledger');}; await gl('admission','assets.admitted',ar.id,'2026-10-01','QA-ASSET-ADMISSION');await command('planPrepare',prep,input('plan',saved.plan,0,{operation:'establish',asset_key:saved.asset,life_months:12,status:'active',evidence:'Vida artificial12 meses e residual0 explícitos; sem tabela fiscal legal.'}));await command('planReview',review,input('plan',saved.plan,1,{decision:'approved'},'review'));await command('chargePrepare',prep,input('charge',saved.charge,0,{operation:'establish',asset_key:saved.asset,plan_key:saved.plan,month:'2026-10',evidence:'Quota Outubro100 calculada pelo plano revisto, decisão individual sem automatismo.'}));const cr=await command('chargeReview',review,input('charge',saved.charge,1,{decision:'approved'},'review'));await gl('depreciation','assets.depreciation',cr.id,'2026-10-31','QA-ASSET-DEPRECIATION'); const state=await get('/api/fixed-assets/ledger?asset_key='+saved.asset);ok(state.balance.cost_minor===120000&&state.balance.accumulated_minor===10000&&state.balance.carrying_minor===110000&&!state.balance.disposed,'actual8085 cost1200 accumulated100 carrying1100');ok(state.records.data.filter(p=>p.journal).length===2,'two actual journals for explicit new asset');const list=await get('/api/fixed-assets?kind=asset&search=QA-ACTIVO-01&per_page=25');ok(list.records.data.length===1&&list.records.data[0].effective.version===2,'single new reviewed asset visible');const history=await get('/api/fixed-assets?kind=asset&record_key='+saved.asset);ok(history.records.data.length===2,'preparation and review history preserved'); if(!saved.replayed){const st=saved.steps.depreciationPost;const out=await prep.command('/api/fixed-assets/ledger/confirm',{preview:st.cut.preview},st.key);assert.equal(out.status,200,out.value.message);assert(out.value.replayed);saved.replayed=true;save();}ok(saved.replayed,'same post confirmation recovered without duplication'); const denied=await read.command('/api/fixed-assets/preview',input('asset',crypto.randomUUID(),0,asset));ok(denied.status===403,'read only cannot prepare');const finance=await session('sgf:finance_prepare','finance').catch(()=>null);if(finance){const r=await finance.get('/api/fixed-assets?kind=asset');ok([403,409].includes(r.status),'finance profile cannot enter assets');}let r=await read.get('/api/fixed-assets?kind=asset&tenant_id=2');ok(r.status===422,'tenant override denied');r=await review.get('/api/fixed-assets/receipts/'+saved.steps.assetPrepare.key);ok(r.status===404,'other actor receipt denied');r=await read.get('/api/fixed-assets?kind=asset&per_page=1000');ok(r.status===422,'unbounded page denied'); const manifest=JSON.parse(fs.readFileSync(root+'/app/public/build/manifest.json'));for(const e of Object.values(manifest).filter(e=>e.isEntry||/FixedAssetsWorkspace/.test(e.file))){r=await fetch('http://127.0.0.1:8085/build/'+e.file);const b=Buffer.from(await r.arrayBuffer());ok(r.status===200&&/javascript/.test(r.headers.get('content-type'))&&crypto.createHash('sha256').update(b).digest('hex')===crypto.createHash('sha256').update(fs.readFileSync(root+'/app/public/build/'+e.file)).digest('hex'),'served MIME and SHA '+e.file);} const proof=root+'/assets-http-20261111.json';fs.writeFileSync(proof,JSON.stringify({passed:true,checks,administrative_commands:6,journal_commands:6,new_journals:2,new_demo:false,browser_visual_review:false},null,2));console.log(JSON.stringify({passed:true,checks:checks.length,proof}));