Files
SGF/scripts/summarize-sourcing-composition.mjs
T
2026-11-04 09:37:20 +02:00

9 lines
6.7 KiB
JavaScript

import fs from 'node:fs';import path from 'node:path';import crypto from 'node:crypto';import assert from 'node:assert/strict';
const [qaTag,demoTag]=process.argv.slice(2);assert([qaTag,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')),qa=path.join(run.root,'private/receipt-composition-'+qaTag),demo=path.join(run.root,'private/receipt-composition-'+demoTag),read=f=>JSON.parse(fs.readFileSync(f,'utf8').replace(/^\uFEFF/,'')),hash=f=>crypto.createHash('sha256').update(fs.readFileSync(f)).digest('hex');
const tests={};for(const [name,base,file,count]of [['workflow',qa,'sourcing-result.json',47],['guards',qa,'sourcing-guards.json',3],['dependency_integrity',qa,'sourcing-loader.json',6],['demonstration',demo,'sourcing-demo-smoke.json',9],['assets',demo,'sourcing-demo-assets.json',3]]){const result=read(path.join(base,file));assert(result.passed);assert.equal(Array.isArray(result.checks)?result.checks.length:result.checks,count);tests[name]={file:'private/'+path.basename(base)+'/'+file,sha256:hash(path.join(base,file)),checks:count,result};}const file='docs/proofs/sourcing-home-20261103.json',ui=read(file);assert(ui.passed&&ui.checks===6);tests.navigation={file,sha256:hash(file),checks:6,result:ui};assert.equal(Object.values(tests).reduce((n,t)=>n+t.checks,0),74);
const files=['app/Modules/Purchasing/SourcingController.php','app/Modules/Purchasing/ReceiptRuntime.php','app/Modules/Purchasing/OrderController.php','config/receipt_qa.php','routes/web.php','app/Shared/Context/ModuleNavigation.php','app/Modules/Identity/Services/IdentityWorkflow.php','resources/js/PurchasingHome.jsx','resources/views/sourcing-workspace.blade.php','public/sourcing-workspace.mjs','scripts/sourcing-host-setup.php','scripts/sourcing-composition-proof.php','scripts/sourcing-guard-proof.php','scripts/sourcing-loader-proof.php','scripts/sourcing-demo-smoke.php','scripts/order-native-setup.php','scripts/receipt-composition-run.mjs','scripts/receipt-composition-http.php'];const sources=files.map(file=>({file,sha256:hash(file)}));for(const base of [qa,demo])for(const file of files.filter(f=>!f.startsWith('scripts/')))assert.equal(hash(path.join(base,'app',file)),hash(file));
const manifests=[];for(const base of [qa,demo]){const bundle=read(path.join(base,'bundle/manifest.json')),economic=read(path.join(base,'economic/manifest.json'));for(const [file,pin]of Object.entries(bundle.files))assert.equal(hash(path.join(base,'bundle',file)),pin);for(const [file,pin]of Object.entries(economic.files))assert.equal(hash(path.join(base,'economic',file)),pin);manifests.push({native_sha256:hash(path.join(base,'bundle/manifest.json')),economic_sha256:hash(path.join(base,'economic/manifest.json')),original_sources:Object.fromEntries(['app/Http/Controllers/QuotationController.php','app/Services/ProposalComparison.php','app/Services/PurchaseWorkflow.php'].map(f=>[f,bundle.originals[f]]))});}assert.deepEqual(manifests[0],manifests[1]);
const previous=read('docs/proofs/order-composition-20261103.json');assert.equal(hash('packages/purchasing/current.json'),previous.preservation.installed_purchasing_sha256);for(const [tag,pin]of [['dc8a83df6a24',Object.values(previous.bundled)[1].native_manifest_sha256],['304b80f5a05f',previous.preservation.previous_receipt_demo_manifest_sha256]]){const old=path.join(run.root,'private/receipt-composition-'+tag+'/bundle');assert.equal(hash(path.join(old,'manifest.json')),pin);for(const [file,pin]of Object.entries(read(path.join(old,'manifest.json')).files))assert.equal(hash(path.join(old,file)),pin);}
const association=read('docs/proofs/module-association-consolidation-summary-20261102.json');assert.equal(hash('app/Modules/Identity/Services/ModuleAssociationReview.php'),association.source_sha256);assert.equal(hash('app/Modules/Identity/Http/ModuleRecordsController.php'),association.controller_sha256);const prior=['docs/proofs/order-composition-20261103.json','docs/proofs/receipt-composition-20261103.json','docs/proofs/module-association-consolidation-summary-20261102.json','docs/proofs/common-ledger-stock-valuation-20261103.json'].map(file=>({file,sha256:hash(file)}));
const out='docs/proofs/sourcing-composition-20261103.json';assert(!fs.existsSync(out));fs.writeFileSync(out,JSON.stringify({date:new Date().toISOString(),increment:'SGF-SOURCING-TO-RECEIPT-QA-v1',functional_code:true,passed:true,checks:74,tests,sources,workflow_package:manifests[0],preview:{mode:'native_commands_in_rollback_only_savepoint',persistent_records_unchanged:true,sequence_values_may_advance:true,external_sends:false},demo:{url:'http://127.0.0.1:8066/qa/enter/actor?open=1',reviewer_url:'http://127.0.0.1:8066/qa/enter/issuer?open=1',warehouse_url:'http://127.0.0.1:8066/qa/enter/validator?open=1',initial_quotes:0,initial_evaluations:0,initial_awards:0,initial_orders:0,initial_receipts:0,initial_movements:0,initial_reserved_minor:10000},qa_rights:['purchasing_sourcing.view','purchasing_sourcing.prepare','purchasing_sourcing.evaluate','purchasing_sourcing.select','purchasing_sourcing.approve'],diagnostics:{initial_demo_smoke_timeout_preserved:true,location:'original all-file runtime package verification, before workflow',correction:'pinned manifest plus content verification before each dependency loads; complete artefact fingerprint verified by this summarizer',business_workflow_47_not_repeated:true},prior_proofs_preserved:prior,preservation:{installed_purchasing_sha256:hash('packages/purchasing/current.json'),old_demo_bundles_intact:true,protected_six_records_changed:false,blocked_cache_cleared:false,real_rights_changed:false,existing_demos_written:false,purchasing_activated_at_destination:false,publication:false,checkpoint:false},limitations:['Entry remains an approved native QA requisition with three synthetic source suppliers; no silent transfer from SGF internal requisitions or second host budget.','Registration/evaluation/selection/approval use the original controller and workflows; no automatic supplier or score choices.','Selected scenario three proposals100/120/140MZN, zero tax, two individual evaluators; formal tender regimes, later corrections/cancellations and real fiscal policy are not declared validated.','Rollback preview can consume nontransactional sequence values, but commits no quote/evaluation/award/audit/budget record; restricted to owned QA databases.','Dependency loading integrity is proved; this does not validate sustained load, all source modules, long-lived workers or owner/runtime deployment separation.','Source selector exposes at most100 configured suppliers; process index/history are server-paginated.','No visual review or deployment capacity validation.'],visual_review_pending:true,deployment_capacity_validated:false},null,2)+'\n');console.log(JSON.stringify({output:out,checks:74,demo_port:8066}));