Files
KArtSell.Aegis/docs/Design/kbx-foundation-v36/scripts/validate-screen-governance.mjs
T

45 lines
2.5 KiB
JavaScript

import fs from 'node:fs'
import path from 'node:path'
const root = process.cwd()
const modulesRoot = path.join(root, 'apps/web/src/modules')
const helpText = fs.readFileSync(path.join(root, 'apps/web/src/help/helpRegistry.ts'), 'utf8')
const recipeContract = JSON.parse(fs.readFileSync(path.join(root, 'contracts/screens/kbx.screen-recipes.json'), 'utf8'))
const recipeByCode = new Map(recipeContract.recipes.map(recipe => [recipe.code, recipe]))
function walk(dir) {
return fs.readdirSync(dir, { withFileTypes: true }).flatMap(e => e.isDirectory() ? walk(path.join(dir,e.name)) : [path.join(dir,e.name)])
}
const errors = []
const warnings = []
const ids = new Set()
for (const file of walk(modulesRoot).filter(f => /definition\.ts$/.test(f))) {
const text = fs.readFileSync(file, 'utf8')
if (!/defineKbxScreen\s*\(/.test(text)) continue
const match = text.match(/defineKbxScreen\s*\(\s*\{([\s\S]*?)\}\s*\)/)
const body = match?.[1] ?? text
const id = body.match(/\bid:\s*['"]([^'"]+)['"]/)?.[1]
if (!id) { errors.push(`${file}: missing screen id`); continue }
if (ids.has(id)) errors.push(`${id}: duplicated screen id`)
ids.add(id)
const type = body.match(/\btype:\s*['"]([^'"]+)['"]/)?.[1]
const templateCode = body.match(/\btemplateCode:\s*['"]([^'"]+)['"]/)?.[1]
if (!templateCode) errors.push(`${id}: templateCode is required`)
else { const recipe=recipeByCode.get(templateCode); if(!recipe) errors.push(`${id}: unknown templateCode ${templateCode}`); else if(recipe.type!==type) errors.push(`${id}: templateCode ${templateCode} expects ${recipe.type}, found ${type}`) }
const helpKey = body.match(/helpKey:\s*['"]([^'"]+)['"]/)?.[1]
if (helpKey !== id) errors.push(`${id}: helpKey must equal screen id`)
if (!new RegExp(`['"]${id.replace(/[.*+?^${}()|[\]\\]/g,'\\$&')}['"]\\s*:`).test(helpText)) errors.push(`${id}: helpRegistry entry missing`)
if (!/permissions:\s*\[[^\]]+\]/.test(body)) errors.push(`${id}: at least one screen permission is required`)
if (!/telemetry:\s*\{\s*enabled:\s*true\s*\}/.test(body)) warnings.push(`${id}: telemetry enabled is recommended`)
if (/group:\s*['"]workflow['"][\s\S]{0,180}?\}/.test(body) && !/group:\s*['"]workflow['"][\s\S]{0,150}?permission:/.test(body)) warnings.push(`${id}: review workflow commands without explicit permission`)
}
if (errors.length) {
console.error('KBX screen governance FAILED')
errors.forEach(x => console.error(` - ${x}`))
process.exit(1)
}
console.log(`KBX screen governance PASS (${ids.size} screens)`)
warnings.forEach(x => console.warn(` warning: ${x}`))