refactor: save settings service

This commit is contained in:
Ahmed Bouhuolia
2025-01-08 17:17:01 +02:00
parent ee284196eb
commit 6f870ea1e1
10 changed files with 118 additions and 21 deletions

View File

@@ -1,16 +1,20 @@
import { Controller, Get } from '@nestjs/common'; import { Body, Controller, Get, Post } from '@nestjs/common';
import { Inject } from '@nestjs/common'; import { SettingsApplicationService } from './SettingsApplication.service';
import { SETTINGS } from './Settings.module'; import { ISettingsDTO } from './Settings.types';
import { SettingsStore } from './SettingsStore'; import { PublicRoute } from '../Auth/Jwt.guard';
@Controller('settings') @Controller('settings')
@PublicRoute()
export class SettingsController { export class SettingsController {
constructor( constructor(
@Inject(SETTINGS) private readonly settingsStore: SettingsStore, private readonly settingsApplicationService: SettingsApplicationService,
) {} ) {}
@Get('') @Post('')
async getSettings() { async saveSettings(@Body() settingsDTO: ISettingsDTO) {
return this.settingsStore.all(); return this.settingsApplicationService.saveSettings(settingsDTO);
} }
@Get('')
async getSettings() {}
} }

View File

@@ -1,20 +1,25 @@
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { SettingRepository } from './repositories/Setting.repository'; import { SettingRepository } from './repositories/Setting.repository';
import { SettingsStore } from './SettingsStore'; import { SettingsStore } from './SettingsStore';
import { SettingsApplicationService } from './SettingsApplication.service';
export const SETTINGS = 'SETTINGS'; import { SaveSettingsService } from './commands/SaveSettings.service';
import { SettingsController } from './Settings.controller';
import { SETTINGS_PROVIDER } from './Settings.types';
@Module({ @Module({
providers: [ providers: [
SettingRepository, SettingRepository,
{ {
provide: SETTINGS, provide: SETTINGS_PROVIDER,
useFactory: (settingRepository: SettingRepository) => { useFactory: (settingRepository: SettingRepository) => {
return new SettingsStore(settingRepository); return new SettingsStore(settingRepository);
}, },
inject: [SettingRepository], inject: [SettingRepository],
}, },
SettingsApplicationService,
SaveSettingsService,
], ],
exports: [SETTINGS] controllers: [SettingsController],
exports: [SETTINGS_PROVIDER],
}) })
export class SettingsModule {} export class SettingsModule {}

View File

@@ -0,0 +1,13 @@
export interface IOptionDTO {
key: string;
value: string;
group: string;
}
export interface ISettingsDTO {
options: IOptionDTO[];
}
export const SETTINGS_PROVIDER = 'SETTINGS';

View File

@@ -0,0 +1,16 @@
import { Injectable } from '@nestjs/common';
import { SaveSettingsService } from './commands/SaveSettings.service';
import { ISettingsDTO } from './Settings.types';
@Injectable()
export class SettingsApplicationService {
constructor(private readonly saveSettingsService: SaveSettingsService) {}
/**
* Saves the given settings.
* @param {ISettingsDTO} settingsDTO
*/
public async saveSettings(settingsDTO: ISettingsDTO) {
return this.saveSettingsService.saveSettings(settingsDTO);
}
}

View File

