Harden MVP runtime and fix packaged desktop white screen
This commit is contained in:
97
scripts/mvp-check.cjs
Normal file
97
scripts/mvp-check.cjs
Normal file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const args = new Set(process.argv.slice(2));
|
||||
if (args.has('--help') || args.has('-h')) {
|
||||
console.log('Project Hub MVP readiness check');
|
||||
console.log('');
|
||||
console.log('Usage:');
|
||||
console.log(' node scripts/mvp-check.cjs [--restart-backend]');
|
||||
console.log('');
|
||||
console.log('Environment:');
|
||||
console.log(' API_BASE default: http://localhost:4000/api');
|
||||
console.log(' WRITE_API_KEY optional x-api-key for write endpoints');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const backendPort = process.env.PORT_BACKEND || '4000';
|
||||
const API_BASE = process.env.API_BASE || `http://localhost:${backendPort}/api`;
|
||||
const HEALTH_URL = API_BASE.replace(/\/api\/?$/, '') + '/health';
|
||||
const RESTART_BACKEND = args.has('--restart-backend');
|
||||
|
||||
function log(msg) {
|
||||
console.log(`[mvp-check] ${msg}`);
|
||||
}
|
||||
|
||||
function formatCheck(status, name, detail = '') {
|
||||
const suffix = detail ? `: ${detail}` : '';
|
||||
console.log(`[mvp-check] ${status} ${name}${suffix}`);
|
||||
}
|
||||
|
||||
async function checkHealth() {
|
||||
try {
|
||||
const response = await fetch(HEALTH_URL, { signal: AbortSignal.timeout(5000) });
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}`);
|
||||
}
|
||||
return { ok: true };
|
||||
} catch (err) {
|
||||
return { ok: false, detail: err.message };
|
||||
}
|
||||
}
|
||||
|
||||
function runNodeScript(scriptPath, scriptArgs = []) {
|
||||
const result = spawnSync(process.execPath, [scriptPath, ...scriptArgs], {
|
||||
env: process.env,
|
||||
encoding: 'utf8',
|
||||
maxBuffer: 10 * 1024 * 1024,
|
||||
});
|
||||
|
||||
const output = [result.stdout || '', result.stderr || ''].join('').trim();
|
||||
const lines = output ? output.split(/\r?\n/).filter(Boolean) : [];
|
||||
const tail = lines.slice(-6).join(' | ');
|
||||
|
||||
if (result.error) {
|
||||
return { ok: false, detail: result.error.message };
|
||||
}
|
||||
if (result.status !== 0) {
|
||||
return { ok: false, detail: tail || `exit ${result.status}` };
|
||||
}
|
||||
return { ok: true, detail: tail };
|
||||
}
|
||||
|
||||
async function run() {
|
||||
log('Starting MVP hardening checks...');
|
||||
log(`API base: ${API_BASE}`);
|
||||
|
||||
const results = [];
|
||||
|
||||
const health = await checkHealth();
|
||||
results.push({ name: 'backend-health', ...health });
|
||||
formatCheck(health.ok ? 'PASS' : 'FAIL', 'backend-health', health.detail || HEALTH_URL);
|
||||
|
||||
const wiring = runNodeScript('scripts/wiring-smoke-test.cjs');
|
||||
results.push({ name: 'wiring-smoke', ...wiring });
|
||||
formatCheck(wiring.ok ? 'PASS' : 'FAIL', 'wiring-smoke', wiring.detail);
|
||||
|
||||
const persistenceArgs = RESTART_BACKEND ? ['--restart-backend'] : [];
|
||||
const persistence = runNodeScript('scripts/persistence-self-test.cjs', persistenceArgs);
|
||||
results.push({ name: RESTART_BACKEND ? 'persistence-restart' : 'persistence', ...persistence });
|
||||
formatCheck(persistence.ok ? 'PASS' : 'FAIL', RESTART_BACKEND ? 'persistence-restart' : 'persistence', persistence.detail);
|
||||
|
||||
const failed = results.filter(r => !r.ok);
|
||||
if (failed.length > 0) {
|
||||
log('NOT READY');
|
||||
log(`Failed checks: ${failed.map(f => f.name).join(', ')}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
log('READY');
|
||||
log('All automated MVP hardening checks passed.');
|
||||
}
|
||||
|
||||
run().catch(err => {
|
||||
log(`NOT READY: ${err.message}`);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user