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

67 lines
5.8 KiB
JavaScript

import fs from 'node:fs'
const read = (file) => fs.readFileSync(file, 'utf8')
const expect = (condition, message) => {
if (!condition) {
console.error(`FAIL: ${message}`)
process.exit(1)
}
console.log(`PASS: ${message}`)
}
const home = read('packages/kbx-ui/src/shell/KbxHomePage.vue')
expect(home.includes('allAttentionQueue') && home.includes('attentionCount:'), 'home module rail derives action pressure from the same attention truth as the home queue')
expect(home.includes("['ArrowLeft','ArrowRight','Home','End']") && home.includes('focusModuleRail'), 'home module rail is keyboard navigable without requiring mouse selection')
expect(home.includes('data-home-module="ALL"') && home.includes(':data-home-module="item.module"'), 'home module rail exposes stable focus targets')
expect(home.includes("explorer?.focus({preventScroll:true})"), 'module selection lands focus on the filtered work explorer')
expect(home.includes('@media(forced-colors:active)') && home.includes('button:focus-visible'), 'home module rail preserves active/focus cues in high-contrast navigation')
const sectionHeader = read('packages/kbx-ui/src/components/KbxSectionHeader.vue')
expect(sectionHeader.includes('countUnit?:string') && sectionHeader.includes("countUnit:'건'"), 'standard section heading owns count units instead of forcing screen-specific count markup')
for (const [file, slot] of [
['packages/kbx-ui/src/components/KbxMasterPage.vue', 'list-actions'],
['packages/kbx-ui/src/components/KbxMasterPage.vue', 'detail-actions'],
['packages/kbx-ui/src/components/KbxTransactionPage.vue', 'header-actions'],
['packages/kbx-ui/src/components/KbxTransactionPage.vue', 'detail-actions'],
['packages/kbx-ui/src/components/KbxQueuePage.vue', 'queue-actions'],
['packages/kbx-ui/src/components/KbxReconcilePage.vue', 'comparison-actions'],
]) {
expect(read(file).includes(`slot name="${slot}"`), `${file.split('/').at(-1)} exposes standard ${slot} work-surface actions`)
}
const order = read('apps/web/src/modules/oms/orders/register/OrderRegisterPage.vue')
expect(order.includes('const pageContext = computed') && order.includes(':context="pageContext"'), 'OMS order registration makes current record/status/error context explicit')
expect(order.includes('<template #detail-actions>') && order.includes('focusNextError') && order.includes('addLineAndFocus'), 'OMS order registration exposes row-add and error recovery beside the detail work surface')
expect(order.includes('detail-count-unit="종"'), 'OMS order detail count uses business-meaningful unit')
const purchase = read('apps/web/src/modules/erp/purchases/PurchasePage.vue')
expect(purchase.includes('useKbxDirtyState') && purchase.includes('useKbxWorkspaceBinding'), 'ERP purchase draft participates in workspace dirty-state recovery')
expect(purchase.includes('KbxLookupDialog') && purchase.includes('lookupRegistry.item.resolveByCode'), 'ERP purchase grid supports both F2 lookup and direct item-code resolution')
expect(purchase.includes('KbxValidationError') && purchase.includes('validateDraft()'), 'ERP purchase draft has field/row validation before save intent')
expect(!purchase.includes("status.value='CONFIRMED'") && purchase.includes('상태를 변경하지 않았습니다'), 'ERP purchase does not fabricate authoritative workflow state on the client')
expect(purchase.includes('editing-policy') && purchase.includes('row-duplicate-requested'), 'ERP purchase detail supports real fast-entry grid interactions')
const move = read('apps/web/src/modules/erp/inventory-move/InventoryMovePage.vue')
expect(move.includes('WAREHOUSE_MUST_DIFFER') && move.includes('INSUFFICIENT_STOCK'), 'ERP inventory move gives immediate cross-field and stock UX validation')
expect(move.includes('metadata?.availableQty') && move.includes('KbxLookupDialog'), 'ERP inventory move resolves item availability into the editing grid')
expect(!move.includes('status.value=t.to') && move.includes('상태를 변경하지 않았습니다'), 'ERP inventory move does not simulate Domain workflow transitions on the client')
expect(move.includes('useKbxPageShortcuts') && move.includes("key:'F8'"), 'ERP inventory move participates in the common save keyboard contract')
const wmsPage = read('apps/web/src/modules/wms/picking/WmsPickingPage.vue')
const wmsVm = read('apps/web/src/modules/wms/picking/useWmsPicking.ts')
expect(wmsPage.includes(':task-context="taskContext"') && wmsPage.includes(':instruction="stageTitle"'), 'WMS picking exposes task context and next instruction through the T09 template contract')
expect(wmsPage.includes('<template #notice>') && wmsPage.includes('pendingCommands') && wmsPage.includes('오프라인'), 'WMS picking dedicates a persistent notice surface to offline/retry truth')
expect(wmsPage.includes('다음 행동') && wmsPage.includes('중복 스캔하지 말고'), 'WMS picking tells the operator what to do next and prevents ambiguous repeat scans')
expect(wmsVm.includes("return '위치 스캔'") && wmsVm.includes("return '상품 스캔'"), 'WMS scanner labels use operator-facing Korean terminology')
const referenceHtml = read('apps/web/fe-reference/index.html')
const referenceJs = read('apps/web/fe-reference/kbx-fe.js')
const referenceCss = read('apps/web/fe-reference/kbx-fe.css')
expect(referenceHtml.includes('FE Reference Lab v53'), 'static HTML reference identifies the v53 golden-screen interaction build')
expect(referenceJs.includes('moduleAttentionCount') && referenceJs.includes('확인 ${moduleAttentionCount(module)}'), 'static JavaScript reference mirrors module attention pressure')
expect(referenceJs.includes("e.key==='ArrowRight'") && referenceJs.includes("e.key==='Home'"), 'static JavaScript module rail mirrors keyboard navigation')
expect(referenceCss.includes('.home-module-rail button:focus-visible'), 'static HTML reference visibly exposes module keyboard focus')
console.log('PASS: FE golden-screen interaction hardening v53 contract')