setting service

This commit is contained in:
Alex Holliday committed 2026-01-17 18:29:42 +00:00
1 parent e498bd60b1
commit 048e53ea15
8 files changed
+169 -84

No files matched your search

-84
View File
@@ -1,84 +0,0 @@
import mongoose from "mongoose";
const AppSettingsSchema = mongoose.Schema(
{
checkTTL: {
type: Number,
default: 30,
},
language: {
type: String,
default: "gb",
},
pagespeedApiKey: {
type: String,
},
systemEmailHost: {
type: String,
},
systemEmailPort: {
type: Number,
},
systemEmailAddress: {
type: String,
},
systemEmailPassword: {
type: String,
},
systemEmailUser: {
type: String,
},
systemEmailConnectionHost: {
type: String,
default: "localhost",
},
systemEmailTLSServername: {
type: String,
},
systemEmailSecure: {
type: Boolean,
default: false,
},
systemEmailPool: {
type: Boolean,
default: false,
},
systemEmailIgnoreTLS: {
type: Boolean,
default: false,
},
systemEmailRequireTLS: {
type: Boolean,
default: false,
},
systemEmailRejectUnauthorized: {
type: Boolean,
default: true,
},
showURL: {
type: Boolean,
default: false,
},
singleton: {
type: Boolean,
required: true,
unique: true,
default: true,
},
version: {
type: Number,
default: 1,
},
globalThresholds: {
cpu: { type: Number },
memory: { type: Number },
disk: { type: Number },
temperature: { type: Number },
},
},
{
timestamps: true,
}
);
export default mongoose.model("AppSettings", AppSettingsSchema);
+49
View File
@@ -0,0 +1,49 @@
import { Schema, model, type Types } from "mongoose";
import type { Settings, SettingsThresholds } from "@/types/settings.js";
interface AppSettingsDocument extends Omit<Settings, "id" | "createdAt" | "updatedAt"> {
_id: Types.ObjectId;
createdAt: Date;
updatedAt: Date;
}
const thresholdsSchema = new Schema<SettingsThresholds>(
{
cpu: { type: Number },
memory: { type: Number },
disk: { type: Number },
temperature: { type: Number },
},
{ _id: false }
);
const AppSettingsSchema = new Schema<AppSettingsDocument>(
{
checkTTL: { type: Number, default: 30 },
language: { type: String, default: "gb" },
pagespeedApiKey: { type: String },
systemEmailHost: { type: String },
systemEmailPort: { type: Number },
systemEmailAddress: { type: String },
systemEmailPassword: { type: String },
systemEmailUser: { type: String },
systemEmailConnectionHost: { type: String, default: "localhost" },
systemEmailTLSServername: { type: String },
systemEmailSecure: { type: Boolean, default: false },
systemEmailPool: { type: Boolean, default: false },
systemEmailIgnoreTLS: { type: Boolean, default: false },
systemEmailRequireTLS: { type: Boolean, default: false },
systemEmailRejectUnauthorized: { type: Boolean, default: true },
showURL: { type: Boolean, default: false },
singleton: { type: Boolean, required: true, unique: true, default: true },
version: { type: Number, default: 1 },
globalThresholds: { type: thresholdsSchema },
},
{ timestamps: true }
);
const AppSettingsModel = model<AppSettingsDocument>("AppSettings", AppSettingsSchema);
export type { AppSettingsDocument };
export { AppSettingsModel };
export default AppSettingsModel;
+3
View File
@@ -16,5 +16,8 @@ export { default as UserModel } from "@/db/models/User.js";
export * from "@/db/models/Invite.js";
export { default as InviteModel } from "@/db/models/Invite.js";
export * from "@/db/models/AppSettings.js";
export { default as AppSettingsModel } from "@/db/models/AppSettings.js";
export * from "@/db/models/RecoveryToken.js";
export { default as RecoveryTokenModel } from "@/db/models/RecoveryToken.js";
+3
View File
@@ -18,3 +18,6 @@ export { default as MongoInvitesRepository } from "@/repositories/invites/MongoI
export * from "@/repositories/recovery-tokens/IRecoveryTokensRepository.js";
export { default as MongoRecoveryTokensRepository } from "@/repositories/recovery-tokens/MongoRecoveryTokensRepository.js";
export * from "@/repositories/settings/ISettingsRepository.js";
export { default as MongoSettingsRepository } from "@/repositories/settings/MongoSettingsRepository.js";
@@ -0,0 +1,8 @@
import type { Settings } from "@/types/index.js";
export interface ISettingsRepository {
// create
// fetch
// update
update(settings: Partial<Settings>): Promise<Settings>;
// delete
}
@@ -0,0 +1,74 @@
import mongoose from "mongoose";
import { ISettingsRepository } from "@/repositories/settings/ISettingsRepository.js";
import type { Settings } from "@/types/index.js";
import { AppSettingsModel, type AppSettingsDocument } from "@/db/models/AppSettings.js";
import { AppError } from "@/utils/AppError.js";
class MongoSettingsRepository implements ISettingsRepository {
private toStringId = (value?: mongoose.Types.ObjectId | string | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
private toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};
protected toEntity = (doc: AppSettingsDocument): Settings => {
return {
id: this.toStringId(doc._id),
checkTTL: doc.checkTTL,
language: doc.language,
pagespeedApiKey: doc.pagespeedApiKey ?? undefined,
systemEmailHost: doc.systemEmailHost ?? undefined,
systemEmailPort: doc.systemEmailPort ?? undefined,
systemEmailAddress: doc.systemEmailAddress ?? undefined,
systemEmailPassword: doc.systemEmailPassword ?? undefined,
systemEmailUser: doc.systemEmailUser ?? undefined,
systemEmailConnectionHost: doc.systemEmailConnectionHost ?? undefined,
systemEmailTLSServername: doc.systemEmailTLSServername ?? undefined,
systemEmailSecure: doc.systemEmailSecure ?? false,
systemEmailPool: doc.systemEmailPool ?? false,
systemEmailIgnoreTLS: doc.systemEmailIgnoreTLS ?? false,
systemEmailRequireTLS: doc.systemEmailRequireTLS ?? false,
systemEmailRejectUnauthorized: doc.systemEmailRejectUnauthorized ?? true,
showURL: doc.showURL ?? false,
singleton: doc.singleton,
version: doc.version ?? 1,
globalThresholds: doc.globalThresholds ?? undefined,
createdAt: this.toDateString(doc.createdAt),
updatedAt: this.toDateString(doc.updatedAt),
};
};
update = async (settings: Partial<Settings>) => {
const update: Record<string, any> = { $set: { ...settings } };
if (settings.pagespeedApiKey === "") {
update.$unset = { pagespeedApiKey: "" };
delete update.$set.pagespeedApiKey;
}
if (settings.systemEmailPassword === "") {
update.$unset = { systemEmailPassword: "" };
delete update.$set.systemEmailPassword;
}
await AppSettingsModel.findOneAndUpdate({}, update, {
upsert: true,
});
const currentSettings = await AppSettingsModel.findOne().select("-__v -_id -createdAt -updatedAt -singleton").lean();
if (!currentSettings) {
throw new AppError({ message: "Settings not found after update", status: 500 });
}
return this.toEntity(currentSettings);
};
}
export default MongoSettingsRepository;
+1
View File
@@ -6,3 +6,4 @@ export * from "@/types/network.js";
export * from "@/types/user.js";
export * from "@/types/invite.js";
export * from "@/types/recoveryToken.js";
export * from "@/types/settings.js";
+31
View File
@@ -0,0 +1,31 @@
export interface SettingsThresholds {
cpu?: number;
memory?: number;
disk?: number;
temperature?: number;
}
export interface Settings {
id: string;
checkTTL: number;
language: string;
pagespeedApiKey?: string;
systemEmailHost?: string;
systemEmailPort?: number;
systemEmailAddress?: string;
systemEmailPassword?: string;
systemEmailUser?: string;
systemEmailConnectionHost?: string;
systemEmailTLSServername?: string;
systemEmailSecure: boolean;
systemEmailPool: boolean;
systemEmailIgnoreTLS: boolean;
systemEmailRequireTLS: boolean;
systemEmailRejectUnauthorized: boolean;
showURL: boolean;
singleton: boolean;
version: number;
globalThresholds?: SettingsThresholds;
createdAt: string;
updatedAt: string;
}