38 lines
2.7 KiB
JavaScript
38 lines
2.7 KiB
JavaScript
// Read-only source census. Route presence does not establish workflow or security acceptance.
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import crypto from 'node:crypto';
|
|
import assert from 'node:assert/strict';
|
|
import { execFileSync } from 'node:child_process';
|
|
import ts from 'typescript';
|
|
const root = path.resolve(import.meta.dirname, '../..');
|
|
const registerPath = 'docs/pre-phase10-ux/preservation.json';
|
|
const registerBytes = fs.readFileSync(path.join(root, registerPath));
|
|
const register = JSON.parse(registerBytes);
|
|
const base = 'd3d338376444b8abdcaf7200f682faa3daf1ad10';
|
|
const digest = bytes => crypto.createHash('sha256').update(bytes.toString('utf8').replace(/\r\n/g, '\n')).digest('hex');
|
|
assert.equal(digest(registerBytes), digest(execFileSync('git', ['show', `${base}:${registerPath}`], { cwd: root })), 'Original preservation register must remain unchanged');
|
|
assert.equal(register.groups.length, 57); assert.equal(register.routes.length, 34);
|
|
const source = fs.readFileSync(path.join(root, 'job-tracker-ui/src/App.tsx'), 'utf8');
|
|
const ast = ts.createSourceFile('App.tsx', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
const declared = new Set();
|
|
function visit(node) {
|
|
if (ts.isJsxAttribute(node) && node.name.getText(ast) === 'path' && node.initializer && ts.isStringLiteral(node.initializer)) declared.add(node.initializer.text);
|
|
if (ts.isPropertyAssignment(node) && node.name.getText(ast) === 'path' && ts.isStringLiteral(node.initializer)) declared.add(node.initializer.text);
|
|
ts.forEachChild(node, visit);
|
|
}
|
|
visit(ast);
|
|
const missing = register.routes.filter(item => !declared.has(item.route));
|
|
assert.deepEqual(missing, [], 'All inherited route patterns must remain registered');
|
|
const result = {
|
|
base, policy: 'Source membership and unchanged criteria only; no acceptance promotion.',
|
|
sourceSha256: digest(source), registerSha256: digest(registerBytes),
|
|
groups: register.groups.map(({ id, currentStatus, requiredClosure, sourceCriterion }) => ({ id, currentStatus, requiredClosure, sourceCriterion })),
|
|
routes: register.routes.map(({ route, owners, requiredClosure }) => ({ route, owners, requiredClosure, sourceMembership: 'PRESENT' })),
|
|
limits: ['57 historical group statuses and original criteria retained, not promoted.', 'Not browser/auth/provider/native/deployed or whole-capability acceptance. CalendarPage retains the original reminder route and owner internally.'],
|
|
};
|
|
const out = path.join(root, 'docs/ui-modernisation/evidence/cross-app');
|
|
fs.mkdirSync(out, { recursive: true });
|
|
fs.writeFileSync(path.join(out, 'PRESERVATION_CENSUS.json'), JSON.stringify(result, null, 2));
|
|
console.log('PASS:57 unchanged preservation groups,34 inherited route patterns present in the TypeScript AST.');
|