Files
SGF/scripts/summarize-invoice-progress.mjs
2026-11-04 09:37:20 +02:00

9 lines
5.9 KiB
JavaScript

import fs from 'node:fs';import path from 'node:path';import crypto from 'node:crypto';import assert from 'node:assert/strict';
const [availableTag,partialTag,demoTag]=process.argv.slice(2);assert([availableTag,partialTag,demoTag].every(t=>/^[a-f0-9]{12}$/.test(t??'')));const run=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json')),available=path.join(run.root,'private/invoice-progress-read-'+availableTag),partial=path.join(run.root,'private/invoice-progress-read-'+partialTag),demo=path.join(run.root,'private/receipt-composition-'+demoTag),prior=path.join(run.root,'private/receipt-composition-92a2386b386b'),read=p=>JSON.parse(fs.readFileSync(p,'utf8')),hash=p=>crypto.createHash('sha256').update(fs.readFileSync(p)).digest('hex'),tests={};
for(const [name,base,file,count]of [['available',available,'invoice-progress-read-result.json',14],['partial',partial,'invoice-progress-read-result.json',16],['ui',partial,'invoice-progress-ui.json',11],['demo',demo,'invoice-progress-demo.json',6]]){const p=path.join(base,file),r=read(p);assert(r.passed);assert.equal(r.checks.length,count);if(r.before_sha256)assert.equal(r.before_sha256,r.after_sha256);tests[name]={file:'private/'+path.basename(base)+'/'+file,sha256:hash(p),checks:count,result:r};}
const files=['app/Modules/Purchasing/InvoiceMatchingProgress.php','app/Modules/Purchasing/InvoiceController.php','config/receipt_qa.php','public/invoice-matching.mjs','public/supplier-invoice-workspace.mjs'];for(const base of [available,partial,demo])for(const file of files)assert.equal(hash(path.join(base,'app',file)),hash(file),file);
const old=fs.readFileSync(path.join(prior,'app/app/Modules/Purchasing/InvoiceController.php'),'utf8'),now=fs.readFileSync('app/Modules/Purchasing/InvoiceController.php','utf8'),tail=text=>text.slice(text.indexOf('public function preview(')),state=text=>text.slice(text.indexOf('private function state('),text.indexOf('private function input('));assert.equal(tail(old),tail(now));assert.equal(state(old),state(now));
const pins=[];for(const base of [read(path.join(available,'state.json')).original_root,read(path.join(partial,'state.json')).original_root,demo]){const p={};for(const dir of ['bundle','economic','internal']){p[dir]=hash(path.join(base,dir,'manifest.json'));for(const [file,h]of Object.entries(read(path.join(base,dir,'manifest.json')).files))assert.equal(hash(path.join(base,dir,file)),h);}pins.push(p);}assert.deepEqual(pins[0],pins[1]);assert.deepEqual(pins[0],pins[2]);assert.deepEqual(pins[0],read('docs/proofs/request-history-composition-20261103.json').pinned_native_manifests);
const previous=['docs/proofs/request-history-composition-20261103.json','docs/proofs/supplier-invoice-composition-20261103.json','docs/proofs/purchasing-continuity-composition-20261103.json','docs/proofs/module-association-consolidation-summary-20261102.json'].map(file=>({file,sha256:hash(file)})),assoc=read(previous.at(-1).file);assert.equal(hash('app/Modules/Identity/Services/ModuleAssociationReview.php'),assoc.source_sha256);assert.equal(hash('app/Modules/Identity/Http/ModuleRecordsController.php'),assoc.controller_sha256);assert.equal(hash('packages/purchasing/current.json'),read(previous[0].file).preservation.installed_purchasing_sha256);
const count=Object.values(tests).reduce((n,t)=>n+t.checks,0);assert.equal(count,47);const out='docs/proofs/invoice-matching-progress-20261103.json';assert(!fs.existsSync(out));fs.writeFileSync(out,JSON.stringify({date:new Date().toISOString(),increment:'SGF-INVOICE-MATCHING-PROGRESS-QA-v1',passed:true,functional_code:true,checks:count,tests,sources:files.map(file=>({file,sha256:hash(file)})),pinned_native_manifests:pins[0],authority:{new_right_names:[],new_writers:0,native_validation_unchanged:true,state_definition_and_preview_confirmation_unchanged:true,source_revision_equivalent:true,pending_quantities_reserved:false,automatic_quantity_selection:false,original_pending_document_preserved:true},read_projection:{two_aggregate_queries_for_quantity_facts:true,physical_corrections_reused_from_original_state:true,display_state_observed_once:true,full_dependency_revision_still_materialises_source_state:true,invoice_history_latest_response_wins:true},regression:{completed_books_reused:true,financial_commands_repeated:0,available_milli:1000,after_validated40_60_remaining_milli:0,pending70_milli:700,all_source_tables_and_sequences_unchanged:true},demo:{port:8081,entry:'http://127.0.0.1:8081/qa/enter/issuer?open=1',initial_main_requests:0,initial_invoices:0},prior_proofs_preserved:previous,preservation:{installed_purchasing_sha256:hash('packages/purchasing/current.json'),target_database_connected:false,protected_six_records_changed:false,blocked_cache_cleared:false,previous_demo_data_written:false,public_rights_changed:false,publication:false,checkpoint:false},limitations:['The quantity projection is read-only. A review permission or warning is not a promise that native validation will succeed.','Pending document quantities are shown separately and do not reserve matching capacity. No rejection correction or credit note is introduced.','The full order dependency state remains materialised for its original revision. Removing a duplicate observation is not a load benchmark or complete pagination/memory optimisation.','Source books contain one order line and existing invoice cases. Larger order histories, query/time/memory benchmarks and indexes are not validated by this trial.','Return/reversal boundary arithmetic is checked without repeating physical correction commands; complete physical correction suites remain their own proof.','DOM tests are not browser rendering visual or accessibility review. The React/Vite build is unchanged; served static module hashes and syntax are checked.','Operational policy, deployment compatibility, sustained load and capacity remain pending.'],visual_review_pending:true,deployment_capacity_validated:false},null,2)+'\n');console.log(JSON.stringify({output:out,checks:count,demo_port:8081}));