diff --git a/src/lib/db/segment-store.ts b/src/lib/db/segment-store.ts index f2017b05be2f..6e19a5acb414 100644 --- a/src/lib/db/segment-store.ts +++ b/src/lib/db/segment-store.ts @@ -1,10 +1,5 @@ import { ISegmentStore } from '../types/stores/segment-store'; -import { - IClientSegment, - IConstraint, - IFeatureStrategySegment, - ISegment, -} from '../types/model'; +import { IConstraint, IFeatureStrategySegment, ISegment } from '../types/model'; import { Logger, LogProvider } from '../logger'; import EventEmitter from 'events'; import NotFoundError from '../error/notfound-error'; @@ -284,30 +279,6 @@ export default class SegmentStore implements ISegmentStore { ); } - async getActive(): Promise { - const rows: ISegmentRow[] = await this.db - .distinct(this.prefixColumns()) - .from(T.segments) - .orderBy('name', 'asc') - .join( - T.featureStrategySegment, - `${T.featureStrategySegment}.segment_id`, - `${T.segments}.id`, - ); - - return rows.map(this.mapRow); - } - - async getActiveForClient(): Promise { - const fullSegments = await this.getActive(); - - return fullSegments.map((segments) => ({ - id: segments.id, - name: segments.name, - constraints: segments.constraints, - })); - } - async getByStrategy(strategyId: string): Promise { const rows = await this.db .select(this.prefixColumns()) diff --git a/src/lib/features/client-feature-toggles/client-feature-toggle-service.ts b/src/lib/features/client-feature-toggles/client-feature-toggle-service.ts index 4c3ec239febe..262105084af5 100644 --- a/src/lib/features/client-feature-toggles/client-feature-toggle-service.ts +++ b/src/lib/features/client-feature-toggles/client-feature-toggle-service.ts @@ -1,6 +1,7 @@ import { IFeatureToggleClientStore, IFeatureToggleQuery, + ISegmentReadModel, IUnleashConfig, IUnleashStores, } from '../../types'; @@ -14,16 +15,24 @@ export class ClientFeatureToggleService { private clientFeatureToggleStore: IFeatureToggleClientStore; + private segmentReadModel: ISegmentReadModel; + constructor( { clientFeatureToggleStore, }: Pick, + segmentReadModel: ISegmentReadModel, { getLogger }: Pick, ) { this.logger = getLogger('services/client-feature-toggle-service.ts'); + this.segmentReadModel = segmentReadModel; this.clientFeatureToggleStore = clientFeatureToggleStore; } + async getActiveSegmentsForClient() { + return this.segmentReadModel.getActiveForClient(); + } + async getClientFeatures( query?: IFeatureToggleQuery, ): Promise { diff --git a/src/lib/features/client-feature-toggles/client-feature-toggle.controller.ts b/src/lib/features/client-feature-toggles/client-feature-toggle.controller.ts index 2b5219e2d761..16ee3b6d8d2a 100644 --- a/src/lib/features/client-feature-toggles/client-feature-toggle.controller.ts +++ b/src/lib/features/client-feature-toggles/client-feature-toggle.controller.ts @@ -31,7 +31,6 @@ import { clientFeaturesSchema, ClientFeaturesSchema, } from '../../openapi/spec/client-features-schema'; -import { ISegmentService } from '../../segments/segment-service-interface'; import ConfigurationRevisionService from '../feature-toggle/configuration-revision-service'; import { ClientFeatureToggleService } from './client-feature-toggle-service'; @@ -53,8 +52,6 @@ export default class FeatureController extends Controller { private clientFeatureToggleService: ClientFeatureToggleService; - private segmentService: ISegmentService; - private clientSpecService: ClientSpecService; private openApiService: OpenApiService; @@ -73,7 +70,6 @@ export default class FeatureController extends Controller { constructor( { clientFeatureToggleService, - segmentService, clientSpecService, openApiService, configurationRevisionService, @@ -81,7 +77,6 @@ export default class FeatureController extends Controller { }: Pick< IUnleashServices, | 'clientFeatureToggleService' - | 'segmentService' | 'clientSpecService' | 'openApiService' | 'configurationRevisionService' @@ -92,7 +87,6 @@ export default class FeatureController extends Controller { super(config); const { clientFeatureCaching } = config; this.clientFeatureToggleService = clientFeatureToggleService; - this.segmentService = segmentService; this.clientSpecService = clientSpecService; this.openApiService = openApiService; this.configurationRevisionService = configurationRevisionService; @@ -162,7 +156,7 @@ export default class FeatureController extends Controller { ): Promise<[FeatureConfigurationClient[], IClientSegment[]]> { return Promise.all([ this.clientFeatureToggleService.getClientFeatures(query), - this.segmentService.getActiveForClient(), + this.clientFeatureToggleService.getActiveSegmentsForClient(), ]); } diff --git a/src/lib/features/client-feature-toggles/createClientFeatureToggleService.ts b/src/lib/features/client-feature-toggles/createClientFeatureToggleService.ts index 183fd5c94d39..9a0f4c330cee 100644 --- a/src/lib/features/client-feature-toggles/createClientFeatureToggleService.ts +++ b/src/lib/features/client-feature-toggles/createClientFeatureToggleService.ts @@ -3,6 +3,8 @@ import { Db } from '../../db/db'; import { IUnleashConfig } from '../../types'; import FakeClientFeatureToggleStore from './fakes/fake-client-feature-toggle-store'; import { ClientFeatureToggleService } from './client-feature-toggle-service'; +import { SegmentReadModel } from '../segment/segment-read-model'; +import { FakeSegmentReadModel } from '../segment/fake-segment-read-model'; export const createClientFeatureToggleService = ( db: Db, @@ -17,10 +19,13 @@ export const createClientFeatureToggleService = ( flagResolver, ); + const segmentReadModel = new SegmentReadModel(db); + const clientFeatureToggleService = new ClientFeatureToggleService( { clientFeatureToggleStore: featureToggleClientStore, }, + segmentReadModel, { getLogger, flagResolver }, ); @@ -34,10 +39,13 @@ export const createFakeClientFeatureToggleService = ( const fakeClientFeatureToggleStore = new FakeClientFeatureToggleStore(); + const fakeSegmentReadModel = new FakeSegmentReadModel(); + const clientFeatureToggleService = new ClientFeatureToggleService( { clientFeatureToggleStore: fakeClientFeatureToggleStore, }, + fakeSegmentReadModel, { getLogger, flagResolver }, ); diff --git a/src/lib/features/client-feature-toggles/tests/client-feature-toggle.e2e.test.ts b/src/lib/features/client-feature-toggles/tests/client-feature-toggle.e2e.test.ts index 7f21a2d8e1e9..b81f02d42e26 100644 --- a/src/lib/features/client-feature-toggles/tests/client-feature-toggle.e2e.test.ts +++ b/src/lib/features/client-feature-toggles/tests/client-feature-toggle.e2e.test.ts @@ -70,15 +70,16 @@ test('should get empty getFeatures via client', () => { test('if caching is enabled should memoize', async () => { const getClientFeatures = jest.fn().mockReturnValue([]); - const getActive = jest.fn().mockReturnValue([]); - const getActiveForClient = jest.fn().mockReturnValue([]); + const getActiveSegmentsForClient = jest.fn().mockReturnValue([]); const respondWithValidation = jest.fn().mockReturnValue({}); const validPath = jest.fn().mockReturnValue(jest.fn()); const clientSpecService = new ClientSpecService({ getLogger }); const openApiService = { respondWithValidation, validPath }; - const clientFeatureToggleService = { getClientFeatures }; + const clientFeatureToggleService = { + getClientFeatures, + getActiveSegmentsForClient, + }; const featureToggleService = { getClientFeatures }; - const segmentService = { getActive, getActiveForClient }; const configurationRevisionService = { getMaxRevisionId: () => 1 }; const controller = new FeatureController( @@ -91,8 +92,6 @@ test('if caching is enabled should memoize', async () => { // @ts-expect-error due to partial implementation featureToggleService, // @ts-expect-error due to partial implementation - segmentService, - // @ts-expect-error due to partial implementation configurationRevisionService, }, { @@ -112,13 +111,14 @@ test('if caching is enabled should memoize', async () => { test('if caching is not enabled all calls goes to service', async () => { const getClientFeatures = jest.fn().mockReturnValue([]); - const getActive = jest.fn().mockReturnValue([]); - const getActiveForClient = jest.fn().mockReturnValue([]); + const getActiveSegmentsForClient = jest.fn().mockReturnValue([]); const respondWithValidation = jest.fn().mockReturnValue({}); const validPath = jest.fn().mockReturnValue(jest.fn()); const clientSpecService = new ClientSpecService({ getLogger }); - const clientFeatureToggleService = { getClientFeatures }; - const segmentService = { getActive, getActiveForClient }; + const clientFeatureToggleService = { + getClientFeatures, + getActiveSegmentsForClient, + }; const featureToggleService = { getClientFeatures }; const openApiService = { respondWithValidation, validPath }; const configurationRevisionService = { getMaxRevisionId: () => 1 }; @@ -133,8 +133,6 @@ test('if caching is not enabled all calls goes to service', async () => { // @ts-expect-error due to partial implementation featureToggleService, // @ts-expect-error due to partial implementation - segmentService, - // @ts-expect-error due to partial implementation configurationRevisionService, }, { diff --git a/src/lib/segments/segment-service-interface.ts b/src/lib/segments/segment-service-interface.ts index 4e6b278dc601..67484522bb55 100644 --- a/src/lib/segments/segment-service-interface.ts +++ b/src/lib/segments/segment-service-interface.ts @@ -1,6 +1,6 @@ import { ChangeRequestStrategy } from '../features/change-request-segment-usage-service/change-request-segment-usage-read-model'; import { UpsertSegmentSchema } from '../openapi'; -import { IClientSegment, IFeatureStrategy, ISegment, IUser } from '../types'; +import { IFeatureStrategy, ISegment, IUser } from '../types'; export type StrategiesUsingSegment = { strategies: IFeatureStrategy[]; @@ -33,8 +33,6 @@ export interface ISegmentService { validateName(name: string): Promise; - getActiveForClient(): Promise; - getAll(): Promise; create( diff --git a/src/lib/services/segment-service.ts b/src/lib/services/segment-service.ts index 796f7098c49a..1231c1cf5465 100644 --- a/src/lib/services/segment-service.ts +++ b/src/lib/services/segment-service.ts @@ -1,6 +1,5 @@ import { IUnleashConfig } from '../types/option'; import { - IClientSegment, IFlagResolver, IUnleashStores, SKIP_CHANGE_REQUEST, @@ -79,10 +78,6 @@ export class SegmentService implements ISegmentService { return this.segmentStore.getAll(this.config.isEnterprise); } - async getActiveForClient(): Promise { - return this.segmentStore.getActiveForClient(); - } - async getByStrategy(strategyId: string): Promise { return this.segmentStore.getByStrategy(strategyId); } diff --git a/src/lib/types/stores/segment-store.ts b/src/lib/types/stores/segment-store.ts index 20c50f2d298a..9328c73ec8c2 100644 --- a/src/lib/types/stores/segment-store.ts +++ b/src/lib/types/stores/segment-store.ts @@ -1,14 +1,10 @@ -import { IClientSegment, IFeatureStrategySegment, ISegment } from '../model'; +import { IFeatureStrategySegment, ISegment } from '../model'; import { Store } from './store'; import User from '../user'; export interface ISegmentStore extends Store { getAll(includeChangeRequestUsageData?: boolean): Promise; - getActive(): Promise; - - getActiveForClient(): Promise; - getByStrategy(strategyId: string): Promise; create( diff --git a/src/test/fixtures/fake-segment-store.ts b/src/test/fixtures/fake-segment-store.ts index da1b73b75901..0d90dfa60ba3 100644 --- a/src/test/fixtures/fake-segment-store.ts +++ b/src/test/fixtures/fake-segment-store.ts @@ -1,9 +1,5 @@ import { ISegmentStore } from '../../lib/types/stores/segment-store'; -import { - IClientSegment, - IFeatureStrategySegment, - ISegment, -} from '../../lib/types/model'; +import { IFeatureStrategySegment, ISegment } from '../../lib/types/model'; export default class FakeSegmentStore implements ISegmentStore { count(): Promise { @@ -34,14 +30,6 @@ export default class FakeSegmentStore implements ISegmentStore { return []; } - async getActive(): Promise { - return []; - } - - async getActiveForClient(): Promise { - return []; - } - async getByStrategy(): Promise { return []; }