Assessor_2.0/server/remediation/remediation-runtime.ts

27 lines
2.1 KiB
TypeScript

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<void> }> {
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; }
}