Files
KArtSell.Aegis/docs/Design/kbx-foundation-v60-status-canonical-contract-hardening/scripts/validate-golden-fe-parity-v41.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

82 lines
2.9 KiB
JavaScript

import fs from 'node:fs'
const failures=[]
const read=path=>fs.readFileSync(path,'utf8')
const requireTokens=(path,tokens)=>{
const text=read(path)
for(const token of tokens)if(!text.includes(token))failures.push(`${path} missing ${token}`)
return text
}
const grid=requireTokens('packages/kbx-ui/src/components/KbxDataGrid.vue',[
"mode:'multiRow'",
'checkboxes:true',
'headerCheckbox:true',
'syncSelectionState',
'gridErrors',
'focusNextEditableCell',
'selectRowByKey',
'defineExpose',
])
if(grid.includes("row-selection=\"selection==='multiple'?'multiple'"))failures.push('KbxDataGrid still uses deprecated string rowSelection configuration')
const lookup=requireTokens('packages/kbx-ui/src/components/KbxLookup.vue',[
'focusNextControl',
'dialogWasOpen',
'`${label} 코드`',
'`${label} 검색`',
])
if(lookup.includes('aria-label="코드"'))failures.push('KbxLookup exposes ambiguous duplicate code labels')
requireTokens('packages/kbx-ui/src/shell/KbxUnsavedChangesDialog.vue',[
"event.key === 'Escape'",
"event.key !== 'Tab'",
'restoreFocus',
'aria-describedby="unsaved-detail"',
])
const orderList=requireTokens('apps/web/src/modules/oms/orders/search/OrderListPage.vue',[
'OrderDetailDrawer',
'@drill-down-requested="openDetail"',
'@row-double-clicked="openDetail"',
'orderApi.getDetail',
'exportCsv',
])
if(orderList.includes('@row-double-clicked="row=>router.push'))failures.push('OMS-ORD-001 still destroys list context on double click')
const orderDefinition=read('apps/web/src/modules/oms/orders/search/order-list.definition.ts')
if(orderDefinition.includes("id: 'hold'"))failures.push('OMS-ORD-001 exposes Hold command without an implemented domain operation')
requireTokens('apps/web/src/modules/erp/items/ItemMasterPage.vue',[
'pendingTransition',
'KbxUnsavedChangesDialog',
'selectRowByKey',
'saveThenTransition',
'@selection-changed="requestChoose"',
])
requireTokens('apps/web/src/modules/oms/orders/register/OrderRegisterPage.vue',[
'pendingReset',
'KbxUnsavedChangesDialog',
'focusNextEditableCell',
'copyCurrent',
'ref="detailGrid"',
])
const registration=read('apps/web/src/modules/oms/orders/register/useOrderRegistration.ts')
for(const token of ['return false','return true','function copyCurrent'])if(!registration.includes(token))failures.push(`useOrderRegistration missing ${token}`)
for(const path of [
'apps/web/src/modules/oms/orders/search/useOrderSearch.ts',
'apps/web/src/modules/oms/orders/register/OrderRegisterPage.vue',
'apps/web/src/modules/erp/items/ItemMasterPage.vue',
]){
if(read(path).includes('Promise.resolve()'))failures.push(`${path} contains a visible-command no-op Promise.resolve()`)
}
if(failures.length){
console.error('Golden FE parity v41 validation failed:\n- '+failures.join('\n- '))
process.exit(1)
}
console.log('Golden FE parity v41 PASS: controlled AG Grid selection, detail Drawer context, Lookup focus continuation, and dirty intra-screen transitions.')