@@ -1,6 +1,6 @@
import { EntityRepository } from '@/common/repository/EntityRepository'; import { EntityRepository } from '@/common/repository/EntityRepository';
import { MetableDBStore } from '../Metable/MetableStoreDB';
import { SettingsOptions } from '@/constants/metable-options'; import { SettingsOptions } from '@/constants/metable-options';
import { MetableDBStore } from '../Metable/MetableStoreDB';
export class SettingsStore extends MetableDBStore { export class SettingsStore extends MetableDBStore {
/** /**
@@ -13,4 +13,5 @@ export class SettingsStore extends MetableDBStore {
this.setExtraColumns(['group']); this.setExtraColumns(['group']);
this.setRepository(repository); this.setRepository(repository);
} }
} }

View File

@@ -0,0 +1,58 @@
import { Inject, Injectable } from '@nestjs/common';
import { pick } from 'lodash';
import { SettingsStore } from '../SettingsStore';
import { IOptionDTO, ISettingsDTO, SETTINGS_PROVIDER } from '../Settings.types';
@Injectable()
export class SaveSettingsService {
constructor(
@Inject(SETTINGS_PROVIDER)
private readonly settingsStore: SettingsStore,
) {}
/**
* Saves the given settings.
* @param {ISettingsDTO} settingsDTO
*/
public async saveSettings(settingsDTO: ISettingsDTO) {
const notDefinedOptions = this.validateNotDefinedSettings(
settingsDTO.options,
);
const errorReasons: { type: string; code: number; keys: any[] }[] = [];
if (notDefinedOptions.length) {
errorReasons.push({
type: 'OPTIONS.KEY.NOT.DEFINED',
code: 200,
keys: notDefinedOptions.map((o) => ({ ...pick(o, ['key', 'group']) })),
});
}
if (errorReasons.length) {
throw new Error(JSON.stringify(errorReasons));
}
settingsDTO.options.forEach((option: IOptionDTO) => {
this.settingsStore.set({ ...option });
});
await this.settingsStore.save();
}
/**
* Validates the given options is defined or either not.
* @param {Array} options
* @return {Boolean}
*/
private validateNotDefinedSettings(options) {
const notDefined = [];
options.forEach((option) => {
const setting = this.settingsStore.config.getMetaConfig(
option.key,
option.group,
);
if (!setting) {
notDefined.push(option);
}
});
return notDefined;
}
}

View File

@@ -6,12 +6,12 @@ import {
} from './types/TransactionsLocking.types'; } from './types/TransactionsLocking.types';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { SettingsStore } from '../Settings/SettingsStore'; import { SettingsStore } from '../Settings/SettingsStore';
import { SETTINGS } from '../Settings/Settings.module'; import { SETTINGS_PROVIDER } from '../Settings/Settings.types';
@Injectable() @Injectable()
export class TransactionsLockingRepository { export class TransactionsLockingRepository {
constructor( constructor(
@Inject(SETTINGS) private readonly settingsStore: SettingsStore, @Inject(SETTINGS_PROVIDER) private readonly settingsStore: SettingsStore,
) {} ) {}
/** /**

12
pnpm-lock.yaml generated
View File

@@ -286,8 +286,8 @@ importers:
specifier: ^8.0.0 specifier: ^8.0.0
version: 8.0.0 version: 8.0.0
posthog-node: posthog-node:
specifier: ^4.2.0 specifier: ^4.3.2
version: 4.2.0 version: 4.3.2
pug: pug:
specifier: ^3.0.2 specifier: ^3.0.2
version: 3.0.2 version: 3.0.2
@@ -623,8 +623,8 @@ importers:
specifier: ^10.3.0 specifier: ^10.3.0
version: 10.9.0 version: 10.9.0
posthog-node: posthog-node:
specifier: ^4.2.0 specifier: ^4.3.2
version: 4.2.0 version: 4.3.2
pug: pug:
specifier: ^3.0.2 specifier: ^3.0.2
version: 3.0.2 version: 3.0.2
@@ -28410,8 +28410,8 @@ packages:
picocolors: 1.1.1 picocolors: 1.1.1
source-map-js: 1.2.1 source-map-js: 1.2.1
/posthog-node@4.2.0: /posthog-node@4.3.2:
resolution: {integrity: sha512-hgyCYMyzMvuF3qWMw6JvS8gT55v7Mtp5wKWcnDrw+nu39D0Tk9BXD7I0LOBp0lGlHEPaXCEVYUtviNKrhMALGA==} resolution: {integrity: sha512-vy8Mt9IEfniUgqQ1rOCQ31CBO1VNqDGd3ZtHlWR9/YfU6RiuK+9pUXPb4h6HTGzQmjL8NFnjd8K8NMXSX8S6MQ==}
engines: {node: '>=15.0.0'} engines: {node: '>=15.0.0'}
dependencies: dependencies:
axios: 1.7.7 axios: 1.7.7