diff --git a/src/lib/__snapshots__/create-config.test.ts.snap b/src/lib/__snapshots__/create-config.test.ts.snap index 4abee2e5d4..74bdf34609 100644 --- a/src/lib/__snapshots__/create-config.test.ts.snap +++ b/src/lib/__snapshots__/create-config.test.ts.snap @@ -154,6 +154,7 @@ exports[`should create default config 1`] = ` "ui": { "environment": "Open Source", }, + "userInactivityThresholdInDays": 180, "versionCheck": { "enable": true, "url": "https://version.unleash.run", diff --git a/src/lib/create-config.ts b/src/lib/create-config.ts index c3550efd9b..a3156fb9b0 100644 --- a/src/lib/create-config.ts +++ b/src/lib/create-config.ts @@ -713,6 +713,14 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig { const openAIAPIKey = process.env.OPENAI_API_KEY; + const defaultDaysToBeConsideredInactive = 180; + const userInactivityThresholdInDays = + options.userInactivityThresholdInDays ?? + parseEnvVarNumber( + process.env.USER_INACTIVITY_THRESHOLD_IN_DAYS, + defaultDaysToBeConsideredInactive, + ); + return { db, session, @@ -752,6 +760,7 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig { feedbackUriPath, dailyMetricsStorageDays, openAIAPIKey, + userInactivityThresholdInDays, }; } diff --git a/src/lib/types/option.ts b/src/lib/types/option.ts index 2f265eb121..b9cb4957fe 100644 --- a/src/lib/types/option.ts +++ b/src/lib/types/option.ts @@ -156,6 +156,7 @@ export interface IUnleashOptions { | 'segments' > >; + userInactivityThresholdInDays?: number; } export interface IEmailOption { @@ -274,4 +275,5 @@ export interface IUnleashConfig { rateLimiting: IRateLimiting; feedbackUriPath?: string; openAIAPIKey?: string; + userInactivityThresholdInDays: number; } diff --git a/src/lib/users/inactive/createInactiveUsersService.ts b/src/lib/users/inactive/createInactiveUsersService.ts index 693a322d08..0fb077122b 100644 --- a/src/lib/users/inactive/createInactiveUsersService.ts +++ b/src/lib/users/inactive/createInactiveUsersService.ts @@ -5,30 +5,32 @@ import { InactiveUsersStore } from './inactive-users-store'; import { FakeInactiveUsersStore } from './fakes/fake-inactive-users-store'; import type { UserService } from '../../services'; -export const DAYS_TO_BE_COUNTED_AS_INACTIVE = 180; export const createInactiveUsersService = ( db: Db, config: IUnleashConfig, userService: UserService, ): InactiveUsersService => { - const { eventBus, getLogger } = config; + const { eventBus, getLogger, userInactivityThresholdInDays } = config; const inactiveUsersStore = new InactiveUsersStore(db, eventBus, getLogger); return new InactiveUsersService( { inactiveUsersStore }, - { getLogger }, + { getLogger, userInactivityThresholdInDays }, { userService }, ); }; export const createFakeInactiveUsersService = ( - { getLogger, eventBus }: Pick, + { + getLogger, + userInactivityThresholdInDays, + }: Pick, userService: UserService, ): InactiveUsersService => { const fakeStore = new FakeInactiveUsersStore(); return new InactiveUsersService( { inactiveUsersStore: fakeStore }, - { getLogger }, + { getLogger, userInactivityThresholdInDays }, { userService }, ); }; diff --git a/src/lib/users/inactive/inactive-users-controller.ts b/src/lib/users/inactive/inactive-users-controller.ts index 6d30f21196..9bf2223f0c 100644 --- a/src/lib/users/inactive/inactive-users-controller.ts +++ b/src/lib/users/inactive/inactive-users-controller.ts @@ -20,7 +20,6 @@ import { import type { IAuthRequest } from '../../routes/unleash-types'; import type { Response } from 'express'; import type { OpenApiService } from '../../services'; -import { DAYS_TO_BE_COUNTED_AS_INACTIVE } from './createInactiveUsersService'; import { anonymise } from '../../util'; export class InactiveUsersController extends Controller { private readonly logger: Logger; @@ -30,6 +29,8 @@ export class InactiveUsersController extends Controller { private openApiService: OpenApiService; private flagResolver: IFlagResolver; + + private readonly userInactivityThresholdInDays: number; constructor( config: IUnleashConfig, { @@ -44,6 +45,8 @@ export class InactiveUsersController extends Controller { this.inactiveUsersService = inactiveUsersService; this.openApiService = openApiService; this.flagResolver = config.flagResolver; + this.userInactivityThresholdInDays = + config.userInactivityThresholdInDays; this.route({ method: 'get', @@ -54,7 +57,7 @@ export class InactiveUsersController extends Controller { openApiService.validPath({ operationId: 'getInactiveUsers', summary: 'Gets inactive users', - description: `Gets all inactive users. An inactive user is a user that has not logged in in the last ${DAYS_TO_BE_COUNTED_AS_INACTIVE} days`, + description: `Gets all inactive users. An inactive user is a user that has not logged in in the last ${this.userInactivityThresholdInDays} days`, tags: ['Users'], responses: { 200: createResponseSchema('inactiveUsersSchema'), @@ -71,7 +74,7 @@ export class InactiveUsersController extends Controller { openApiService.validPath({ operationId: 'deleteInactiveUsers', summary: 'Deletes inactive users', - description: `Deletes all inactive users. An inactive user is a user that has not logged in in the last ${DAYS_TO_BE_COUNTED_AS_INACTIVE} days`, + description: `Deletes all inactive users. An inactive user is a user that has not logged in in the last ${this.userInactivityThresholdInDays} days`, tags: ['Users'], requestBody: createRequestSchema('idsSchema'), responses: { diff --git a/src/lib/users/inactive/inactive-users-service.ts b/src/lib/users/inactive/inactive-users-service.ts index 9cd58523f0..e90f0ddaaf 100644 --- a/src/lib/users/inactive/inactive-users-service.ts +++ b/src/lib/users/inactive/inactive-users-service.ts @@ -8,15 +8,18 @@ import type { IInactiveUsersStore } from './types/inactive-users-store-type'; import type { Logger } from '../../logger'; import type { InactiveUserSchema } from '../../openapi'; import type { UserService } from '../../services'; -import { DAYS_TO_BE_COUNTED_AS_INACTIVE } from './createInactiveUsersService'; export class InactiveUsersService { private inactiveUsersStore: IInactiveUsersStore; private readonly logger: Logger; private userService: UserService; + private readonly userInactivityThresholdInDays: number; constructor( { inactiveUsersStore }: Pick, - { getLogger }: Pick, + { + getLogger, + userInactivityThresholdInDays, + }: Pick, services: { userService: UserService; }, @@ -24,11 +27,12 @@ export class InactiveUsersService { this.logger = getLogger('services/client-feature-toggle-service.ts'); this.inactiveUsersStore = inactiveUsersStore; this.userService = services.userService; + this.userInactivityThresholdInDays = userInactivityThresholdInDays; } async getInactiveUsers(): Promise { const users = await this.inactiveUsersStore.getInactiveUsers( - DAYS_TO_BE_COUNTED_AS_INACTIVE, + this.userInactivityThresholdInDays, ); if (users.length > 0) { return users.map((user) => {