From 98d462db275100bcf2271c7f9609b07fd6237837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gast=C3=B3n=20Fournier?= Date: Tue, 7 Mar 2023 14:56:20 +0100 Subject: [PATCH] chore: add a new project column to segments table (#3263) ## About the changes Adds a migration and persistence layer with a new column `segment_project_id` to bind a segment to a project. --- src/lib/db/feature-toggle-client-store.ts | 15 +-------- src/lib/db/index.ts | 2 -- src/lib/db/segment-store.ts | 5 +++ .../createFeatureToggleService.ts | 2 -- src/lib/types/model.ts | 1 + ...06103400-add-project-column-to-segments.js | 13 ++++++++ .../feature-toggle-client-store.e2e.test.ts | 32 +++++++++++++++++++ 7 files changed, 52 insertions(+), 18 deletions(-) create mode 100644 src/migrations/20230306103400-add-project-column-to-segments.js create mode 100644 src/test/e2e/stores/feature-toggle-client-store.e2e.test.ts diff --git a/src/lib/db/feature-toggle-client-store.ts b/src/lib/db/feature-toggle-client-store.ts index 3de0b5c675..3a70625d89 100644 --- a/src/lib/db/feature-toggle-client-store.ts +++ b/src/lib/db/feature-toggle-client-store.ts @@ -15,7 +15,6 @@ import EventEmitter from 'events'; import FeatureToggleStore from './feature-toggle-store'; import { ensureStringValue } from '../util/ensureStringValue'; import { mapValues } from '../util/map-values'; -import { IFlagResolver } from '../types/experimental'; import Raw = Knex.Raw; import { Db } from './db'; @@ -51,28 +50,16 @@ export default class FeatureToggleClientStore private logger: Logger; - private inlineSegmentConstraints: boolean; - private timer: Function; - private flagResolver: IFlagResolver; - - constructor( - db: Db, - eventBus: EventEmitter, - getLogger: LogProvider, - inlineSegmentConstraints: boolean, - flagResolver: IFlagResolver, - ) { + constructor(db: Db, eventBus: EventEmitter, getLogger: LogProvider) { this.db = db; this.logger = getLogger('feature-toggle-client-store.ts'); - this.inlineSegmentConstraints = inlineSegmentConstraints; this.timer = (action) => metricsHelper.wrapTimer(eventBus, DB_TIME, { store: 'feature-toggle', action, }); - this.flagResolver = flagResolver; } private async getAll({ diff --git a/src/lib/db/index.ts b/src/lib/db/index.ts index 02c2ed1378..0baefaad43 100644 --- a/src/lib/db/index.ts +++ b/src/lib/db/index.ts @@ -85,8 +85,6 @@ export const createStores = ( db, eventBus, getLogger, - config.inlineSegmentConstraints, - config.flagResolver, ), environmentStore: new EnvironmentStore(db, eventBus, getLogger), featureTagStore: new FeatureTagStore(db, eventBus, getLogger), diff --git a/src/lib/db/segment-store.ts b/src/lib/db/segment-store.ts index 149932a315..a2fc24ce4c 100644 --- a/src/lib/db/segment-store.ts +++ b/src/lib/db/segment-store.ts @@ -17,6 +17,7 @@ const COLUMNS = [ 'id', 'name', 'description', + 'segment_project_id', 'created_by', 'created_at', 'constraints', @@ -26,6 +27,7 @@ interface ISegmentRow { id: number; name: string; description?: string; + segment_project_id?: string; created_by?: string; created_at?: Date; constraints: IConstraint[]; @@ -66,6 +68,7 @@ export default class SegmentStore implements ISegmentStore { id: segment.id, name: segment.name, description: segment.description, + segment_project_id: segment.project, constraints: JSON.stringify(segment.constraints), created_by: user.username || user.email, }) @@ -80,6 +83,7 @@ export default class SegmentStore implements ISegmentStore { .update({ name: segment.name, description: segment.description, + segment_project_id: segment.project, constraints: JSON.stringify(segment.constraints), }) .returning(COLUMNS); @@ -199,6 +203,7 @@ export default class SegmentStore implements ISegmentStore { id: row.id, name: row.name, description: row.description, + project: row.segment_project_id, constraints: row.constraints, createdBy: row.created_by, createdAt: row.created_at, diff --git a/src/lib/features/feature-toggle/createFeatureToggleService.ts b/src/lib/features/feature-toggle/createFeatureToggleService.ts index 1b2930ef9f..c1eabb586b 100644 --- a/src/lib/features/feature-toggle/createFeatureToggleService.ts +++ b/src/lib/features/feature-toggle/createFeatureToggleService.ts @@ -51,8 +51,6 @@ export const createFeatureToggleService = ( db, eventBus, getLogger, - config.inlineSegmentConstraints, - flagResolver, ); const projectStore = new ProjectStore( db, diff --git a/src/lib/types/model.ts b/src/lib/types/model.ts index bae7afda68..4c7575b135 100644 --- a/src/lib/types/model.ts +++ b/src/lib/types/model.ts @@ -384,6 +384,7 @@ export interface ISegment { id: number; name: string; description?: string; + project?: string; constraints: IConstraint[]; createdBy?: string; createdAt: Date; diff --git a/src/migrations/20230306103400-add-project-column-to-segments.js b/src/migrations/20230306103400-add-project-column-to-segments.js new file mode 100644 index 0000000000..85857c1b83 --- /dev/null +++ b/src/migrations/20230306103400-add-project-column-to-segments.js @@ -0,0 +1,13 @@ +exports.up = function (db, cb) { + db.runSql( + `ALTER TABLE segments ADD COLUMN segment_project_id varchar(255) REFERENCES projects(id) ON DELETE CASCADE;`, + cb, + ); +}; + +exports.down = function (db, cb) { + db.runSql( + `ALTER TABLE segments DROP COLUMN IF EXISTS segment_project_id;`, + cb, + ); +}; diff --git a/src/test/e2e/stores/feature-toggle-client-store.e2e.test.ts b/src/test/e2e/stores/feature-toggle-client-store.e2e.test.ts new file mode 100644 index 0000000000..5c802f5858 --- /dev/null +++ b/src/test/e2e/stores/feature-toggle-client-store.e2e.test.ts @@ -0,0 +1,32 @@ +import dbInit from '../helpers/database-init'; +import getLogger from '../../fixtures/no-logger'; +import { setupApp } from '../helpers/test-helper'; + +let stores; +let app; +let db; +let featureToggleClientStore; + +beforeAll(async () => { + getLogger.setMuteError(true); + db = await dbInit('feature_toggle_client_store_serial', getLogger); + app = await setupApp(db.stores); + stores = db.stores; + featureToggleClientStore = stores.featureToggleClientStore; +}); + +afterAll(async () => { + await app.destroy(); + await db.destroy(); +}); + +test('should be able to fetch client toggles', async () => { + const response = await app.request + .post('/api/admin/state/import?drop=true') + .attach('file', 'src/test/examples/exported-segments.json'); + + expect(response.status).toBe(202); + + const clientToggles = await featureToggleClientStore.getClient(); + expect(clientToggles).toHaveLength(1); +});