1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-25 00:07:47 +01:00

refactor: Context service feature oriented (#9052)

This commit is contained in:
Mateusz Kwasniewski 2025-01-03 10:23:47 +01:00 committed by GitHub
parent 9003a7eb91
commit eb0b7d5e4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 131 additions and 100 deletions

View File

@ -6,7 +6,7 @@ import FeatureTypeStore from './feature-type-store';
import StrategyStore from './strategy-store';
import ClientInstanceStore from './client-instance-store';
import ClientApplicationsStore from './client-applications-store';
import ContextFieldStore from './context-field-store';
import ContextFieldStore from '../features/context/context-field-store';
import SettingStore from './setting-store';
import UserStore from './user-store';
import ProjectStore from '../features/project/project-store';

View File

@ -1,4 +1,4 @@
import type { Store } from './store';
import type { Store } from '../../types/stores/store';
export interface IContextFieldDto {
name: string;

View File

@ -1,13 +1,13 @@
import type { Db } from './db';
import type { Logger, LogProvider } from '../logger';
import type { Db } from '../../db/db';
import type { Logger, LogProvider } from '../../logger';
import type {
IContextField,
IContextFieldDto,
IContextFieldStore,
ILegalValue,
} from '../types/stores/context-field-store';
import NotFoundError from '../error/notfound-error';
import type { IFlagResolver } from '../types';
} from './context-field-store-type';
import NotFoundError from '../../error/notfound-error';
import type { IFlagResolver } from '../../types';
const COLUMNS = [
'name',

View File

@ -1,13 +1,15 @@
import type { Logger } from '../logger';
import type { Logger } from '../../logger';
import type {
IContextField,
IContextFieldDto,
IContextFieldStore,
} from '../types/stores/context-field-store';
import type { IProjectStore } from '../features/project/project-store-type';
import type { IFeatureStrategiesStore, IUnleashStores } from '../types/stores';
import type { IUnleashConfig } from '../types/option';
import type { ContextFieldStrategiesSchema } from '../openapi/spec/context-field-strategies-schema';
} from './context-field-store-type';
import type {
IFeatureStrategiesStore,
IUnleashStores,
} from '../../types/stores';
import type { IUnleashConfig } from '../../types/option';
import type { ContextFieldStrategiesSchema } from '../../openapi/spec/context-field-strategies-schema';
import {
CONTEXT_FIELD_CREATED,
CONTEXT_FIELD_DELETED,
@ -15,16 +17,14 @@ import {
type IAuditUser,
type IFeatureStrategy,
type IFlagResolver,
} from '../types';
import type { IPrivateProjectChecker } from '../features/private-project/privateProjectCheckerType';
import type EventService from '../features/events/event-service';
import { contextSchema } from './context-schema';
import { NameExistsError } from '../error';
import { nameSchema } from '../schema/feature-schema';
} from '../../types';
import type { IPrivateProjectChecker } from '../private-project/privateProjectCheckerType';
import type EventService from '../events/event-service';
import { contextSchema } from '../../services/context-schema';
import { NameExistsError } from '../../error';
import { nameSchema } from '../../schema/feature-schema';
class ContextService {
private projectStore: IProjectStore;
private eventService: EventService;
private contextFieldStore: IContextFieldStore;
@ -39,13 +39,9 @@ class ContextService {
constructor(
{
projectStore,
contextFieldStore,
featureStrategiesStore,
}: Pick<
IUnleashStores,
'projectStore' | 'contextFieldStore' | 'featureStrategiesStore'
>,
}: Pick<IUnleashStores, 'contextFieldStore' | 'featureStrategiesStore'>,
{
getLogger,
flagResolver,
@ -54,7 +50,6 @@ class ContextService {
privateProjectChecker: IPrivateProjectChecker,
) {
this.privateProjectChecker = privateProjectChecker;
this.projectStore = projectStore;
this.eventService = eventService;
this.flagResolver = flagResolver;
this.contextFieldStore = contextFieldStore;

View File

@ -1,6 +1,6 @@
import type { Request, Response } from 'express';
import Controller from '../controller';
import Controller from '../../routes/controller';
import {
CREATE_CONTEXT_FIELD,
@ -10,9 +10,9 @@ import {
} from '../../types/permissions';
import type { IUnleashConfig } from '../../types/option';
import type { IUnleashServices } from '../../types/services';
import type ContextService from '../../services/context-service';
import type ContextService from './context-service';
import type { Logger } from '../../logger';
import type { IAuthRequest } from '../unleash-types';
import type { IAuthRequest } from '../../routes/unleash-types';
import type { OpenApiService } from '../../services/openapi-service';
import {

View File

@ -0,0 +1,65 @@
import type { Db } from '../../db/db';
import type { IUnleashConfig } from '../../types';
import ContextService from './context-service';
import ContextFieldStore from './context-field-store';
import FeatureStrategiesStore from '../feature-toggle/feature-toggle-strategies-store';
import {
createEventsService,
createFakeEventsService,
} from '../events/createEventsService';
import { PrivateProjectChecker } from '../private-project/privateProjectChecker';
import PrivateProjectStore from '../private-project/privateProjectStore';
import FakeContextFieldStore from './fake-context-field-store';
import FakeFeatureStrategiesStore from '../feature-toggle/fakes/fake-feature-strategies-store';
import { FakePrivateProjectChecker } from '../private-project/fakePrivateProjectChecker';
export const createContextService =
(config: IUnleashConfig) =>
(db: Db): ContextService => {
const { getLogger, flagResolver, eventBus, isEnterprise } = config;
const contextFieldStore = new ContextFieldStore(
db,
getLogger,
flagResolver,
);
const featureStrategiesStore = new FeatureStrategiesStore(
db,
eventBus,
getLogger,
flagResolver,
);
const eventService = createEventsService(db, config);
const privateProjectStore = new PrivateProjectStore(db, getLogger);
const privateProjectChecker = new PrivateProjectChecker(
{ privateProjectStore },
{ isEnterprise },
);
return new ContextService(
{ contextFieldStore, featureStrategiesStore },
{
getLogger,
flagResolver,
},
eventService,
privateProjectChecker,
);
};
export const createFakeContextService = (
config: IUnleashConfig,
): ContextService => {
const { getLogger, flagResolver, eventBus, isEnterprise } = config;
const contextFieldStore = new FakeContextFieldStore();
const featureStrategiesStore = new FakeFeatureStrategiesStore();
const eventService = createFakeEventsService(config);
const privateProjectChecker = new FakePrivateProjectChecker();
return new ContextService(
{ contextFieldStore, featureStrategiesStore },
{
getLogger,
flagResolver,
},
eventService,
privateProjectChecker,
);
};

View File

@ -2,8 +2,8 @@ import type {
IContextField,
IContextFieldDto,
IContextFieldStore,
} from '../../lib/types/stores/context-field-store';
import NotFoundError from '../../lib/error/notfound-error';
} from './context-field-store-type';
import NotFoundError from '../../error/notfound-error';
export default class FakeContextFieldStore implements IContextFieldStore {
count(): Promise<number> {

View File

@ -5,13 +5,11 @@ import { ImportTogglesStore } from './import-toggles-store';
import FeatureToggleStore from '../feature-toggle/feature-toggle-store';
import TagStore from '../../db/tag-store';
import TagTypeStore from '../tag-type/tag-type-store';
import ProjectStore from '../project/project-store';
import FeatureTagStore from '../../db/feature-tag-store';
import StrategyStore from '../../db/strategy-store';
import ContextFieldStore from '../../db/context-field-store';
import ContextFieldStore from '../context/context-field-store';
import FeatureStrategiesStore from '../feature-toggle/feature-toggle-strategies-store';
import {
ContextService,
FeatureTagService,
StrategyService,
TagTypeService,
@ -28,17 +26,12 @@ import { FeatureEnvironmentStore } from '../../db/feature-environment-store';
import FakeFeatureToggleStore from '../feature-toggle/fakes/fake-feature-toggle-store';
import FakeTagStore from '../../../test/fixtures/fake-tag-store';
import FakeTagTypeStore from '../tag-type/fake-tag-type-store';
import FakeProjectStore from '../../../test/fixtures/fake-project-store';
import FakeFeatureTagStore from '../../../test/fixtures/fake-feature-tag-store';
import FakeContextFieldStore from '../../../test/fixtures/fake-context-field-store';
import FakeContextFieldStore from '../context/fake-context-field-store';
import FakeFeatureStrategiesStore from '../feature-toggle/fakes/fake-feature-strategies-store';
import FakeFeatureEnvironmentStore from '../../../test/fixtures/fake-feature-environment-store';
import FakeStrategiesStore from '../../../test/fixtures/fake-strategies-store';
import EventStore from '../events/event-store';
import {
createFakePrivateProjectChecker,
createPrivateProjectChecker,
} from '../private-project/createPrivateProjectChecker';
import { createPrivateProjectChecker } from '../private-project/createPrivateProjectChecker';
import type { DeferredServiceFactory } from '../../db/transaction';
import { DependentFeaturesReadModel } from '../dependent-features/dependent-features-read-model';
import { FakeDependentFeaturesReadModel } from '../dependent-features/fake-dependent-features-read-model';
@ -52,16 +45,19 @@ import {
} from '../events/createEventsService';
import { SegmentReadModel } from '../segment/segment-read-model';
import { FakeSegmentReadModel } from '../segment/fake-segment-read-model';
import {
createContextService,
createFakeContextService,
} from '../context/createContextService';
export const createFakeExportImportTogglesService = (
config: IUnleashConfig,
): ExportImportService => {
const { getLogger, flagResolver } = config;
const { getLogger } = config;
const importTogglesStore = {} as ImportTogglesStore;
const featureToggleStore = new FakeFeatureToggleStore();
const tagStore = new FakeTagStore();
const tagTypeStore = new FakeTagTypeStore();
const projectStore = new FakeProjectStore();
const featureTagStore = new FakeFeatureTagStore();
const strategyStore = new FakeStrategiesStore();
const contextFieldStore = new FakeContextFieldStore();
@ -69,7 +65,6 @@ export const createFakeExportImportTogglesService = (
const featureEnvironmentStore = new FakeFeatureEnvironmentStore();
const { accessService } = createFakeAccessService(config);
const { featureToggleService } = createFakeFeatureToggleService(config);
const privateProjectChecker = createFakePrivateProjectChecker();
const eventService = createFakeEventsService(config);
@ -82,16 +77,7 @@ export const createFakeExportImportTogglesService = (
{ getLogger },
eventService,
);
const contextService = new ContextService(
{
projectStore,
contextFieldStore,
featureStrategiesStore,
},
{ getLogger, flagResolver },
eventService,
privateProjectChecker,
);
const contextService = createFakeContextService(config);
const strategyService = new StrategyService(
{ strategyStore },
{ getLogger },
@ -108,7 +94,7 @@ export const createFakeExportImportTogglesService = (
const dependentFeaturesService = createFakeDependentFeaturesService(config);
const exportImportService = new ExportImportService(
return new ExportImportService(
{
importTogglesStore,
featureStrategiesStore,
@ -132,8 +118,6 @@ export const createFakeExportImportTogglesService = (
dependentFeaturesReadModel,
segmentReadModel,
);
return exportImportService;
};
export const deferredExportImportTogglesService = (
@ -150,7 +134,6 @@ export const deferredExportImportTogglesService = (
);
const tagStore = new TagStore(db, eventBus, getLogger);
const tagTypeStore = new TagTypeStore(db, eventBus, getLogger);
const projectStore = new ProjectStore(db, eventBus, config);
const featureTagStore = new FeatureTagStore(db, eventBus, getLogger);
const strategyStore = new StrategyStore(db, getLogger);
const contextFieldStore = new ContextFieldStore(
@ -169,11 +152,9 @@ export const deferredExportImportTogglesService = (
eventBus,
config,
);
const eventStore = new EventStore(db, getLogger);
const accessService = createAccessService(db, config);
const featureToggleService = createFeatureToggleService(db, config);
const privateProjectChecker = createPrivateProjectChecker(db, config);
createPrivateProjectChecker(db, config);
const eventService = createEventsService(db, config);
const featureTagService = new FeatureTagService(
@ -185,16 +166,7 @@ export const deferredExportImportTogglesService = (
{ getLogger },
eventService,
);
const contextService = new ContextService(
{
projectStore,
contextFieldStore,
featureStrategiesStore,
},
{ getLogger, flagResolver },
eventService,
privateProjectChecker,
);
const contextService = createContextService(config)(db);
const strategyService = new StrategyService(
{ strategyStore },
{ getLogger },
@ -212,7 +184,7 @@ export const deferredExportImportTogglesService = (
const dependentFeaturesService =
createDependentFeaturesService(config)(db);
const exportImportService = new ExportImportService(
return new ExportImportService(
{
importTogglesStore,
featureStrategiesStore,
@ -236,8 +208,6 @@ export const deferredExportImportTogglesService = (
dependentFeaturesReadModel,
segmentReadModel,
);
return exportImportService;
};
};
export const createExportImportTogglesService = (

View File

@ -15,7 +15,7 @@ import {
RoleName,
} from '../../types';
import type { ImportTogglesSchema, VariantsSchema } from '../../openapi';
import type { IContextFieldDto } from '../../types/stores/context-field-store';
import type { IContextFieldDto } from '../context/context-field-store-type';
import type { AccessService } from '../../services';
import { DEFAULT_ENV } from '../../util';
import type { IRole } from '../../types/stores/access-store';

View File

@ -25,7 +25,7 @@ import type {
UpsertSegmentSchema,
VariantsSchema,
} from '../../openapi';
import type { IContextFieldDto } from '../../types/stores/context-field-store';
import type { IContextFieldDto } from '../context/context-field-store-type';
let app: IUnleashTest;
let db: ITestDb;

View File

@ -1,4 +1,4 @@
import type { IContextFieldDto } from '../../types/stores/context-field-store';
import type { IContextFieldDto } from '../context/context-field-store-type';
export const isValidField = (
importedField: IContextFieldDto,

View File

@ -2,7 +2,7 @@ import type {
FeatureStrategySchema,
ImportTogglesValidateItemSchema,
} from '../../openapi';
import type { IContextFieldDto } from '../../types/stores/context-field-store';
import type { IContextFieldDto } from '../context/context-field-store-type';
import type { FeatureNameCheckResultWithFeaturePattern } from '../feature-toggle/feature-toggle-service';
import type { ProjectFeaturesLimit } from './import-toggles-store-type';

View File

@ -8,7 +8,7 @@ import FeatureToggleStore from './feature-toggle-store';
import FeatureToggleClientStore from '../client-feature-toggles/client-feature-toggle-store';
import ProjectStore from '../project/project-store';
import { FeatureEnvironmentStore } from '../../db/feature-environment-store';
import ContextFieldStore from '../../db/context-field-store';
import ContextFieldStore from '../context/context-field-store';
import GroupStore from '../../db/group-store';
import { AccountStore } from '../../db/account-store';
import { AccessStore } from '../../db/access-store';
@ -22,7 +22,7 @@ import FakeFeatureToggleStore from './fakes/fake-feature-toggle-store';
import FakeClientFeatureToggleStore from '../client-feature-toggles/fakes/fake-client-feature-toggle-store';
import FakeProjectStore from '../../../test/fixtures/fake-project-store';
import FakeFeatureEnvironmentStore from '../../../test/fixtures/fake-feature-environment-store';
import FakeContextFieldStore from '../../../test/fixtures/fake-context-field-store';
import FakeContextFieldStore from '../context/fake-context-field-store';
import FakeGroupStore from '../../../test/fixtures/fake-group-store';
import { FakeAccountStore } from '../../../test/fixtures/fake-account-store';
import FakeAccessStore from '../../../test/fixtures/fake-access-store';

View File

@ -86,7 +86,7 @@ import {
validateSemver,
validateString,
} from '../../util/validators/constraint-types';
import type { IContextFieldStore } from '../../types/stores/context-field-store';
import type { IContextFieldStore } from '../context/context-field-store-type';
import type { SetStrategySortOrderSchema } from '../../openapi/spec/set-strategy-sort-order-schema';
import {
getDefaultStrategy,

View File

@ -14,7 +14,7 @@ import UserStore from '../../db/user-store';
import ProjectStore from '../project/project-store';
import EnvironmentStore from '../project-environments/environment-store';
import StrategyStore from '../../db/strategy-store';
import ContextFieldStore from '../../db/context-field-store';
import ContextFieldStore from '../context/context-field-store';
import GroupStore from '../../db/group-store';
import SegmentStore from '../segment/segment-store';
import RoleStore from '../../db/role-store';
@ -30,7 +30,7 @@ import FakeFeatureToggleStore from '../feature-toggle/fakes/fake-feature-toggle-
import FakeProjectStore from '../../../test/fixtures/fake-project-store';
import FakeEnvironmentStore from '../project-environments/fake-environment-store';
import FakeGroupStore from '../../../test/fixtures/fake-group-store';
import FakeContextFieldStore from '../../../test/fixtures/fake-context-field-store';
import FakeContextFieldStore from '../context/fake-context-field-store';
import FakeRoleStore from '../../../test/fixtures/fake-role-store';
import FakeClientInstanceStore from '../../../test/fixtures/fake-client-instance-store';
import FakeClientMetricsStoreV2 from '../metrics/client-metrics/fake-client-metrics-store-v2';

View File

@ -10,7 +10,7 @@ import type {
ITrafficDataUsageStore,
IUnleashStores,
} from '../../types/stores';
import type { IContextFieldStore } from '../../types/stores/context-field-store';
import type { IContextFieldStore } from '../context/context-field-store-type';
import type { IEnvironmentStore } from '../project-environments/environment-store-type';
import type { IFeatureToggleStore } from '../feature-toggle/types/feature-toggle-store-type';
import type { IGroupStore } from '../../types/stores/group-store';

View File

@ -9,7 +9,7 @@ import PlaygroundController from '../../features/playground/playground';
import MetricsController from './metrics';
import UserController from './user/user';
import ConfigController from './config';
import { ContextController } from './context';
import { ContextController } from '../../features/context/context';
import ClientMetricsController from '../../features/metrics/client-metrics/client-metrics';
import TagController from './tag';
import TagTypeController from '../../features/tag-type/tag-type';

View File

@ -14,7 +14,7 @@ import TagTypeService from '../features/tag-type/tag-type-service';
import TagService from './tag-service';
import StrategyService from './strategy-service';
import AddonService from './addon-service';
import ContextService from './context-service';
import ContextService from '../features/context/context-service';
import VersionService from './version-service';
import { EmailService } from './email-service';
import { AccessService } from './access-service';
@ -153,6 +153,10 @@ import {
createProjectStatusService,
} from '../features/project-status/createProjectStatusService';
import { ProjectStatusService } from '../features/project-status/project-status-service';
import {
createContextService,
createFakeContextService,
} from '../features/context/createContextService';
export const createServices = (
stores: IUnleashStores,
@ -196,12 +200,9 @@ export const createServices = (
? new FeatureLifecycleReadModel(db, config.flagResolver)
: new FakeFeatureLifecycleReadModel();
const contextService = new ContextService(
stores,
config,
eventService,
privateProjectChecker,
);
const contextService = db
? withTransactional(createContextService(config), db)
: withFakeTransactional(createFakeContextService(config));
const emailService = new EmailService(config);
const featureTypeService = new FeatureTypeService(
stores,

View File

@ -5,7 +5,7 @@ import type StrategyService from '../services/strategy-service';
import type TagTypeService from '../features/tag-type/tag-type-service';
import type TagService from '../services/tag-service';
import type ClientInstanceService from '../features/metrics/instance/instance-service';
import type ContextService from '../services/context-service';
import type ContextService from '../features/context/context-service';
import type VersionService from '../services/version-service';
import type { ApiTokenService } from '../services/api-token-service';
import type { EmailService } from '../services/email-service';

View File

@ -5,7 +5,7 @@ import { IStrategyStore } from './stores/strategy-store';
import { IClientApplicationsStore } from './stores/client-applications-store';
import { IClientInstanceStore } from './stores/client-instance-store';
import { IFeatureToggleStore } from '../features/feature-toggle/types/feature-toggle-store-type';
import { IContextFieldStore } from './stores/context-field-store';
import { IContextFieldStore } from '../features/context/context-field-store-type';
import { ISettingStore } from './stores/settings-store';
import { ISessionStore } from './stores/session-store';
import { ITagStore } from './stores/tag-store';

View File

@ -1,5 +1,5 @@
import { validateSemver, validateLegalValues } from './constraint-types';
import type { ILegalValue } from '../../types/stores/context-field-store';
import type { ILegalValue } from '../../features/context/context-field-store-type';
const legalValues: Readonly<ILegalValue[]> = [
{ value: '100' },

View File

@ -4,7 +4,7 @@ import {
constraintStringTypeSchema,
} from '../../schema/constraint-value-types';
import BadDataError from '../../error/bad-data-error';
import type { ILegalValue } from '../../types/stores/context-field-store';
import type { ILegalValue } from '../../features/context/context-field-store-type';
import { parseStrictSemVer } from '../semver';
export const validateNumber = async (value: unknown): Promise<void> => {

View File

@ -12,7 +12,7 @@ import {
} from '../../../lib/types';
import type { IUnleashServices } from '../../../lib/types/services';
import type { Db } from '../../../lib/db/db';
import type { IContextFieldDto } from '../../../lib/types/stores/context-field-store';
import type { IContextFieldDto } from '../../../lib/features/context/context-field-store-type';
import { DEFAULT_ENV } from '../../../lib/util';
import type {
CreateDependentFeatureSchema,

View File

@ -1,6 +1,6 @@
import dbInit, { type ITestDb } from '../helpers/database-init';
import getLogger from '../../fixtures/no-logger';
import type { IContextFieldDto } from '../../../lib/types/stores/context-field-store';
import type { IContextFieldDto } from '../../../lib/features/context/context-field-store-type';
import fc, { type Arbitrary } from 'fast-check';
import type { IUnleashStores } from '../../../lib/types';

View File

@ -5,7 +5,7 @@ import FakeFeatureToggleStore from '../../lib/features/feature-toggle/fakes/fake
import FakeTagStore from './fake-tag-store';
import FakeTagTypeStore from '../../lib/features/tag-type/fake-tag-type-store';
import FakeEventStore from './fake-event-store';
import FakeContextFieldStore from './fake-context-field-store';
import FakeContextFieldStore from '../../lib/features/context/fake-context-field-store';
import FakeSettingStore from './fake-setting-store';
import FakeAddonStore from './fake-addon-store';
import FakeProjectStore from './fake-project-store';