1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-06-09 01:17:06 +02:00

feat: making context service transactional (#9063)

This commit is contained in:
Mateusz Kwasniewski 2025-01-06 13:38:09 +01:00 committed by GitHub
parent 1c0431365e
commit 13fb7c4a63
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 29 additions and 22 deletions

View File

@ -40,6 +40,7 @@ import type { UpdateContextFieldSchema } from '../../openapi/spec/update-context
import type { CreateContextFieldSchema } from '../../openapi/spec/create-context-field-schema'; import type { CreateContextFieldSchema } from '../../openapi/spec/create-context-field-schema';
import { extractUserIdFromUser } from '../../util'; import { extractUserIdFromUser } from '../../util';
import type { LegalValueSchema } from '../../openapi'; import type { LegalValueSchema } from '../../openapi';
import type { WithTransactional } from '../../db/transaction';
interface ContextParam { interface ContextParam {
contextField: string; contextField: string;
@ -50,7 +51,7 @@ interface DeleteLegalValueParam extends ContextParam {
} }
export class ContextController extends Controller { export class ContextController extends Controller {
private contextService: ContextService; private transactionalContextService: WithTransactional<ContextService>;
private openApiService: OpenApiService; private openApiService: OpenApiService;
@ -59,14 +60,17 @@ export class ContextController extends Controller {
constructor( constructor(
config: IUnleashConfig, config: IUnleashConfig,
{ {
contextService, transactionalContextService,
openApiService, openApiService,
}: Pick<IUnleashServices, 'contextService' | 'openApiService'>, }: Pick<
IUnleashServices,
'transactionalContextService' | 'openApiService'
>,
) { ) {
super(config); super(config);
this.openApiService = openApiService; this.openApiService = openApiService;
this.logger = config.getLogger('/admin-api/context.ts'); this.logger = config.getLogger('/admin-api/context.ts');
this.contextService = contextService; this.transactionalContextService = transactionalContextService;
this.route({ this.route({
method: 'get', method: 'get',
@ -257,7 +261,9 @@ export class ContextController extends Controller {
res: Response<ContextFieldsSchema>, res: Response<ContextFieldsSchema>,
): Promise<void> { ): Promise<void> {
res.status(200) res.status(200)
.json(serializeDates(await this.contextService.getAll())) .json(
serializeDates(await this.transactionalContextService.getAll()),
)
.end(); .end();
} }
@ -268,7 +274,7 @@ export class ContextController extends Controller {
try { try {
const name = req.params.contextField; const name = req.params.contextField;
const contextField = const contextField =
await this.contextService.getContextField(name); await this.transactionalContextService.getContextField(name);
this.openApiService.respondWithValidation( this.openApiService.respondWithValidation(
200, 200,
res, res,
@ -286,9 +292,8 @@ export class ContextController extends Controller {
): Promise<void> { ): Promise<void> {
const value = req.body; const value = req.body;
const result = await this.contextService.createContextField( const result = await this.transactionalContextService.transactional(
value, (service) => service.createContextField(value, req.audit),
req.audit,
); );
this.openApiService.respondWithValidation( this.openApiService.respondWithValidation(
@ -307,9 +312,8 @@ export class ContextController extends Controller {
const name = req.params.contextField; const name = req.params.contextField;
const contextField = req.body; const contextField = req.body;
await this.contextService.updateContextField( await this.transactionalContextService.transactional((service) =>
{ ...contextField, name }, service.updateContextField({ ...contextField, name }, req.audit),
req.audit,
); );
res.status(200).end(); res.status(200).end();
} }
@ -321,9 +325,8 @@ export class ContextController extends Controller {
const name = req.params.contextField; const name = req.params.contextField;
const legalValue = req.body; const legalValue = req.body;
await this.contextService.updateLegalValue( await this.transactionalContextService.transactional((service) =>
{ name, legalValue }, service.updateLegalValue({ name, legalValue }, req.audit),
req.audit,
); );
res.status(200).end(); res.status(200).end();
} }
@ -335,9 +338,8 @@ export class ContextController extends Controller {
const name = req.params.contextField; const name = req.params.contextField;
const legalValue = req.params.legalValue; const legalValue = req.params.legalValue;
await this.contextService.deleteLegalValue( await this.transactionalContextService.transactional((service) =>
{ name, legalValue }, service.deleteLegalValue({ name, legalValue }, req.audit),
req.audit,
); );
res.status(200).end(); res.status(200).end();
} }
@ -348,7 +350,9 @@ export class ContextController extends Controller {
): Promise<void> { ): Promise<void> {
const name = req.params.contextField; 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(); res.status(200).end();
} }
@ -358,7 +362,7 @@ export class ContextController extends Controller {
): Promise<void> { ): Promise<void> {
const { name } = req.body; const { name } = req.body;
await this.contextService.validateName(name); await this.transactionalContextService.validateName(name);
res.status(200).end(); res.status(200).end();
} }
@ -369,7 +373,7 @@ export class ContextController extends Controller {
const { contextField } = req.params; const { contextField } = req.params;
const { user } = req; const { user } = req;
const contextFields = const contextFields =
await this.contextService.getStrategiesByContextField( await this.transactionalContextService.getStrategiesByContextField(
contextField, contextField,
extractUserIdFromUser(user), extractUserIdFromUser(user),
); );

View File

@ -200,9 +200,10 @@ export const createServices = (
? new FeatureLifecycleReadModel(db, config.flagResolver) ? new FeatureLifecycleReadModel(db, config.flagResolver)
: new FakeFeatureLifecycleReadModel(); : new FakeFeatureLifecycleReadModel();
const contextService = db const transactionalContextService = db
? withTransactional(createContextService(config), db) ? withTransactional(createContextService(config), db)
: withFakeTransactional(createFakeContextService(config)); : withFakeTransactional(createFakeContextService(config));
const contextService = transactionalContextService;
const emailService = new EmailService(config); const emailService = new EmailService(config);
const featureTypeService = new FeatureTypeService( const featureTypeService = new FeatureTypeService(
stores, stores,
@ -434,6 +435,7 @@ export const createServices = (
clientInstanceService, clientInstanceService,
clientMetricsServiceV2, clientMetricsServiceV2,
contextService, contextService,
transactionalContextService,
versionService, versionService,
apiTokenService, apiTokenService,
emailService, emailService,

View File

@ -69,6 +69,7 @@ export interface IUnleashServices {
clientInstanceService: ClientInstanceService; clientInstanceService: ClientInstanceService;
clientMetricsServiceV2: ClientMetricsServiceV2; clientMetricsServiceV2: ClientMetricsServiceV2;
contextService: ContextService; contextService: ContextService;
transactionalContextService: WithTransactional<ContextService>;
emailService: EmailService; emailService: EmailService;
environmentService: EnvironmentService; environmentService: EnvironmentService;
transactionalEnvironmentService: WithTransactional<EnvironmentService>; transactionalEnvironmentService: WithTransactional<EnvironmentService>;