import { Pool } from 'pg'; import { repositoryConnectionString, sslConfiguration, type RepositoryEnvironment } from '../repository-factory'; import { MemoryRemediationStore, PostgresRemediationStore, type RemediationStore } from './remediation-store'; import migration from './migration.sql?raw'; import { PostgresAssessorRepository } from '../postgres/postgres-assessor-repository'; import { remediationReadPortFrom, type RemediationReadPort } from '../../src/remediation/remediation-read-port'; import type { AssessorRepository } from '../../src/persistence/assessor-repository'; export async function createRemediationRuntime(environment: RepositoryEnvironment, repository: AssessorRepository): Promise<{ store: RemediationStore; port: RemediationReadPort; close(): Promise }> { const connectionString = repositoryConnectionString(environment); if (!connectionString) return { store: new MemoryRemediationStore(), port: remediationReadPortFrom(repository, async () => repository.revision), async close() {} }; const hostname = new URL(connectionString).hostname; const pool = new Pool({ connectionString, max: 2, application_name: 'assessor-remediation-writer', ssl: sslConfiguration(environment.ASSESSOR_DATABASE_SSL ?? (['localhost', '127.0.0.1', '[::1]'].includes(hostname) ? 'disable' : 'require')) }); const reader = new Pool({ connectionString, max: 2, application_name: 'assessor-remediation-reader', options: '-c default_transaction_read_only=on', ssl: pool.options.ssl }); try { await pool.query(migration); const readRepository = await PostgresAssessorRepository.openReadOnly(reader); const port = remediationReadPortFrom(readRepository, async () => { const response = await reader.query<{ revision: string }>('SELECT revision FROM assessor_repository_state WHERE singleton = true'); return Number(response.rows[0]?.revision ?? -1); }); return { store: new PostgresRemediationStore(pool), port, async close() { await Promise.all([pool.end(), reader.end()]); } }; } catch (error) { await Promise.all([pool.end(), reader.end()]); throw error; } }