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

7 lines
6.4 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=p=>JSON.parse(fs.readFileSync(p,'utf8')),hash=p=>crypto.createHash('sha256').update(fs.readFileSync(p)).digest('hex');const tests={};for(const [name,base,file,count]of [['workflow',qa,'supplier-result.json',34],['boundaries',qa,'supplier-boundary.json',6],['guards',qa,'supplier-guards.json',3],['demonstration',demo,'supplier-demo-smoke.json',12],['assets',demo,'supplier-demo-assets.json',3],['navigation','.', 'docs/proofs/supplier-home-20261103.json',6]]){const p=path.join(base,file),r=read(p);assert(r.passed);assert.equal(Array.isArray(r.checks)?r.checks.length:r.checks,count);tests[name]={file:base==='.'?file:'private/'+path.basename(base)+'/'+file,sha256:hash(p),checks:count,result:r};}assert.equal(Object.values(tests).reduce((n,t)=>n+t.checks,0),64);
const files=['app/Modules/Purchasing/SupplierController.php','app/Modules/Purchasing/SupplierAccess.php','app/Modules/Purchasing/SourcingController.php','app/Modules/Purchasing/ReceiptRuntime.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/supplier-workspace.blade.php','resources/views/sourcing-workspace.blade.php','public/supplier-workspace.mjs','scripts/supplier-host-setup.php','scripts/supplier-composition-proof.php','scripts/supplier-boundary-proof.php','scripts/supplier-guard-proof.php','scripts/supplier-demo-smoke.php','scripts/supplier-demo-assets.mjs','scripts/order-native-setup.php','scripts/receipt-composition-run.mjs','scripts/receipt-composition-http.php','scripts/receipt-composition-extra.mjs'];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 b=read(path.join(base,'bundle/manifest.json')),e=read(path.join(base,'economic/manifest.json'));for(const [file,pin]of Object.entries(b.files))assert.equal(hash(path.join(base,'bundle',file)),pin);for(const [file,pin]of Object.entries(e.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/SupplierController.php','app/Http/Requests/SaveSupplierRequest.php','app/Services/SupplierParticipation.php','app/Policies/SupplierPolicy.php'].map(file=>{assert.equal(hash(path.resolve('../compras',file)),b.originals[file]);return [file,b.originals[file]];}))});}assert.deepEqual(manifests[0],manifests[1]);
const previous=read('docs/proofs/sourcing-composition-20261103.json');assert.equal(hash('packages/purchasing/current.json'),previous.preservation.installed_purchasing_sha256);const old=path.join(run.root,'private/receipt-composition-2c8780f3686a/bundle');assert.equal(hash(path.join(old,'manifest.json')),previous.workflow_package.native_sha256);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);for(const p of previous.prior_proofs_preserved)assert.equal(hash(p.file),p.sha256);
const out='docs/proofs/supplier-composition-20261103.json';assert(!fs.existsSync(out));fs.writeFileSync(out,JSON.stringify({date:new Date().toISOString(),increment:'SGF-SUPPLIER-REGISTRY-QA-v1',passed:true,functional_code:true,checks:64,tests,sources,workflow_package:manifests[0],demo:{url:'http://127.0.0.1:8067/qa/enter/actor?open=1',reviewer_url:'http://127.0.0.1:8067/qa/enter/issuer?open=1',warehouse_url:'http://127.0.0.1:8067/qa/enter/validator?open=1',initial_prepared_seed_suppliers:3,initial_sgf_supplier_decisions:0,initial_quotes:0,initial_orders:0,initial_receipts:0},qa_rights:['purchasing_suppliers.view','purchasing_suppliers.prepare','purchasing_suppliers.review'],reused_valid_proofs:[{file:'docs/proofs/sourcing-composition-20261103.json',sha256:hash('docs/proofs/sourcing-composition-20261103.json'),checks:74,scope:'original source-to-receipt scenario; not rerun as supplier tests'}],test_scope:'34 workflow checks retained; six new access/review boundaries plus12 live demonstration checks cover later access and presentation adjustments. No unrelated business suites repeated.',preview:{mode:'original_controller_in_rollback_only_savepoint',persistent_records_unchanged:true,sequence_may_advance:true,temporary_supplier_id_not_exposed:true},preservation:{installed_purchasing_sha256:hash('packages/purchasing/current.json'),old_sourcing_demo_native_bundle_intact:true,protected_six_records_changed:false,blocked_cache_cleared:false,real_rights_changed:false,target_database_connected:false,existing_demo_business_data_written:false,activation_at_destination:false,publication:false,checkpoint:false},limitations:['QA owner roles and copied composition are not a generally installed or deployment-validated module.','Native supplier field validation, preparation and distinct review are reused; document references are declared text, not attachment upload or verified external evidence.','Index search/status/pagination15 and per-supplier history15 are server-side; sourcing picker retains its100-supplier cap.','New suppliers are scoped by audited company/unit origin; prepared seed suppliers stay explicitly bound. Operational registry sharing policy is not inferred.','SGF internal requisition handoff with one budget authority, formal tender regimes and later procurement corrections remain separate gaps.','No visual review, sustained-load claim or real fiscal/operational activation.'],visual_review_pending:true,deployment_capacity_validated:false},null,2)+'\n');console.log(JSON.stringify({output:out,checks:64,demo_port:8067}));