import fs from 'node:fs'; import crypto from 'node:crypto'; import assert from 'node:assert/strict'; import {session} from './sgf-single-http.mjs'; import {checkedPayablePage,payablePageSummary,payablePageCsv} from '../resources/js/payable-position-view.js'; const checks=[],ok=(v,n)=>{assert(v,n);checks.push(n);},s=await session('sgf:read_only','finance'),query={page:1,per_page:25},path='/api/finance/payable-positions?'; let r=await s.get(path+new URLSearchParams(query));assert.equal(r.status,200);const data=checkedPayablePage(await r.json(),query); ok(data.positions.length>0,'actual source documents visible'); const legacy=await s.get('/api/finance/payables'),old=await legacy.json();assert.equal(legacy.status,200); for(const row of data.positions.filter(x=>x.obligation_id)){const prior=old.obligations.find(o=>o.id===row.obligation_id);ok(prior&&String(prior.balance_minor)===row.balance_minor&&String(prior.principal_minor)===row.principal_minor,'canonical principal and balance '+row.obligation_id);r=await s.get('/api/finance/payables?document_id='+row.document_id);const focused=await r.json();ok(r.status===200&&focused.obligations.length===1&&focused.obligations[0].id===row.obligation_id,'exact document target '+row.document_id);} r=await s.get(path+new URLSearchParams({...query,per_page:100}));ok(JSON.stringify(checkedPayablePage(await r.json(),{...query,per_page:100}).positions)===JSON.stringify(data.positions),'known page25/100 identical'); for(const row of data.positions){r=await s.get(path+new URLSearchParams({...query,search:row.reference}));ok((await r.json()).positions.some(x=>x.document_id===row.document_id),'document search '+row.document_id);} r=await s.get(path+new URLSearchParams({...query,search:data.positions[0].supplier}));ok((await r.json()).positions.length>0,'supplier search'); r=await s.get(path+new URLSearchParams({...query,document_state:'pending'}));ok((await r.json()).positions.every(x=>x.document_state==='pending'),'document state filter'); r=await s.get(path+new URLSearchParams({...query,search:'%'}));ok((await r.json()).pagination.total===0,'literal wildcard'); ok(data.positions.every(x=>x.due_status!=='unknown'||x.days_overdue===null),'unknown lag remains null'); ok(data.positions.filter(x=>!x.obligation_id).every(x=>x.balance_minor===null),'unrecognized not assumed debt zero'); ok(payablePageSummary(data).totals.every(x=>x.currency),'page totals preserve currency'); ok(payablePageCsv(data,query).includes('Apenas esta pagina'),'CSV only visible page'); for(const extra of [{tenant_id:2},{per_page:1000},{document_state:'paid'}]){r=await s.get(path+new URLSearchParams({...query,...extra}));ok(r.status===422,'unsupported query refused '+JSON.stringify(extra));} r=await s.get('/api/finance/payables?document_id=2147483647');ok(r.status===403,'unavailable exact target refused without fallback'); const other=await session('sgf:read_only','commercial');r=await other.get(path+new URLSearchParams(query));ok([403,409].includes(r.status),'other module refused'); const run=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json')),root=run.root+'/private/receipt-composition-cc50a276c10c',app=root+'/app',manifest=JSON.parse(fs.readFileSync(app+'/public/build/manifest.json')); for(const entry of Object.values(manifest).filter(e=>e.isEntry||e.file.includes('PayablePositionsWorkspace'))){r=await fetch('http://127.0.0.1:8085/build/'+entry.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(app+'/public/build/'+entry.file)).digest('hex'),'actual JS asset '+entry.file);} fs.writeFileSync(root+'/payable-positions-sample-private.json',JSON.stringify(data));const file=root+'/payable-positions-http-20261110.json';fs.writeFileSync(file,JSON.stringify({passed:true,checks,business_commands:0,new_grants:0,new_demo:false,browser_visual_review:false},null,2));console.log(JSON.stringify({passed:true,checks:checks.length,proof:file}));