feat(runtime): add production control-plane foundation

This commit is contained in:
chick
2026-07-18 12:43:46 +08:00
parent 9451e1ee42
commit 293c015f89
13 changed files with 513 additions and 31 deletions
+62
View File
@@ -0,0 +1,62 @@
import type Database from 'better-sqlite3';
import { stat as fsStat } from 'node:fs/promises';
import { MIGRATIONS } from './infrastructure/database/migrations.js';
import type { ReadinessResult } from './app.js';
export interface ProductionReadinessOptions {
readonly db: Database.Database;
readonly gatewayToken: string;
/** Metadata/availability probe only. This callback must never retrieve a secret. */
readonly keychainMetadataCheck: () => boolean | Promise<boolean>;
}
interface ExecutableMetadata {
isFile(): boolean;
readonly mode: number;
}
export async function defaultKeychainMetadataCheck(
platform: NodeJS.Platform = process.platform,
stat: (path: string) => Promise<ExecutableMetadata> = fsStat,
): Promise<boolean> {
if (platform !== 'darwin') return false;
try {
const metadata = await stat('/usr/bin/security');
return metadata.isFile() && (metadata.mode & 0o111) !== 0;
} catch {
return false;
}
}
export function createProductionReadiness(
options: ProductionReadinessOptions,
): () => Promise<ReadinessResult> {
return async () => {
const checks: Record<string, string> = {};
let ready = true;
try {
options.db.prepare('SELECT 1').get();
checks.database = 'ready';
} catch {
checks.database = 'unavailable';
ready = false;
}
try {
const expected = MIGRATIONS.at(-1)?.id ?? 0;
const row = options.db.prepare('SELECT MAX(id) AS id FROM schema_migrations').get() as {
id: number | null;
};
checks.migrations = row.id === expected ? 'ready' : 'pending';
if (row.id !== expected) ready = false;
} catch {
checks.migrations = 'unavailable';
ready = false;
}
checks.gatewayAuth = Buffer.byteLength(options.gatewayToken) >= 32 ? 'ready' : 'unconfigured';
if (checks.gatewayAuth !== 'ready') ready = false;
try {
checks.keychain = (await options.keychainMetadataCheck()) ? 'ready' : 'unavailable';
} catch {
checks.keychain = 'unavailable';
}
if (checks.keychain !== 'ready') ready = false;
return { ready, checks };
};
}