industry-service.mjs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. /** Production entry point. Loopback only; the existing gateway owns browser access. */
  2. import { createServer } from 'node:http';
  3. import path from 'node:path';
  4. import { fileURLToPath } from 'node:url';
  5. import { createIndustryApi } from './industry-api.mjs';
  6. export function serviceConfig(env = process.env) {
  7. if (!env.KSF_LIBRARY_API_TOKEN) throw Error('KSF_LIBRARY_API_TOKEN_REQUIRED');
  8. const sources = [env.KSF_UNIFIED_DB_CONFIG, env.KSF_LIBRARY_REGISTRY, env.KSF_VOC_DB, env.KSF_INDUSTRY_SNAPSHOT].filter(Boolean);
  9. if (sources.length !== 1) throw Error('EXACTLY_ONE_DATA_BINDING_REQUIRED');
  10. const port = Number(env.KSF_INDUSTRY_PORT || 4190);
  11. if (!Number.isInteger(port) || port < 1024 || port > 65535) throw Error('INVALID_INDUSTRY_PORT');
  12. return { registry: env.KSF_LIBRARY_REGISTRY, db: env.KSF_VOC_DB,
  13. unifiedConfig: env.KSF_UNIFIED_DB_CONFIG,
  14. snapshot: env.KSF_INDUSTRY_SNAPSHOT, monitoringStore: env.KSF_MONITORING_STORE,
  15. policyUsageReview: env.KSF_INDUSTRY_POLICY_USAGE_REVIEW, policyUsageSha256: env.KSF_INDUSTRY_POLICY_USAGE_SHA256,
  16. token: env.KSF_LIBRARY_API_TOKEN, python: env.KSF_LIBRARY_PYTHON || 'python3', port };
  17. }
  18. export function createIndustryService(config) {
  19. const handler = createIndustryApi(config);
  20. const server = createServer((req, res) => {
  21. if (req.url !== '/api/industry') {
  22. res.writeHead(404, { 'content-type': 'application/json', 'cache-control': 'no-store' });
  23. return res.end(JSON.stringify({ ok: false, error: { code: 'NOT_FOUND' } }));
  24. }
  25. return handler(req, res);
  26. });
  27. server.requestTimeout = 35000;
  28. server.on('close', handler.close);
  29. server.headersTimeout = 10000;
  30. return server;
  31. }
  32. if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
  33. const config = serviceConfig();
  34. const server = createIndustryService(config);
  35. server.listen(config.port, '127.0.0.1', () => process.stdout.write('Industry read service listening on loopback\n'));
  36. const close = () => { server.close(); setTimeout(() => process.exit(1), 30000).unref(); };
  37. process.on('SIGTERM', close);
  38. process.on('SIGINT', close);
  39. }