const fs = require('fs'); const path = require('path'); const YAML = require('yaml'); const configPath = path.join(__dirname, 'app.yaml'); function toInt(value, fallback) { const parsed = Number.parseInt(value, 10); return Number.isFinite(parsed) ? parsed : fallback; } function loadYamlConfig(filePath) { if (!fs.existsSync(filePath)) { throw new Error(`config file not found: ${filePath}`); } const raw = fs.readFileSync(filePath, 'utf8'); return YAML.parse(raw) || {}; } function buildConfig() { const parsed = loadYamlConfig(configPath); const host = parsed.host || {}; const instrumentEntities = Object.entries(parsed) .filter(([key, value]) => key !== 'host' && key !== 'instruments' && value && typeof value === 'object') .map(([instrumentId, value]) => ({ instrument_id: instrumentId, ...value })); return { env: host.env || 'development', db: { path: host.db?.path || 'middleware/data/workstation.sqlite', busyTimeout: toInt(host.db?.busyTimeout, 5000) }, connectors: { httpJsonPort: toInt(host.connectors?.httpJsonPort, 3001), hl7TcpPort: toInt(host.connectors?.hl7TcpPort, 3002), astmSerialPath: host.connectors?.astmSerialPath || 'COM1', astmSerialBaudRate: toInt(host.connectors?.astmSerialBaudRate, 9600), astmSerialDataBits: toInt(host.connectors?.astmSerialDataBits, 8), astmSerialStopBits: toInt(host.connectors?.astmSerialStopBits, 1), astmSerialParity: host.connectors?.astmSerialParity || 'none' }, clqms: { url: host.url || host.clqms?.url || '', token: host.apikey || host.clqms?.token || '', timeout: toInt(host.clqms?.timeout, 8000) }, healthPort: toInt(host.port || host.healthPort, 4001), worker: { pollInterval: toInt(host.worker?.pollInterval, 5000), batchSize: toInt(host.worker?.batchSize, 5), lockTTLSeconds: toInt(host.worker?.lockTTLSeconds, 60), workerId: host.worker?.workerId || 'worker-default' }, retries: { schedule: host.retries?.schedule || [30, 120, 600, 1800, 7200, 21600], maxAttempts: toInt(host.retries?.maxAttempts, 10) }, instruments: Array.isArray(parsed.instruments) ? parsed.instruments : [], instrumentEntities, configPath }; } module.exports = buildConfig();