import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; const root = dirname(dirname(fileURLToPath(import.meta.url))); const read = (path) => readFileSync(join(root, path), 'utf8'); const packageJson = JSON.parse(read('package.json')); assert.equal(packageJson.dependencies.fastify.startsWith('^4.'), true); assert.equal(packageJson.dependencies.zod.startsWith('^3.'), true); assert.equal(packageJson.dependencies.mysql2.startsWith('^3.'), true); assert.equal(packageJson.dependencies.kysely.startsWith('^0.'), true); const tsconfig = JSON.parse(read('tsconfig.json')); assert.equal(tsconfig.compilerOptions.strict, true); assert.equal(tsconfig.compilerOptions.moduleResolution, 'NodeNext'); const appSource = read('src/app.ts'); assert.match(appSource, /genReqId/); assert.match(appSource, /x-trace-id/); assert.match(appSource, /setErrorHandler/); assert.match(appSource, /rateLimit/); assert.match(appSource, /cors/); const configSource = read('src/config.ts'); assert.match(configSource, /z\.object/); assert.match(configSource, /QIPAI_MQTT_URL/); assert.match(configSource, /QIPAI_MYSQL_PASSWORD/); const healthSource = read('src/routes/health.ts'); for (const route of [ '/app-api/health', '/admin-api/health', '/app-api/ready', '/admin-api/ready', '/app-api/version', '/admin-api/version' ]) { assert.match(healthSource, new RegExp(route)); } console.log('PASS: backend M01-A contract is present.');