Files
SGF/scripts/sgf-payable-due-http.mjs
T
2026-11-11 09:00:17 +02:00

17 lines
6.1 KiB
JavaScript

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',progress=root+'/payable-due-http-progress.json',saved=fs.existsSync(progress)?JSON.parse(fs.readFileSync(progress)):{},save=()=>fs.writeFileSync(progress,JSON.stringify(saved)),checks=[],ok=(v,n)=>{assert(v,n);checks.push(n);};
const reader=await session('sgf:read_only','finance'),prepare=await session('sgf:finance_prepare','finance'),review=await session('sgf:finance_review','finance');let r=await reader.get('/api/finance/payable-positions');assert.equal(r.status,200);const positions=await r.json(),row=positions.positions.find(x=>x.obligation_id&&x.principal_minor==='10000');assert(row);const id=row.obligation_id,base='/api/finance/payable-due',query={obligation_id:id,reference_on:'2026-11-30'},url=q=>base+'?'+new URLSearchParams(q);
const load=async(s=reader,q=query)=>{const r=await s.get(url(q));assert.equal(r.status,200);return r.json();};const initial=await load();ok(initial.basis.position.balance_minor===10000&&initial.basis.position.due_on===null,'original100 and original unknown date');
async function perform(name,s,input){saved[name]??={key:crypto.randomUUID()};save();const step=saved[name];if(step.result)return step.result;const receipt=await s.get(base+'/receipts/'+step.key);if(receipt.status===200){step.result=(await receipt.json()).result;save();return step.result;}assert.equal(receipt.status,404);const cut=await s.command(base+'/preview',input,step.key);assert.equal(cut.status,200,JSON.stringify(cut.value));step.cut=cut.value;save();const out=await s.command(base+'/confirm',{preview:cut.value.preview},step.key);assert.equal(out.status,201,JSON.stringify(out.value));step.result=out.value;save();return out.value;}
const input={action:'prepare',obligation_id:id,version:0,data:{due_on:'2026-11-30',evidence:'QA artificial SGF-PAYABLE-DUE-v1; condição de ensaio, não prazo comercial real.'},reason:'Preparação individual QA do vencimento artificial aprovado, sem alterar principal ou saldo.'};
const v1=await perform('prepare',prepare,input);ok(v1.version===1&&v1.state==='prepared','actual intention v1');const v2=await perform('review',review,{action:'review',obligation_id:id,version:1,data:{decision:'approved'},reason:'Revisão distinta QA da evidência artificial e da data30/11/2026, sem efeito monetário.'});ok(v2.version===2&&v2.state==='approved','actual distinct approval v2');
if(!saved.replayChecked){const replay=await prepare.command(base+'/confirm',{preview:saved.prepare.cut.preview},saved.prepare.key);assert.equal(replay.status,200);assert.equal(replay.value.replayed,true);saved.replayChecked=true;save();}ok(saved.replayChecked,'same confirmation replays without duplication');
const current=await load();ok(current.basis.version===2&&current.history.total===2,'two audited versions only');ok(current.days_overdue===0&&current.due_status==='not_overdue','due day no delay');const later=await load(reader,{...query,reference_on:'2026-12-01'});ok(later.days_overdue===1&&later.due_status==='overdue','next reference day one day');ok(current.reviewed_terms.evidence.includes('artificial')&&current.basis.position.due_on===null,'reviewed metadata separate from original');ok(current.basis.position.balance_minor===10000&&current.basis.position.principal_minor===10000,'money unchanged after approval');
const large=await load(reader,{...query,per_page:100});ok(JSON.stringify(large.history.data)===JSON.stringify(current.history.data),'history25/100');const far=await load(reader,{...query,page:100000});ok(far.history.data.length===0,'history far page no fallback');
r=await prepare.get(base+'/receipts/'+saved.prepare.key);const receipt=await r.json();ok(r.status===200&&receipt.historical_receipt_only&&!receipt.operation_executed,'own historical receipt read only');r=await review.get(base+'/receipts/'+saved.prepare.key);ok(r.status===404,'other actor receipt unavailable');
let out=await reader.command(base+'/preview',{...input,version:2});ok(out.status===403,'read only cannot prepare');out=await prepare.command(base+'/preview',{action:'review',obligation_id:id,version:2,data:{decision:'approved'},reason:'QA tentativa indevida de revisão própria.'});ok(out.status===403,'preparer cannot review');out=await review.command(base+'/preview',{...input,version:2});ok(out.status===403,'reviewer cannot prepare');
r=await reader.get(url({...query,tenant_id:2}));ok(r.status===422,'tenant override refused');r=await reader.get(url({...query,obligation_id:2147483647}));ok(r.status===403,'foreign obligation refused');r=await reader.get(url({...query,per_page:1000}));ok(r.status===422,'unbounded history refused');const commercial=await session('sgf:read_only','commercial');r=await commercial.get(url(query));ok([403,409].includes(r.status),'other module refused');
const fresh=await session('sgf:finance_prepare','finance');r=await fresh.get(base+'/receipts/'+saved.prepare.key);ok(r.status===200&&(await r.json()).result.id===v1.id,'receipt recoverable in fresh authorized session');
fs.writeFileSync(root+'/payable-due-sample-private.json',JSON.stringify(current));const manifest=JSON.parse(fs.readFileSync(root+'/app/public/build/manifest.json'));for(const e of Object.values(manifest).filter(v=>v.isEntry||v.file.includes('PayablePositionsWorkspace'))){r=await fetch('http://127.0.0.1:8085/build/'+e.file);const bytes=Buffer.from(await r.arrayBuffer());ok(r.status===200&&/javascript/.test(r.headers.get('content-type'))&&crypto.createHash('sha256').update(bytes).digest('hex')===crypto.createHash('sha256').update(fs.readFileSync(root+'/app/public/build/'+e.file)).digest('hex'),'actual JS delivery '+e.file);}
const file=root+'/payable-due-http-20261110.json';fs.writeFileSync(file,JSON.stringify({passed:true,checks,actual_confirmed_commands:2,prepared_host:13,reviewed_host:14,financial_effects:0,new_demo:false,browser_visual_review:false},null,2));console.log(JSON.stringify({passed:true,checks:checks.length,proof:file}));