Files
KArtSell.Aegis/docs/Design/kbx-foundation-v60-status-canonical-contract-hardening/scripts/validate-fe-reference.mjs
T
kjh2064 3f293d8aa8
deploy / deploy (push) Successful in 1m52s
deploy / notify (push) Successful in 1s
V13-FE-006: consolidate approved UI and contract hardening
2026-08-13 02:41:00 +09:00

44 lines
2.7 KiB
JavaScript

import fs from 'node:fs'
import path from 'node:path'
const root=process.cwd()
const base=path.join(root,'apps/web/fe-reference')
const required=['index.html','kbx-fe.css','kbx-fe.js','README.md']
const errors=[]
for(const file of required){if(!fs.existsSync(path.join(base,file)))errors.push(`missing ${file}`)}
if(!errors.length){
const html=fs.readFileSync(path.join(base,'index.html'),'utf8')
const css=fs.readFileSync(path.join(base,'kbx-fe.css'),'utf8')
const js=fs.readFileSync(path.join(base,'kbx-fe.js'),'utf8')
for(const token of ['global-header','side-nav','workspaceTabs','menuSearchDialog','lookupDialog','unsavedDialog','quantityDialog','exceptionDialog','drawerBackdrop','Content-Security-Policy']){
if(!html.includes(token))errors.push(`html missing ${token}`)
}
for(const token of ['--header-h:56px','--nav-w:220px','--nav-collapsed:56px','--control-h:34px','.wms-phone','.data-state','.confirm-dialog','.cell-editor','.scan-box.scan-error','.validation-summary','.action-result']){
if(!css.includes(token))errors.push(`css missing ${token}`)
}
for(const template of ['T01','T02','T03','T04','T05','T06','T07','T08','T09']){
if(!js.includes(template))errors.push(`js missing ${template}`)
}
for(const behavior of ['requestCloseTab','pendingNavigationId','openLookup','bindLookups','showUtilityPanel','applyIntent','orderQuickFilter','orderDataState','fastRows','inventoryItemId','queueFilter','mismatchOnly','importStep','importJobStatus','startImportJob','applyScan','lastScanValue','networkStatus','selectedOrders','toggleFavorite','orderSearch','captureOrderSearch','masterDraft','validateMasterDraft','transactionHeader','validateTransaction','selectedQueueRows','selectedReconcileRows','trySaveDirtyScreen','beforeunload']){
if(!js.includes(behavior))errors.push(`js missing behavior ${behavior}`)
}
for(const security of ["const esc =",'knownIds','try{ localStorage.setItem','localStorage.getItem']){
if(!js.includes(security))errors.push(`security/stability contract missing ${security}`)
}
for(const forbidden of ['prompt(','eval(','document.write(']){
if(js.includes(forbidden))errors.push(`forbidden FE pattern ${forbidden}`)
}
if(!js.includes("selection===0"))errors.push('selection-dependent command disabling missing')
if(!js.includes("e.key==='Enter'"))errors.push('keyboard Enter flow missing')
if(!js.includes("e.key==='Escape'"))errors.push('Escape recovery flow missing')
}
if(errors.length){
console.error('FE reference validation failed')
for(const error of errors)console.error(`- ${error}`)
process.exit(1)
}
console.log('FE reference validation passed: v44 completion loops + themed state/recovery + non-modal runtime center + secure shell + async import + WMS guards')