43 lines
3.7 KiB
JavaScript
43 lines
3.7 KiB
JavaScript
import fs from 'node:fs'
|
|
const read=p=>fs.readFileSync(p,'utf8')
|
|
const failures=[]
|
|
const check=(ok,msg)=>{if(!ok)failures.push(msg)}
|
|
const manifest=read('packages/kbx-ui/src/registry/componentManifest.ts')
|
|
const componentVersion=(name)=>{const match=manifest.match(new RegExp(`${name}[^\\n]+version:\\s*['\"]([^'\"]+)['\"]`));return match?.[1]??''}
|
|
const atLeast=(actual,minimum)=>{const a=actual.split('.').map(Number),m=minimum.split('.').map(Number);for(let i=0;i<3;i++){if((a[i]??0)>(m[i]??0))return true;if((a[i]??0)<(m[i]??0))return false}return true}
|
|
|
|
const boundary=read('packages/kbx-ui/src/components/KbxTemplateStateBoundary.vue')
|
|
for(const token of ['errorRetryable?: boolean','errorRetryable:true',"props.errorRetryable ? retryLabel : ''"])check(boundary.includes(token),`TemplateStateBoundary retry truth missing: ${token}`)
|
|
check(atLeast(componentVersion('KbxTemplateStateBoundary'),'1.3.0'),'KbxTemplateStateBoundary must be >= 1.3.0')
|
|
|
|
for(const rel of ['KbxListPage.vue','KbxMasterPage.vue','KbxTransactionPage.vue','KbxFastEntryPage.vue','KbxMasterDetailPage.vue','KbxQueuePage.vue','KbxReconcilePage.vue','KbxImportPage.vue']){
|
|
const src=read(`packages/kbx-ui/src/components/${rel}`)
|
|
check(src.includes('errorRetryable'),`${rel} must expose errorRetryable`)
|
|
check(src.includes(':error-retryable="errorRetryable"'),`${rel} must propagate errorRetryable to the state boundary`)
|
|
}
|
|
const workQueue=read('packages/kbx-ui/src/components/KbxWorkQueuePage.vue')
|
|
check(workQueue.includes(':error-retryable="errorRetryable"'),'KbxWorkQueuePage must preserve retryability through the T06 alias')
|
|
const wmsShell=read('packages/kbx-ui/src/wms/KbxWmsMobilePage.vue')
|
|
check(wmsShell.includes('errorRetryable?: boolean')&&wmsShell.includes(':error-retryable="errorRetryable !== false"'),'T09 shell must expose non-retryable errors')
|
|
|
|
const workApi=read('apps/web/src/modules/wms/work/workApi.ts')
|
|
check(workApi.includes("code:'WMS_WORK_QUERY_NOT_CONNECTED'")&&workApi.includes('retryable:false'),'Permanent WMS API-not-connected problem must not claim retryability')
|
|
const workPage=read('apps/web/src/modules/wms/work/WmsWorkPage.vue')
|
|
check(workPage.includes(':error-retryable="queryProblem?.retryable !== false"'),'WMS Work must bind problem retryability to T06')
|
|
|
|
const home=read('packages/kbx-ui/src/shell/KbxHomePage.vue')
|
|
for(const token of ['attentionToggleLabel','`우선 ${attentionExpandedLimit}개 보기`','attentionOperationCount','attentionNotificationCount','kbx-home__attention-centers','작업 센터 전체','알림 센터 전체'])check(home.includes(token),`Home overflow truth/navigation missing: ${token}`)
|
|
check(atLeast(componentVersion('KbxHomePage'),'1.10.0'),'KbxHomePage must be >= 1.10.0')
|
|
check(atLeast(componentVersion('KbxQueuePage'),'1.9.0'),'KbxQueuePage must be >= 1.9.0')
|
|
|
|
const ref=read('apps/web/fe-reference/kbx-fe.js')
|
|
for(const token of ['Array.from({length:18}','const attentionCap=24','`우선 ${attentionCap}개 보기`','attentionOverflow','homeJobsAll','homeNoticesAll',"showSystemPanel('jobs')","showSystemPanel('notices')"])check(ref.includes(token),`Reference Home overflow parity missing: ${token}`)
|
|
const css=read('apps/web/fe-reference/kbx-fe.css')
|
|
check(css.includes('.attention-centers'),'Reference theme must style Home attention overflow center links')
|
|
|
|
const catalog=read('packages/kbx-ui/src/catalog/componentCatalog.ts')
|
|
check(catalog.includes("id:'error-no-retry'")&&catalog.includes('재시도 불가 오류'),'Component catalog must reproduce non-retryable error state')
|
|
|
|
if(failures.length){console.error('FE operational truth v50 validation failed:');for(const f of failures)console.error(`- ${f}`);process.exit(1)}
|
|
console.log('FE operational truth v50 PASS: truthful retryability + bounded Home attention overflow routes + Light/Dark reference parity.')
|