22 lines
3.0 KiB
JavaScript
22 lines
3.0 KiB
JavaScript
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
const root=process.cwd();const fail=[];const read=p=>fs.readFileSync(path.join(root,p),'utf8')
|
|
const manifest=read('packages/kbx-ui/src/registry/templateManifest.ts')
|
|
for(const code of ['T01','T02','T03','T04','T05','T06','T07','T08','T09'])if(!manifest.includes(`code:'${code}'`))fail.push(`template manifest missing ${code}`)
|
|
for(const type of ['list','master','transaction','fast-entry','master-detail','queue','reconcile','import','wms-mobile'])if(!manifest.includes(`type:'${type}'`))fail.push(`template manifest missing type ${type}`)
|
|
for(const file of ['KbxListPage.vue','KbxMasterPage.vue','KbxTransactionPage.vue','KbxFastEntryPage.vue','KbxMasterDetailPage.vue','KbxQueuePage.vue','KbxReconcilePage.vue','KbxImportPage.vue']){
|
|
const text=read(`packages/kbx-ui/src/components/${file}`)
|
|
if(!text.includes('KbxTemplateContextBar'))fail.push(`${file} missing shared template context surface`)
|
|
}
|
|
const reconcile=read('packages/kbx-ui/src/components/KbxReconcilePage.vue');for(const x of ['name="resolution"','name="audit"','name="detail"'])if(!reconcile.includes(x))fail.push(`T07 missing ${x}`)
|
|
const imp=read('packages/kbx-ui/src/components/KbxImportPage.vue');if(!imp.includes('name="result"'))fail.push('T08 missing result surface')
|
|
const wms=read('packages/kbx-ui/src/wms/KbxWmsMobilePage.vue');for(const x of ['taskContext','instruction','name="context"','name="actions"'])if(!wms.includes(x))fail.push(`T09 missing ${x}`)
|
|
const home=read('packages/kbx-ui/src/shell/KbxHomePage.vue');for(const x of ['이어서 작업','resumeTab','selectedModule','모듈별 업무'])if(!home.includes(x))fail.push(`Home missing ${x}`)
|
|
const side=read('packages/kbx-ui/src/shell/KbxSideNavigation.vue');for(const x of ['module-switcher','menuSearch','selectedModule','최근메뉴'])if(!side.includes(x))fail.push(`Side navigation missing ${x}`)
|
|
const search=read('packages/kbx-ui/src/shell/KbxMenuSearch.vue');if(!search.includes('priorityScreenIds'))fail.push('Menu search missing favorite/recent priority')
|
|
const store=read('apps/web/src/shell/workspaceStore.ts');for(const x of ['setPreferenceScope','STORAGE_PREFIX','normalizePreference','encodeURIComponent','if(scopeKey.value','syncRoute(screenId:string,title:string,path:string,recent?:'])if(!store.includes(x))fail.push(`Preference security missing ${x}`)
|
|
const frame=read('apps/web/src/shell/KbxAppFrame.vue');for(const x of ['preferenceScope','recentPolicy','navEntry.path','setPreferenceScope','item.path.startsWith(nav.path)','allowedTabs'])if(!frame.includes(x))fail.push(`App frame missing secure navigation contract ${x}`)
|
|
const tabs=read('packages/kbx-ui/src/shell/KbxWorkspaceTabs.vue');for(const x of ["role=\"tablist\"","ArrowLeft","ArrowRight","Delete",':max-tabs']){if(x===':max-tabs')continue;if(!tabs.includes(x))fail.push(`Workspace tabs missing ${x}`)}
|
|
if(fail.length){console.error(fail.join('\n'));process.exit(1)}
|
|
console.log('v28 template/navigation hardening validation passed for T01-T09, Home, secure preferences, menu search, and workspace tabs.')
|