update config

This commit is contained in:
Alex Holliday committed 2026-03-25 13:48:36 -07:00
1 parent f43b7584a6
commit 1defa52ae8
3 files changed
+115 -34

No files matched your search

+88 -16
View File
@@ -46,6 +46,7 @@ import {
IIncidentService,
INotificationMessageBuilder,
ISettingsService,
SettingsService,
EnvConfig,
} from "@/service/index.js";
@@ -92,9 +93,23 @@ import {
MongoInvitesRepository,
MongoRecoveryTokensRepository,
MongoNotificationsRepository,
MongoIncidentRepository,
MongoIncidentsRepository,
MongoTeamsRepository,
MongoMaintenanceWindowsRepository,
MongoSettingsRepository,
TimescaleMonitorsRepository,
TimescaleChecksRepository,
TimescaleGeoChecksRepository,
TimescaleMonitorStatsRepository,
TimescaleStatusPagesRepository,
TimescaleUsersRepository,
TimescaleInvitesRepository,
TimescaleRecoveryTokensRepository,
TimescaleNotificationsRepository,
TimescaleIncidentsRepository,
TimescaleTeamsRepository,
TimescaleMaintenanceWindowsRepository,
TimescaleSettingsRepository,
IMonitorsRepository,
IChecksRepository,
IGeoChecksRepository,
@@ -110,6 +125,7 @@ import {
IMaintenanceWindowsRepository,
} from "@/repositories/index.js";
import { ILogger } from "@/utils/logger.js";
import TimescaleDB from "@/db/TimescaleDB.js";
export type InitializedServices = {
settingsService: ISettingsService;
@@ -152,32 +168,88 @@ export const initializeServices = async ({
logger,
envSettings,
settingsService,
settingsRepository,
}: {
logger: ILogger;
envSettings: EnvConfig;
settingsService: ISettingsService;
settingsRepository: ISettingsRepository;
}): Promise<InitializedServices> => {
// Create DB
const db = new MongoDB(logger, envSettings);
let dbType = "mongodb";
const connectionString = envSettings.dbConnectionString;
if (connectionString.startsWith("mongodb")) {
dbType = "mongodb";
} else if (connectionString.startsWith("postgresql")) {
dbType = "postgresql";
}
let db: IDb | null = null;
if (dbType === "mongodb") {
db = new MongoDB(logger, envSettings);
} else if (dbType === "postgresql") {
db = new TimescaleDB(logger, envSettings);
}
if (!db) {
throw new Error("Unsupported database type");
}
await db.connect();
let monitorsRepository: IMonitorsRepository;
let checksRepository: IChecksRepository;
let geoChecksRepository: IGeoChecksRepository;
let monitorStatsRepository: IMonitorStatsRepository;
let statusPagesRepository: IStatusPagesRepository;
let usersRepository: IUsersRepository;
let invitesRepository: IInvitesRepository;
let recoveryTokensRepository: IRecoveryTokensRepository;
let settingsRepository: ISettingsRepository;
let notificationsRepository: INotificationsRepository;
let incidentsRepository: IIncidentsRepository;
let teamsRepository: ITeamsRepository;
let maintenanceWindowsRepository: IMaintenanceWindowsRepository;
// Repositories
const monitorsRepository = new MongoMonitorsRepository();
const checksRepository = new MongoChecksRepository(logger);
const geoChecksRepository = new MongoGeoChecksRepository(logger);
const monitorStatsRepository = new MongoMonitorStatsRepository();
const statusPagesRepository = new MongoStatusPagesRepository();
const usersRepository = new MongoUsersRepository();
const invitesRepository = new MongoInvitesRepository();
const recoveryTokensRepository = new MongoRecoveryTokensRepository();
const notificationsRepository = new MongoNotificationsRepository();
const incidentsRepository = new MongoIncidentRepository();
const teamsRepository = new MongoTeamsRepository();
const maintenanceWindowsRepository = new MongoMaintenanceWindowsRepository();
if (dbType === "mongodb") {
monitorsRepository = new MongoMonitorsRepository();
checksRepository = new MongoChecksRepository(logger);
geoChecksRepository = new MongoGeoChecksRepository(logger);
monitorStatsRepository = new MongoMonitorStatsRepository();
statusPagesRepository = new MongoStatusPagesRepository();
usersRepository = new MongoUsersRepository();
invitesRepository = new MongoInvitesRepository();
recoveryTokensRepository = new MongoRecoveryTokensRepository();
settingsRepository = new MongoSettingsRepository();
notificationsRepository = new MongoNotificationsRepository();
incidentsRepository = new MongoIncidentsRepository();
teamsRepository = new MongoTeamsRepository();
maintenanceWindowsRepository = new MongoMaintenanceWindowsRepository();
} else {
const pool = db.getPool();
if (!pool) {
throw new Error("Failed to get database pool");
}
monitorsRepository = new TimescaleMonitorsRepository(pool);
checksRepository = new TimescaleChecksRepository(pool);
geoChecksRepository = new TimescaleGeoChecksRepository(pool);
monitorStatsRepository = new TimescaleMonitorStatsRepository(pool);
statusPagesRepository = new TimescaleStatusPagesRepository(pool);
usersRepository = new TimescaleUsersRepository(pool);
invitesRepository = new TimescaleInvitesRepository(pool);
recoveryTokensRepository = new TimescaleRecoveryTokensRepository(pool);
settingsRepository = new TimescaleSettingsRepository(pool);
notificationsRepository = new TimescaleNotificationsRepository(pool);
incidentsRepository = new TimescaleIncidentsRepository(pool);
teamsRepository = new TimescaleTeamsRepository(pool);
maintenanceWindowsRepository = new TimescaleMaintenanceWindowsRepository(pool);
}
// Inject settings repository into settings service (now that DB is connected)
(settingsService as SettingsService).setRepository(settingsRepository);
// Network providers
const pingProvider = new PingProvider(ping);
+4 -10
View File
@@ -6,11 +6,9 @@ import { validateEnv } from "./validation/envValidation.js";
import { fileURLToPath } from "url";
import path from "path";
import fs from "fs";
import { runMigrations } from "./db/migration/index.js";
import Logger, { ILogger } from "@/utils/logger.js";
import { SettingsService } from "@/service/index.js";
import { MongoSettingsRepository } from "./repositories/index.js";
const SERVICE_NAME = "Server";
let logger: ILogger;
@@ -25,19 +23,15 @@ const startApp = async () => {
const openApiSpec = JSON.parse(fs.readFileSync(path.join(__dirname, "../openapi.json"), "utf8"));
const frontendPath = path.join(__dirname, "..", "public");
// Create services
const settingsRepository = new MongoSettingsRepository();
const settingsService = new SettingsService(settingsRepository, env);
// Create settings service (env only — DB repository injected after connect)
const settingsService = new SettingsService(env);
const envSettings = settingsService.loadSettings();
// Create logger
logger = new Logger({ envSettings });
// Initialize services
const services = await initializeServices({ logger, envSettings, settingsService, settingsRepository });
await runMigrations(logger);
// Initialize services (connects DB, creates repositories, injects settingsRepository)
const services = await initializeServices({ logger, envSettings, settingsService });
// Initialize controllers
const controllers = initializeControllers(services);
+23 -8
View File
@@ -25,10 +25,9 @@ export interface ISettingsService {
export class SettingsService implements ISettingsService {
static SERVICE_NAME = SERVICE_NAME;
private settings: EnvConfig;
private settingsRepository: ISettingsRepository;
private settingsRepository: ISettingsRepository | null = null;
constructor(settingsRepository: ISettingsRepository, env: ValidatedEnv) {
this.settingsRepository = settingsRepository;
constructor(env: ValidatedEnv) {
this.settings = {
jwtSecret: env.JWT_SECRET,
jwtTTL: env.TOKEN_TTL as StringValue,
@@ -39,6 +38,10 @@ export class SettingsService implements ISettingsService {
};
}
setRepository(settingsRepository: ISettingsRepository) {
this.settingsRepository = settingsRepository;
}
get serviceName() {
return SettingsService.SERVICE_NAME;
}
@@ -54,18 +57,30 @@ export class SettingsService implements ISettingsService {
return this.settings;
}
private getRepository(): ISettingsRepository {
if (!this.settingsRepository) {
throw new AppError({
message: "Settings repository not initialized. Call setRepository() after DB connect.",
status: 500,
service: SERVICE_NAME,
});
}
return this.settingsRepository;
}
updateDbSettings = async (newSettings: SettingsUpdate) => {
return await this.settingsRepository.update(newSettings);
return await this.getRepository().update(newSettings);
};
getDBSettings = async () => {
const repo = this.getRepository();
// Remove any old settings
await this.settingsRepository.deleteLegacy();
await repo.deleteLegacy();
let settings = await this.settingsRepository.findSingleton();
let settings = await repo.findSingleton();
if (settings === null) {
await this.settingsRepository.create({});
settings = await this.settingsRepository.findSingleton();
await repo.create({});
settings = await repo.findSingleton();
}
if (!settings) {