/** Production entry point. Loopback only; the existing gateway owns browser access. */ import { createServer } from 'node:http'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { createIndustryApi } from './industry-api.mjs'; export function serviceConfig(env = process.env) { if (!env.KSF_LIBRARY_API_TOKEN) throw Error('KSF_LIBRARY_API_TOKEN_REQUIRED'); const sources = [env.KSF_UNIFIED_DB_CONFIG, env.KSF_LIBRARY_REGISTRY, env.KSF_VOC_DB, env.KSF_INDUSTRY_SNAPSHOT].filter(Boolean); if (sources.length !== 1) throw Error('EXACTLY_ONE_DATA_BINDING_REQUIRED'); const port = Number(env.KSF_INDUSTRY_PORT || 4190); if (!Number.isInteger(port) || port < 1024 || port > 65535) throw Error('INVALID_INDUSTRY_PORT'); return { registry: env.KSF_LIBRARY_REGISTRY, db: env.KSF_VOC_DB, unifiedConfig: env.KSF_UNIFIED_DB_CONFIG, snapshot: env.KSF_INDUSTRY_SNAPSHOT, monitoringStore: env.KSF_MONITORING_STORE, policyUsageReview: env.KSF_INDUSTRY_POLICY_USAGE_REVIEW, policyUsageSha256: env.KSF_INDUSTRY_POLICY_USAGE_SHA256, token: env.KSF_LIBRARY_API_TOKEN, python: env.KSF_LIBRARY_PYTHON || 'python3', port }; } export function createIndustryService(config) { const handler = createIndustryApi(config); const server = createServer((req, res) => { if (req.url !== '/api/industry') { res.writeHead(404, { 'content-type': 'application/json', 'cache-control': 'no-store' }); return res.end(JSON.stringify({ ok: false, error: { code: 'NOT_FOUND' } })); } return handler(req, res); }); server.requestTimeout = 35000; server.on('close', handler.close); server.headersTimeout = 10000; return server; } if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { const config = serviceConfig(); const server = createIndustryService(config); server.listen(config.port, '127.0.0.1', () => process.stdout.write('Industry read service listening on loopback\n')); const close = () => { server.close(); setTimeout(() => process.exit(1), 30000).unref(); }; process.on('SIGTERM', close); process.on('SIGINT', close); }