mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-26 13:48:33 +02:00
feat: make all feature toggle service write methods transactional (#9973)
This commit is contained in:
parent
2a083edc14
commit
410142cb42
@ -16,10 +16,7 @@ import {
|
||||
emptyResponse,
|
||||
getStandardResponses,
|
||||
} from '../../openapi/util/standard-responses';
|
||||
import type {
|
||||
TransactionCreator,
|
||||
UnleashTransaction,
|
||||
} from '../../db/transaction';
|
||||
import type { WithTransactional } from '../../db/transaction';
|
||||
import {
|
||||
archivedFeaturesSchema,
|
||||
type ArchivedFeaturesSchema,
|
||||
@ -27,10 +24,7 @@ import {
|
||||
|
||||
export default class ArchiveController extends Controller {
|
||||
private featureService: FeatureToggleService;
|
||||
private transactionalFeatureToggleService: (
|
||||
db: UnleashTransaction,
|
||||
) => FeatureToggleService;
|
||||
private readonly startTransaction: TransactionCreator<UnleashTransaction>;
|
||||
private transactionalFeatureToggleService: WithTransactional<FeatureToggleService>;
|
||||
private openApiService: OpenApiService;
|
||||
|
||||
constructor(
|
||||
@ -45,14 +39,12 @@ export default class ArchiveController extends Controller {
|
||||
| 'featureToggleService'
|
||||
| 'openApiService'
|
||||
>,
|
||||
startTransaction: TransactionCreator<UnleashTransaction>,
|
||||
) {
|
||||
super(config);
|
||||
this.featureService = featureToggleService;
|
||||
this.openApiService = openApiService;
|
||||
this.transactionalFeatureToggleService =
|
||||
transactionalFeatureToggleService;
|
||||
this.startTransaction = startTransaction;
|
||||
|
||||
this.route({
|
||||
method: 'get',
|
||||
@ -204,11 +196,8 @@ export default class ArchiveController extends Controller {
|
||||
): Promise<void> {
|
||||
const { featureName } = req.params;
|
||||
|
||||
await this.startTransaction(async (tx) =>
|
||||
this.transactionalFeatureToggleService(tx).reviveFeature(
|
||||
featureName,
|
||||
req.audit,
|
||||
),
|
||||
await this.transactionalFeatureToggleService.transactional((service) =>
|
||||
service.reviveFeature(featureName, req.audit),
|
||||
);
|
||||
res.status(200).end();
|
||||
}
|
||||
|
@ -48,10 +48,7 @@ import type {
|
||||
} from '../../services';
|
||||
import { querySchema } from '../../schema/feature-schema';
|
||||
import type { BatchStaleSchema } from '../../openapi/spec/batch-stale-schema';
|
||||
import type {
|
||||
TransactionCreator,
|
||||
UnleashTransaction,
|
||||
} from '../../db/transaction';
|
||||
import type { WithTransactional } from '../../db/transaction';
|
||||
import { BadDataError } from '../../error';
|
||||
import { anonymise } from '../../util';
|
||||
import { throwOnInvalidSchema } from '../../openapi/validate';
|
||||
@ -116,9 +113,7 @@ export default class ProjectFeaturesController extends Controller {
|
||||
|
||||
private featureTagService: FeatureTagService;
|
||||
|
||||
private transactionalFeatureToggleService: (
|
||||
db: UnleashTransaction,
|
||||
) => FeatureToggleService;
|
||||
private transactionalFeatureToggleService: WithTransactional<FeatureToggleService>;
|
||||
|
||||
private openApiService: OpenApiService;
|
||||
|
||||
@ -126,8 +121,6 @@ export default class ProjectFeaturesController extends Controller {
|
||||
|
||||
private readonly logger: Logger;
|
||||
|
||||
private readonly startTransaction: TransactionCreator<UnleashTransaction>;
|
||||
|
||||
constructor(
|
||||
config: IUnleashConfig,
|
||||
{
|
||||
@ -136,13 +129,11 @@ export default class ProjectFeaturesController extends Controller {
|
||||
transactionalFeatureToggleService,
|
||||
featureTagService,
|
||||
}: ProjectFeaturesServices,
|
||||
startTransaction: TransactionCreator<UnleashTransaction>,
|
||||
) {
|
||||
super(config);
|
||||
this.featureService = featureToggleService;
|
||||
this.transactionalFeatureToggleService =
|
||||
transactionalFeatureToggleService;
|
||||
this.startTransaction = startTransaction;
|
||||
this.openApiService = openApiService;
|
||||
this.featureTagService = featureTagService;
|
||||
this.flagResolver = config.flagResolver;
|
||||
@ -658,13 +649,17 @@ export default class ProjectFeaturesController extends Controller {
|
||||
): Promise<void> {
|
||||
const { projectId, featureName } = req.params;
|
||||
const { name, replaceGroupId } = req.body;
|
||||
const created = await this.featureService.cloneFeatureToggle(
|
||||
featureName,
|
||||
projectId,
|
||||
name,
|
||||
req.audit,
|
||||
replaceGroupId,
|
||||
);
|
||||
const created =
|
||||
await this.transactionalFeatureToggleService.transactional(
|
||||
(service) =>
|
||||
service.cloneFeatureToggle(
|
||||
featureName,
|
||||
projectId,
|
||||
name,
|
||||
req.audit,
|
||||
replaceGroupId,
|
||||
),
|
||||
);
|
||||
|
||||
this.openApiService.respondWithValidation(
|
||||
201,
|
||||
@ -680,14 +675,18 @@ export default class ProjectFeaturesController extends Controller {
|
||||
): Promise<void> {
|
||||
const { projectId } = req.params;
|
||||
|
||||
const created = await this.featureService.createFeatureToggle(
|
||||
projectId,
|
||||
{
|
||||
...req.body,
|
||||
description: req.body.description || undefined,
|
||||
},
|
||||
req.audit,
|
||||
);
|
||||
const created =
|
||||
await this.transactionalFeatureToggleService.transactional(
|
||||
(service) =>
|
||||
service.createFeatureToggle(
|
||||
projectId,
|
||||
{
|
||||
...req.body,
|
||||
description: req.body.description || undefined,
|
||||
},
|
||||
req.audit,
|
||||
),
|
||||
);
|
||||
|
||||
this.openApiService.respondWithValidation(
|
||||
201,
|
||||
@ -762,15 +761,19 @@ export default class ProjectFeaturesController extends Controller {
|
||||
if (data.name && data.name !== featureName) {
|
||||
throw new BadDataError('Cannot change name of feature flag');
|
||||
}
|
||||
const created = await this.featureService.updateFeatureToggle(
|
||||
projectId,
|
||||
{
|
||||
...data,
|
||||
name: featureName,
|
||||
},
|
||||
featureName,
|
||||
req.audit,
|
||||
);
|
||||
const created =
|
||||
await this.transactionalFeatureToggleService.transactional(
|
||||
(service) =>
|
||||
service.updateFeatureToggle(
|
||||
projectId,
|
||||
{
|
||||
...data,
|
||||
name: featureName,
|
||||
},
|
||||
featureName,
|
||||
req.audit,
|
||||
),
|
||||
);
|
||||
|
||||
this.openApiService.respondWithValidation(
|
||||
200,
|
||||
@ -790,12 +793,16 @@ export default class ProjectFeaturesController extends Controller {
|
||||
res: Response<FeatureSchema>,
|
||||
): Promise<void> {
|
||||
const { projectId, featureName } = req.params;
|
||||
const updated = await this.featureService.patchFeature(
|
||||
projectId,
|
||||
featureName,
|
||||
req.body,
|
||||
req.audit,
|
||||
);
|
||||
const updated =
|
||||
await this.transactionalFeatureToggleService.transactional(
|
||||
(service) =>
|
||||
service.patchFeature(
|
||||
projectId,
|
||||
featureName,
|
||||
req.body,
|
||||
req.audit,
|
||||
),
|
||||
);
|
||||
this.openApiService.respondWithValidation(
|
||||
200,
|
||||
res,
|
||||
@ -814,13 +821,8 @@ export default class ProjectFeaturesController extends Controller {
|
||||
res: Response<void>,
|
||||
): Promise<void> {
|
||||
const { featureName, projectId } = req.params;
|
||||
await this.startTransaction(async (tx) =>
|
||||
this.transactionalFeatureToggleService(tx).archiveToggle(
|
||||
featureName,
|
||||
req.user,
|
||||
req.audit,
|
||||
projectId,
|
||||
),
|
||||
await this.transactionalFeatureToggleService.transactional((service) =>
|
||||
service.archiveToggle(featureName, req.user, req.audit, projectId),
|
||||
);
|
||||
res.status(202).send();
|
||||
}
|
||||
@ -887,14 +889,16 @@ export default class ProjectFeaturesController extends Controller {
|
||||
): Promise<void> {
|
||||
const { featureName, environment, projectId } = req.params;
|
||||
const { shouldActivateDisabledStrategies } = req.query;
|
||||
await this.featureService.updateEnabled(
|
||||
projectId,
|
||||
featureName,
|
||||
environment,
|
||||
true,
|
||||
req.audit,
|
||||
req.user,
|
||||
shouldActivateDisabledStrategies === 'true',
|
||||
await this.transactionalFeatureToggleService.transactional((service) =>
|
||||
service.updateEnabled(
|
||||
projectId,
|
||||
featureName,
|
||||
environment,
|
||||
true,
|
||||
req.audit,
|
||||
req.user,
|
||||
shouldActivateDisabledStrategies === 'true',
|
||||
),
|
||||
);
|
||||
res.status(200).end();
|
||||
}
|
||||
@ -917,8 +921,8 @@ export default class ProjectFeaturesController extends Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.startTransaction(async (tx) =>
|
||||
this.transactionalFeatureToggleService(tx).bulkUpdateEnabled(
|
||||
await this.transactionalFeatureToggleService.transactional((service) =>
|
||||
service.bulkUpdateEnabled(
|
||||
projectId,
|
||||
features,
|
||||
environment,
|
||||
@ -949,8 +953,8 @@ export default class ProjectFeaturesController extends Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.startTransaction(async (tx) =>
|
||||
this.transactionalFeatureToggleService(tx).bulkUpdateEnabled(
|
||||
await this.transactionalFeatureToggleService.transactional((service) =>
|
||||
service.bulkUpdateEnabled(
|
||||
projectId,
|
||||
features,
|
||||
environment,
|
||||
@ -968,13 +972,15 @@ export default class ProjectFeaturesController extends Controller {
|
||||
res: Response<void>,
|
||||
): Promise<void> {
|
||||
const { featureName, environment, projectId } = req.params;
|
||||
await this.featureService.updateEnabled(
|
||||
projectId,
|
||||
featureName,
|
||||
environment,
|
||||
false,
|
||||
req.audit,
|
||||
req.user,
|
||||
await this.transactionalFeatureToggleService.transactional((service) =>
|
||||
service.updateEnabled(
|
||||
projectId,
|
||||
featureName,
|
||||
environment,
|
||||
false,
|
||||
req.audit,
|
||||
req.user,
|
||||
),
|
||||
);
|
||||
res.status(200).end();
|
||||
}
|
||||
@ -994,12 +1000,16 @@ export default class ProjectFeaturesController extends Controller {
|
||||
strategyConfig.segmentIds = [];
|
||||
}
|
||||
|
||||
const strategy = await this.featureService.createStrategy(
|
||||
strategyConfig,
|
||||
{ environment, projectId, featureName },
|
||||
req.audit,
|
||||
req.user,
|
||||
);
|
||||
const strategy =
|
||||
await this.transactionalFeatureToggleService.transactional(
|
||||
(service) =>
|
||||
service.createStrategy(
|
||||
strategyConfig,
|
||||
{ environment, projectId, featureName },
|
||||
req.audit,
|
||||
req.user,
|
||||
),
|
||||
);
|
||||
|
||||
const updatedStrategy = await this.featureService.getStrategy(
|
||||
strategy.id,
|
||||
@ -1031,10 +1041,8 @@ export default class ProjectFeaturesController extends Controller {
|
||||
res: Response,
|
||||
): Promise<void> {
|
||||
const { featureName, projectId, environment } = req.params;
|
||||
await this.startTransaction(async (tx) =>
|
||||
this.transactionalFeatureToggleService(
|
||||
tx,
|
||||
).updateStrategiesSortOrder(
|
||||
await this.transactionalFeatureToggleService.transactional((service) =>
|
||||
service.updateStrategiesSortOrder(
|
||||
{
|
||||
featureName,
|
||||
environment,
|
||||
@ -1058,15 +1066,17 @@ export default class ProjectFeaturesController extends Controller {
|
||||
req.body.segmentIds = [];
|
||||
}
|
||||
|
||||
const updatedStrategy = await this.startTransaction(async (tx) =>
|
||||
this.transactionalFeatureToggleService(tx).updateStrategy(
|
||||
strategyId,
|
||||
req.body,
|
||||
{ environment, projectId, featureName },
|
||||
req.audit,
|
||||
req.user,
|
||||
),
|
||||
);
|
||||
const updatedStrategy =
|
||||
await this.transactionalFeatureToggleService.transactional(
|
||||
(service) =>
|
||||
service.updateStrategy(
|
||||
strategyId,
|
||||
req.body,
|
||||
{ environment, projectId, featureName },
|
||||
req.audit,
|
||||
req.user,
|
||||
),
|
||||
);
|
||||
|
||||
res.status(200).json(updatedStrategy);
|
||||
}
|
||||
@ -1083,15 +1093,17 @@ export default class ProjectFeaturesController extends Controller {
|
||||
|
||||
throwOnInvalidSchema(featureStrategySchema.$id, newDocument);
|
||||
|
||||
const updatedStrategy = await this.startTransaction(async (tx) =>
|
||||
this.transactionalFeatureToggleService(tx).updateStrategy(
|
||||
strategyId,
|
||||
newDocument,
|
||||
{ environment, projectId, featureName },
|
||||
req.audit,
|
||||
req.user,
|
||||
),
|
||||
);
|
||||
const updatedStrategy =
|
||||
await this.transactionalFeatureToggleService.transactional(
|
||||
(service) =>
|
||||
service.updateStrategy(
|
||||
strategyId,
|
||||
newDocument,
|
||||
{ environment, projectId, featureName },
|
||||
req.audit,
|
||||
req.user,
|
||||
),
|
||||
);
|
||||
|
||||
res.status(200).json(updatedStrategy);
|
||||
}
|
||||
@ -1115,36 +1127,17 @@ export default class ProjectFeaturesController extends Controller {
|
||||
const { environment, projectId, featureName } = req.params;
|
||||
const { strategyId } = req.params;
|
||||
this.logger.info(strategyId);
|
||||
const strategy = await this.featureService.deleteStrategy(
|
||||
strategyId,
|
||||
{ environment, projectId, featureName },
|
||||
req.audit,
|
||||
req.user,
|
||||
);
|
||||
res.status(200).json(strategy);
|
||||
}
|
||||
|
||||
async updateStrategyParameter(
|
||||
req: IAuthRequest<
|
||||
StrategyIdParams,
|
||||
any,
|
||||
{ name: string; value: string | number },
|
||||
any
|
||||
>,
|
||||
res: Response<FeatureStrategySchema>,
|
||||
): Promise<void> {
|
||||
const { strategyId, environment, projectId, featureName } = req.params;
|
||||
const { name, value } = req.body;
|
||||
|
||||
const updatedStrategy =
|
||||
await this.featureService.updateStrategyParameter(
|
||||
strategyId,
|
||||
name,
|
||||
value,
|
||||
{ environment, projectId, featureName },
|
||||
req.audit,
|
||||
const strategy =
|
||||
await this.transactionalFeatureToggleService.transactional(
|
||||
(service) =>
|
||||
service.deleteStrategy(
|
||||
strategyId,
|
||||
{ environment, projectId, featureName },
|
||||
req.audit,
|
||||
req.user,
|
||||
),
|
||||
);
|
||||
res.status(200).json(updatedStrategy);
|
||||
res.status(200).json(strategy);
|
||||
}
|
||||
|
||||
async updateFeaturesTags(
|
||||
|
@ -31,7 +31,6 @@ import type { OpenApiService } from '../../services';
|
||||
import type { IAuthRequest } from '../../routes/unleash-types';
|
||||
import { ProjectApiTokenController } from '../../routes/admin-api/project/api-token';
|
||||
import ProjectArchiveController from '../../routes/admin-api/project/project-archive';
|
||||
import { createKnexTransactionStarter } from '../../db/transaction';
|
||||
import type { Db } from '../../db/db';
|
||||
import DependentFeaturesController from '../dependent-features/dependent-features-controller';
|
||||
import type { ProjectOverviewSchema } from '../../openapi/spec/project-overview-schema';
|
||||
@ -222,14 +221,7 @@ export default class ProjectController extends Controller {
|
||||
],
|
||||
});
|
||||
|
||||
this.use(
|
||||
'/',
|
||||
new ProjectFeaturesController(
|
||||
config,
|
||||
services,
|
||||
createKnexTransactionStarter(db),
|
||||
).router,
|
||||
);
|
||||
this.use('/', new ProjectFeaturesController(config, services).router);
|
||||
this.use('/', new DependentFeaturesController(config, services).router);
|
||||
this.use(
|
||||
'/',
|
||||
@ -238,14 +230,7 @@ export default class ProjectController extends Controller {
|
||||
this.use('/', new ProjectHealthReport(config, services).router);
|
||||
this.use('/', new VariantsController(config, services).router);
|
||||
this.use('/', new ProjectApiTokenController(config, services).router);
|
||||
this.use(
|
||||
'/',
|
||||
new ProjectArchiveController(
|
||||
config,
|
||||
services,
|
||||
createKnexTransactionStarter(db),
|
||||
).router,
|
||||
);
|
||||
this.use('/', new ProjectArchiveController(config, services).router);
|
||||
this.use('/', new ProjectInsightsController(config, services).router);
|
||||
this.use('/', new ProjectStatusController(config, services).router);
|
||||
this.use('/', new FeatureLifecycleController(config, services).router);
|
||||
|
@ -28,7 +28,6 @@ import InstanceAdminController from './instance-admin';
|
||||
import TelemetryController from './telemetry';
|
||||
import FavoritesController from './favorites';
|
||||
import MaintenanceController from '../../features/maintenance/maintenance-controller';
|
||||
import { createKnexTransactionStarter } from '../../db/transaction';
|
||||
import type { Db } from '../../db/db';
|
||||
import ExportImportController from '../../features/export-import-toggles/export-import-controller';
|
||||
import { SegmentsController } from '../../features/segment/segment-controller';
|
||||
@ -53,11 +52,7 @@ export class AdminApi extends Controller {
|
||||
);
|
||||
this.app.use(
|
||||
'/archive',
|
||||
new ArchiveController(
|
||||
config,
|
||||
services,
|
||||
createKnexTransactionStarter(db),
|
||||
).router,
|
||||
new ArchiveController(config, services).router,
|
||||
);
|
||||
this.app.use(
|
||||
'/strategies',
|
||||
|
@ -21,10 +21,7 @@ import {
|
||||
createResponseSchema,
|
||||
} from '../../../openapi';
|
||||
import Controller from '../../controller';
|
||||
import type {
|
||||
TransactionCreator,
|
||||
UnleashTransaction,
|
||||
} from '../../../db/transaction';
|
||||
import type { WithTransactional } from '../../../db/transaction';
|
||||
|
||||
const PATH = '/:projectId';
|
||||
const PATH_ARCHIVE = `${PATH}/archive`;
|
||||
@ -37,10 +34,7 @@ export default class ProjectArchiveController extends Controller {
|
||||
|
||||
private featureService: FeatureToggleService;
|
||||
|
||||
private transactionalFeatureToggleService: (
|
||||
db: UnleashTransaction,
|
||||
) => FeatureToggleService;
|
||||
private readonly startTransaction: TransactionCreator<UnleashTransaction>;
|
||||
private transactionalFeatureToggleService: WithTransactional<FeatureToggleService>;
|
||||
|
||||
private openApiService: OpenApiService;
|
||||
|
||||
@ -58,7 +52,6 @@ export default class ProjectArchiveController extends Controller {
|
||||
| 'featureToggleService'
|
||||
| 'openApiService'
|
||||
>,
|
||||
startTransaction: TransactionCreator<UnleashTransaction>,
|
||||
) {
|
||||
super(config);
|
||||
this.logger = config.getLogger('/admin-api/archive.js');
|
||||
@ -67,7 +60,6 @@ export default class ProjectArchiveController extends Controller {
|
||||
this.flagResolver = config.flagResolver;
|
||||
this.transactionalFeatureToggleService =
|
||||
transactionalFeatureToggleService;
|
||||
this.startTransaction = startTransaction;
|
||||
|
||||
this.route({
|
||||
method: 'post',
|
||||
@ -178,12 +170,8 @@ export default class ProjectArchiveController extends Controller {
|
||||
): Promise<void> {
|
||||
const { projectId } = req.params;
|
||||
const { features } = req.body;
|
||||
await this.startTransaction(async (tx) =>
|
||||
this.transactionalFeatureToggleService(tx).reviveFeatures(
|
||||
features,
|
||||
projectId,
|
||||
req.audit,
|
||||
),
|
||||
await this.transactionalFeatureToggleService.transactional((service) =>
|
||||
service.reviveFeatures(features, projectId, req.audit),
|
||||
);
|
||||
res.status(200).end();
|
||||
}
|
||||
@ -195,13 +183,8 @@ export default class ProjectArchiveController extends Controller {
|
||||
const { features } = req.body;
|
||||
const { projectId } = req.params;
|
||||
|
||||
await this.startTransaction(async (tx) =>
|
||||
this.transactionalFeatureToggleService(tx).archiveToggles(
|
||||
features,
|
||||
req.user,
|
||||
req.audit,
|
||||
projectId,
|
||||
),
|
||||
await this.transactionalFeatureToggleService.transactional((service) =>
|
||||
service.archiveToggles(features, req.user, req.audit, projectId),
|
||||
);
|
||||
|
||||
res.status(202).end();
|
||||
|
@ -69,6 +69,7 @@ import {
|
||||
createFakeAccessService,
|
||||
createFakeEnvironmentService,
|
||||
createFakeEventsService,
|
||||
createFakeFeatureToggleService,
|
||||
createFakeProjectService,
|
||||
createFakeUserSubscriptionsService,
|
||||
createFeatureLifecycleService,
|
||||
@ -133,8 +134,6 @@ import {
|
||||
createFakeApiTokenService,
|
||||
} from '../features/api-tokens/createApiTokenService';
|
||||
import { IntegrationEventsService } from '../features/integration-events/integration-events-service';
|
||||
import { FeatureCollaboratorsReadModel } from '../features/feature-toggle/feature-collaborators-read-model';
|
||||
import { FakeFeatureCollaboratorsReadModel } from '../features/feature-toggle/fake-feature-collaborators-read-model';
|
||||
import {
|
||||
createFakePlaygroundService,
|
||||
createPlaygroundService,
|
||||
@ -160,8 +159,6 @@ import {
|
||||
} from '../features/context/createContextService';
|
||||
import { UniqueConnectionService } from '../features/unique-connection/unique-connection-service';
|
||||
import { createFakeFeatureLinkService } from '../features/feature-links/createFeatureLinkService';
|
||||
import { FeatureLinksReadModel } from '../features/feature-links/feature-links-read-model';
|
||||
import { FakeFeatureLinksReadModel } from '../features/feature-links/fake-feature-links-read-model';
|
||||
import { UnknownFlagsService } from '../features/metrics/unknown-flags/unknown-flags-service';
|
||||
|
||||
export const createServices = (
|
||||
@ -287,26 +284,6 @@ export const createServices = (
|
||||
? createFeatureSearchService(config)(db)
|
||||
: createFakeFeatureSearchService(config);
|
||||
|
||||
const featureCollaboratorsReadModel = db
|
||||
? new FeatureCollaboratorsReadModel(db)
|
||||
: new FakeFeatureCollaboratorsReadModel();
|
||||
|
||||
const featureLinksReadModel = db
|
||||
? new FeatureLinksReadModel(db, config.eventBus)
|
||||
: new FakeFeatureLinksReadModel();
|
||||
|
||||
const featureToggleService = new FeatureToggleService(stores, config, {
|
||||
segmentService,
|
||||
accessService,
|
||||
eventService,
|
||||
changeRequestAccessReadModel,
|
||||
privateProjectChecker,
|
||||
dependentFeaturesReadModel,
|
||||
dependentFeaturesService,
|
||||
featureLifecycleReadModel,
|
||||
featureCollaboratorsReadModel,
|
||||
featureLinksReadModel,
|
||||
});
|
||||
const transactionalEnvironmentService = db
|
||||
? withTransactional(createEnvironmentService(config), db)
|
||||
: withFakeTransactional(createFakeEnvironmentService(config));
|
||||
@ -346,8 +323,12 @@ export const createServices = (
|
||||
const importService = db
|
||||
? withTransactional(deferredExportImportTogglesService(config), db)
|
||||
: withFakeTransactional(createFakeExportImportTogglesService(config));
|
||||
const transactionalFeatureToggleService = (txDb: Knex.Transaction) =>
|
||||
createFeatureToggleService(txDb, config);
|
||||
const featureToggleService = db
|
||||
? withTransactional((db) => createFeatureToggleService(db, config), db)
|
||||
: withFakeTransactional(
|
||||
createFakeFeatureToggleService(config).featureToggleService,
|
||||
);
|
||||
const transactionalFeatureToggleService = featureToggleService;
|
||||
const transactionalGroupService = (txDb: Knex.Transaction) =>
|
||||
createGroupService(txDb, config);
|
||||
const userSplashService = new UserSplashService(stores, config);
|
||||
|
@ -114,9 +114,7 @@ export interface IUnleashServices {
|
||||
configurationRevisionService: ConfigurationRevisionService;
|
||||
schedulerService: SchedulerService;
|
||||
eventAnnouncerService: EventAnnouncerService;
|
||||
transactionalFeatureToggleService: (
|
||||
db: Knex.Transaction,
|
||||
) => FeatureToggleService;
|
||||
transactionalFeatureToggleService: WithTransactional<FeatureToggleService>;
|
||||
transactionalGroupService: (db: Knex.Transaction) => GroupService;
|
||||
privateProjectChecker: IPrivateProjectChecker;
|
||||
dependentFeaturesService: DependentFeaturesService;
|
||||
|
@ -35,7 +35,11 @@ test('should not allow to create feature flags in maintenance mode', async () =>
|
||||
});
|
||||
|
||||
test('maintenance mode is off by default', async () => {
|
||||
const appWithMaintenanceMode = await setupApp(db.stores);
|
||||
const appWithMaintenanceMode = await setupAppWithCustomConfig(
|
||||
db.stores,
|
||||
{},
|
||||
db.rawDatabase,
|
||||
);
|
||||
|
||||
return appWithMaintenanceMode.request
|
||||
.post('/api/admin/projects/default/features')
|
||||
|
@ -11,14 +11,18 @@ let db: ITestDb;
|
||||
|
||||
beforeAll(async () => {
|
||||
db = await dbInit('project_feature_variants_api_sunset', getLogger);
|
||||
app = await setupAppWithCustomConfig(db.stores, {
|
||||
experimental: {
|
||||
flags: {
|
||||
strictSchemaValidation: true,
|
||||
enableLegacyVariants: false,
|
||||
app = await setupAppWithCustomConfig(
|
||||
db.stores,
|
||||
{
|
||||
experimental: {
|
||||
flags: {
|
||||
strictSchemaValidation: true,
|
||||
enableLegacyVariants: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
db.rawDatabase,
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
|
@ -12,14 +12,18 @@ let db: ITestDb;
|
||||
|
||||
beforeAll(async () => {
|
||||
db = await dbInit('project_feature_variants_api_serial', getLogger);
|
||||
app = await setupAppWithCustomConfig(db.stores, {
|
||||
experimental: {
|
||||
flags: {
|
||||
strictSchemaValidation: true,
|
||||
enableLegacyVariants: true,
|
||||
app = await setupAppWithCustomConfig(
|
||||
db.stores,
|
||||
{
|
||||
experimental: {
|
||||
flags: {
|
||||
strictSchemaValidation: true,
|
||||
enableLegacyVariants: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
db.rawDatabase,
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
|
@ -19,7 +19,7 @@ beforeAll(async () => {
|
||||
getLogger.setMuteError(true);
|
||||
db = await dbInit('user_pat', getLogger);
|
||||
patStore = db.stores.patStore;
|
||||
app = await setupAppWithAuth(db.stores);
|
||||
app = await setupAppWithAuth(db.stores, {}, db.rawDatabase);
|
||||
|
||||
await app.request
|
||||
.post(`/auth/demo/login`)
|
||||
|
Loading…
Reference in New Issue
Block a user