From 13fb7c4a6323c75c681ef43b8c04e440b3be6d76 Mon Sep 17 00:00:00 2001 From: Mateusz Kwasniewski Date: Mon, 6 Jan 2025 13:38:09 +0100 Subject: [PATCH] feat: making context service transactional (#9063) --- src/lib/features/context/context.ts | 46 ++++++++++++++++------------- src/lib/services/index.ts | 4 ++- src/lib/types/services.ts | 1 + 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/lib/features/context/context.ts b/src/lib/features/context/context.ts index ca21648ac2..46bfcf6e23 100644 --- a/src/lib/features/context/context.ts +++ b/src/lib/features/context/context.ts @@ -40,6 +40,7 @@ import type { UpdateContextFieldSchema } from '../../openapi/spec/update-context import type { CreateContextFieldSchema } from '../../openapi/spec/create-context-field-schema'; import { extractUserIdFromUser } from '../../util'; import type { LegalValueSchema } from '../../openapi'; +import type { WithTransactional } from '../../db/transaction'; interface ContextParam { contextField: string; @@ -50,7 +51,7 @@ interface DeleteLegalValueParam extends ContextParam { } export class ContextController extends Controller { - private contextService: ContextService; + private transactionalContextService: WithTransactional; private openApiService: OpenApiService; @@ -59,14 +60,17 @@ export class ContextController extends Controller { constructor( config: IUnleashConfig, { - contextService, + transactionalContextService, openApiService, - }: Pick, + }: Pick< + IUnleashServices, + 'transactionalContextService' | 'openApiService' + >, ) { super(config); this.openApiService = openApiService; this.logger = config.getLogger('/admin-api/context.ts'); - this.contextService = contextService; + this.transactionalContextService = transactionalContextService; this.route({ method: 'get', @@ -257,7 +261,9 @@ export class ContextController extends Controller { res: Response, ): Promise { res.status(200) - .json(serializeDates(await this.contextService.getAll())) + .json( + serializeDates(await this.transactionalContextService.getAll()), + ) .end(); } @@ -268,7 +274,7 @@ export class ContextController extends Controller { try { const name = req.params.contextField; const contextField = - await this.contextService.getContextField(name); + await this.transactionalContextService.getContextField(name); this.openApiService.respondWithValidation( 200, res, @@ -286,9 +292,8 @@ export class ContextController extends Controller { ): Promise { const value = req.body; - const result = await this.contextService.createContextField( - value, - req.audit, + const result = await this.transactionalContextService.transactional( + (service) => service.createContextField(value, req.audit), ); this.openApiService.respondWithValidation( @@ -307,9 +312,8 @@ export class ContextController extends Controller { const name = req.params.contextField; const contextField = req.body; - await this.contextService.updateContextField( - { ...contextField, name }, - req.audit, + await this.transactionalContextService.transactional((service) => + service.updateContextField({ ...contextField, name }, req.audit), ); res.status(200).end(); } @@ -321,9 +325,8 @@ export class ContextController extends Controller { const name = req.params.contextField; const legalValue = req.body; - await this.contextService.updateLegalValue( - { name, legalValue }, - req.audit, + await this.transactionalContextService.transactional((service) => + service.updateLegalValue({ name, legalValue }, req.audit), ); res.status(200).end(); } @@ -335,9 +338,8 @@ export class ContextController extends Controller { const name = req.params.contextField; const legalValue = req.params.legalValue; - await this.contextService.deleteLegalValue( - { name, legalValue }, - req.audit, + await this.transactionalContextService.transactional((service) => + service.deleteLegalValue({ name, legalValue }, req.audit), ); res.status(200).end(); } @@ -348,7 +350,9 @@ export class ContextController extends Controller { ): Promise { const name = req.params.contextField; - await this.contextService.deleteContextField(name, req.audit); + await this.transactionalContextService.transactional((service) => + service.deleteContextField(name, req.audit), + ); res.status(200).end(); } @@ -358,7 +362,7 @@ export class ContextController extends Controller { ): Promise { const { name } = req.body; - await this.contextService.validateName(name); + await this.transactionalContextService.validateName(name); res.status(200).end(); } @@ -369,7 +373,7 @@ export class ContextController extends Controller { const { contextField } = req.params; const { user } = req; const contextFields = - await this.contextService.getStrategiesByContextField( + await this.transactionalContextService.getStrategiesByContextField( contextField, extractUserIdFromUser(user), ); diff --git a/src/lib/services/index.ts b/src/lib/services/index.ts index f40705d247..3cdc3fe1ba 100644 --- a/src/lib/services/index.ts +++ b/src/lib/services/index.ts @@ -200,9 +200,10 @@ export const createServices = ( ? new FeatureLifecycleReadModel(db, config.flagResolver) : new FakeFeatureLifecycleReadModel(); - const contextService = db + const transactionalContextService = db ? withTransactional(createContextService(config), db) : withFakeTransactional(createFakeContextService(config)); + const contextService = transactionalContextService; const emailService = new EmailService(config); const featureTypeService = new FeatureTypeService( stores, @@ -434,6 +435,7 @@ export const createServices = ( clientInstanceService, clientMetricsServiceV2, contextService, + transactionalContextService, versionService, apiTokenService, emailService, diff --git a/src/lib/types/services.ts b/src/lib/types/services.ts index 711bd4abf6..5fa6d107c7 100644 --- a/src/lib/types/services.ts +++ b/src/lib/types/services.ts @@ -69,6 +69,7 @@ export interface IUnleashServices { clientInstanceService: ClientInstanceService; clientMetricsServiceV2: ClientMetricsServiceV2; contextService: ContextService; + transactionalContextService: WithTransactional; emailService: EmailService; environmentService: EnvironmentService; transactionalEnvironmentService: WithTransactional;