import fs from 'node:fs'; import path from 'node:path'; const root = process.cwd(); const contractPath = path.join(root, 'docs/contracts/admin-enterprise-applications-r11.json'); const contract = JSON.parse(fs.readFileSync(contractPath, 'utf8')); const read = (file) => fs.readFileSync(path.join(root, file), 'utf8'); const failures = []; function requirePattern(source, pattern, message) { if (!pattern.test(source)) failures.push(message); } const entry = read(contract.stableEntry); const entryLines = entry.split(/\r?\n/).length; requirePattern( entry, new RegExp(`export\\s+function\\s+${contract.stableExport}\\s*\\(`), `stable export ${contract.stableExport} is missing`, ); if (entryLines > contract.maxStableEntryLines) { failures.push(`stable entry has ${entryLines} lines; maximum is ${contract.maxStableEntryLines}`); } if (!entry.includes(`import '${contract.styleImport}';`)) { failures.push(`stable entry does not import ${contract.styleImport}`); } const moduleSources = []; for (const [file, exports] of Object.entries(contract.modules)) { const source = read(file); moduleSources.push(source); for (const exportedName of exports) { requirePattern( source, new RegExp(`export\\s+(?:function|const|class)\\s+${exportedName}\\b`), `${file} is missing export ${exportedName}`, ); } if (source.includes('adminApi.')) { failures.push(`${file} must not move real API coordination out of the stable entry`); } } for (const [file, methods] of Object.entries(contract.apiCalls)) { const source = read(file); for (const method of methods) { requirePattern(source, new RegExp(`adminApi\\.${method}\\b`), `${file} is missing adminApi.${method}`); } } const style = read(contract.styleFile); const globalStyle = read('src/styles/global.css'); const adminStyle = read('src/styles/admin.css'); const componentStyle = read('src/styles/components.css'); const shellStyle = read('src/styles/shell.css'); for (const selector of contract.pageStyleSelectors) { if (!style.includes(selector)) failures.push(`${contract.styleFile} is missing ${selector}`); if (globalStyle.includes(selector)) failures.push(`src/styles/global.css still contains page selector ${selector}`); } for (const selector of contract.sharedSelectorsKeptGlobal) { if (!globalStyle.includes(selector)) failures.push(`shared selector ${selector} was removed from global.css`); } for (const selector of contract.sharedSelectorsKeptInAdmin) { if (!adminStyle.includes(selector)) failures.push(`shared selector ${selector} was removed from admin.css`); if (globalStyle.includes(selector)) failures.push(`shared selector ${selector} still exists in global.css`); } for (const selector of contract.sharedSelectorsKeptInComponents) { if (!componentStyle.includes(selector)) failures.push(`shared selector ${selector} was removed from components.css`); if (globalStyle.includes(selector)) failures.push(`shared selector ${selector} still exists in global.css`); } for (const selector of contract.sharedSelectorsKeptInShell) { if (!shellStyle.includes(selector)) failures.push(`shared selector ${selector} was removed from shell.css`); if (globalStyle.includes(selector)) failures.push(`shared selector ${selector} still exists in global.css`); } for (const label of contract.interactionLabels) { if (![entry, ...moduleSources].some((source) => source.includes(label))) { failures.push(`interaction label ${label} is missing`); } } requirePattern( style, /@media\s*\(max-width:\s*780px\)[\s\S]*?\.admin-application-filter[\s\S]*?grid-template-columns:\s*1fr/, '780px enterprise application filter responsive rule is missing', ); requirePattern( style, /@media\s*\(max-width:\s*900px\)[\s\S]*?\.cmpp-connection-summary[\s\S]*?\.cmpp-connection-card__grid/, '900px CMPP connection responsive rule is missing', ); requirePattern( style, /@media\s*\(max-width:\s*520px\)[\s\S]*?\.cmpp-connection-summary[\s\S]*?\.cmpp-connection-card__grid/, '520px CMPP connection responsive rule is missing', ); requirePattern( entry, /const \[appliedEnterpriseKeyword,[\s\S]*?const \[appliedApplicationKeyword,[\s\S]*?const \[appliedStatus,/, 'draft and applied filter state separation is missing', ); if (failures.length > 0) { console.error(`R11 admin enterprise applications verification failed:\n- ${failures.join('\n- ')}`); process.exit(1); } console.log( `R11 admin enterprise applications verified: ${entryLines} stable-entry lines, ` + `${Object.keys(contract.modules).length} focused modules, real API coordination and page-scoped CSS preserved.`, );