Files
KArtSell.Aegis/docs/Design/kbx-foundation-v36/scripts/validate-application-shell.mjs
T

14 lines
2.5 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 required=[
'packages/kbx-ui/src/shell/KbxApplicationShell.vue','packages/kbx-ui/src/shell/KbxGlobalHeader.vue','packages/kbx-ui/src/shell/KbxSideNavigation.vue','packages/kbx-ui/src/shell/KbxWorkspaceTabs.vue','packages/kbx-ui/src/shell/KbxMenuSearch.vue','packages/kbx-ui/src/shell/KbxUnsavedChangesDialog.vue','packages/kbx-ui/src/shell/KbxHomePage.vue','packages/kbx-ui/src/shell/KbxAccessDenied.vue','apps/web/src/shell/KbxAppFrame.vue','apps/web/src/shell/navigationCatalog.ts','apps/web/src/shell/workspaceStore.ts','apps/web/src/router/appRoutes.ts','apps/web/src/modules/wms/work/work.definition.ts']
for(const file of required)if(!fs.existsSync(path.join(root,file)))fail.push(`missing ${file}`)
const catalog=read('apps/web/src/shell/navigationCatalog.ts');const ids=[...catalog.matchAll(/screenId:'([^']+)'/g)].map(x=>x[1]);const paths=[...catalog.matchAll(/path:'([^']+)'/g)].map(x=>x[1]);if(new Set(ids).size!==ids.length)fail.push('duplicate navigation screenId');if(new Set(paths).size!==paths.length)fail.push('duplicate navigation path')
const generated=read('apps/web/src/registry/screens.generated.ts');for(const id of ids){if(!generated.includes(`id: '${id}'`)&&!read('generated/screen-manifest.json').includes(`\"id\": \"${id}\"`))fail.push(`navigation unknown screen ${id}`)}
const routes=read('apps/web/src/router/appRoutes.ts');for(const [i,id] of ids.entries()){if(!routes.includes(`path:'${paths[i]}'`)||!routes.includes(`screenId:'${id}'`))fail.push(`route/nav mismatch ${id} ${paths[i]}`)}
const frame=read('apps/web/src/shell/KbxAppFrame.vue');if(!frame.includes('useKbxShortcuts')||!frame.includes("key:'Ctrl+K'")||!frame.includes("scope:'application'"))fail.push('Ctrl+K menu search must use central application-scope shortcut');if(!frame.includes('pendingClose'))fail.push('dirty close handling missing');if(!frame.includes('activeScreenAllowed'))fail.push('direct URL permission guard missing');if(!frame.includes('KbxHomePage'))fail.push('home composition missing')
if(!routes.includes("{path:'/',redirect:'/home'}"))fail.push('root does not open home');const tabs=read('packages/kbx-ui/src/shell/KbxWorkspaceTabs.vue');if(!tabs.includes('더보기 {{ overflowTabs.length }}'))fail.push('workspace overflow missing')
if(fail.length){console.error(fail.join('\n'));process.exit(1)}console.log(`Application shell validation passed for ${ids.length} menu entries.`)