Skip to content

Commit 92881d8

Browse files
Merge pull request #2885 from RedisInsight/feature/RI-5257-add-telemetry-usser-property
Feature/ri 5257 add telemetry usser property
2 parents 64013cb + d93384f commit 92881d8

30 files changed

+542
-59
lines changed

redisinsight/api/config/features-config.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": 2.3402,
2+
"version": 2.3403,
33
"features": {
44
"insightsRecommendations": {
55
"flag": true,
@@ -47,6 +47,22 @@
4747
}
4848
}
4949
},
50+
"cloudSsoRecommendedSettings": {
51+
"flag": true,
52+
"perc": [[0, 50]],
53+
"filters": [
54+
{
55+
"name": "config.server.buildType",
56+
"value": "ELECTRON",
57+
"cond": "eq"
58+
},
59+
{
60+
"name": "agreements.analytics",
61+
"value": true,
62+
"cond": "eq"
63+
}
64+
]
65+
},
5066
"redisModuleFilter": {
5167
"flag": true,
5268
"perc": [[0, 100]],

redisinsight/api/src/__mocks__/feature.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,12 @@ export const mockFeatureSso = Object.assign(new Feature(), {
182182
redisStackPreview: [
183183
{
184184
provider: 'AWS',
185-
regions: ['us-east-2', 'ap-southeast-1', 'sa-east-1']
185+
regions: ['us-east-2', 'ap-southeast-1', 'sa-east-1'],
186186
},
187187
{
188188
provider: 'GCP',
189-
regions: ['asia-northeast1', 'europe-west1', 'us-central1']
190-
}
189+
regions: ['asia-northeast1', 'europe-west1', 'us-central1'],
190+
},
191191
],
192192
},
193193
},

redisinsight/api/src/modules/analytics/analytics.service.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ describe('AnalyticsService', () => {
196196
event: TelemetryEvents.ApplicationStarted,
197197
eventData: {},
198198
nonTracking: false,
199+
traits: {
200+
telemetry: 'will be overwritten',
201+
custom: 'trait',
202+
},
199203
});
200204

201205
expect(mockAnalyticsPage).toHaveBeenCalledWith({
@@ -205,6 +209,7 @@ describe('AnalyticsService', () => {
205209
context: {
206210
traits: {
207211
telemetry: Telemetry.Enabled,
212+
custom: 'trait',
208213
},
209214
},
210215
properties: {

redisinsight/api/src/modules/analytics/analytics.service.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export interface ITelemetryEvent {
1313
event: string;
1414
eventData: Object;
1515
nonTracking: boolean;
16+
traits?: Object;
1617
}
1718

1819
export interface ITelemetryInitEvent {
@@ -43,7 +44,7 @@ export class AnalyticsService {
4344

4445
private appVersion: string = '2.0.0';
4546

46-
private analytics;
47+
private analytics: Analytics;
4748

4849
constructor(
4950
private settingsService: SettingsService,
@@ -80,7 +81,9 @@ export class AnalyticsService {
8081
// for analytics is granted or not.
8182
// If permissions not granted
8283
// anonymousId will includes "00000000-0000-0000-0000-000000000001" value without any user identifiers.
83-
const { event, eventData, nonTracking } = payload;
84+
const {
85+
event, eventData, nonTracking, traits = {},
86+
} = payload;
8487
const isAnalyticsGranted = await this.checkIsAnalyticsGranted();
8588

8689
if (isAnalyticsGranted || nonTracking) {
@@ -90,8 +93,9 @@ export class AnalyticsService {
9093
event,
9194
context: {
9295
traits: {
96+
...traits,
9397
telemetry: isAnalyticsGranted ? Telemetry.Enabled : Telemetry.Disabled,
94-
}
98+
},
9599
},
96100
properties: {
97101
...eventData,
@@ -118,7 +122,9 @@ export class AnalyticsService {
118122
// user in any way. When `nonTracking` is True, the event is sent regardless of whether the user's permission
119123
// for analytics is granted or not.
120124
// If permissions not granted anonymousId includes "UNSET" value without any user identifiers.
121-
const { event, eventData, nonTracking } = payload;
125+
const {
126+
event, eventData, nonTracking, traits = {},
127+
} = payload;
122128
const isAnalyticsGranted = await this.checkIsAnalyticsGranted();
123129

124130
if (isAnalyticsGranted || nonTracking) {
@@ -128,8 +134,9 @@ export class AnalyticsService {
128134
integrations: { Amplitude: { session_id: this.sessionId } },
129135
context: {
130136
traits: {
137+
...traits,
131138
telemetry: isAnalyticsGranted ? Telemetry.Enabled : Telemetry.Disabled,
132-
}
139+
},
133140
},
134141
properties: {
135142
...eventData,

redisinsight/api/src/modules/analytics/dto/analytics.dto.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,13 @@ export class SendEventDto {
3636
@IsOptional()
3737
@IsBoolean()
3838
nonTracking: boolean = false;
39+
40+
@ApiPropertyOptional({
41+
description: 'User data.',
42+
type: Object,
43+
example: { telemetry: true },
44+
})
45+
@IsOptional()
46+
@ValidateNested()
47+
traits: Object = {};
3948
}

redisinsight/api/src/modules/cloud/job/cloud-job.factory.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
22
import {
33
CloudJob,
44
CreateFreeSubscriptionAndDatabaseCloudJob,
5-
ImportFreeDatabaseCloudJob
5+
ImportFreeDatabaseCloudJob,
66
} from 'src/modules/cloud/job/jobs';
77
import { CloudJobName } from 'src/modules/cloud/job/constants';
88
import { CreateFreeDatabaseCloudJob } from 'src/modules/cloud/job/jobs/create-free-database.cloud-job';
@@ -16,6 +16,7 @@ import { DatabaseService } from 'src/modules/database/database.service';
1616
import { CloudDatabaseAnalytics } from 'src/modules/cloud/database/cloud-database.analytics';
1717
import { CloudRequestUtm } from 'src/modules/cloud/common/models';
1818
import { CloudCapiKeyService } from 'src/modules/cloud/capi-key/cloud-capi-key.service';
19+
import { CloudSubscriptionApiService } from 'src/modules/cloud/subscription/cloud-subscription.api.service';
1920

2021
@Injectable()
2122
export class CloudJobFactory {
@@ -26,6 +27,7 @@ export class CloudJobFactory {
2627
private readonly cloudDatabaseAnalytics: CloudDatabaseAnalytics,
2728
private readonly databaseService: DatabaseService,
2829
private readonly cloudCapiKeyService: CloudCapiKeyService,
30+
private readonly cloudSubscriptionApiService: CloudSubscriptionApiService,
2931
) {}
3032

3133
async create(
@@ -53,6 +55,7 @@ export class CloudJobFactory {
5355
cloudDatabaseAnalytics: this.cloudDatabaseAnalytics,
5456
databaseService: this.databaseService,
5557
cloudCapiKeyService: this.cloudCapiKeyService,
58+
cloudSubscriptionApiService: this.cloudSubscriptionApiService,
5659
},
5760
);
5861
case CloudJobName.CreateFreeDatabase:
Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
1-
import { ApiProperty } from '@nestjs/swagger';
2-
import { IsNotEmpty, IsNumber } from 'class-validator';
1+
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2+
import { IsBoolean, IsNotEmpty, IsNumber, IsOptional, ValidateIf } from 'class-validator';
33

44
export class CreateSubscriptionAndDatabaseCloudJobDataDto {
55
@ApiProperty({
66
description: 'Plan id for create a subscription.',
77
type: Number,
88
})
9+
@ValidateIf((object) => !object.isRecommendedSettings)
910
@IsNumber()
1011
@IsNotEmpty()
1112
planId: number;
13+
14+
@ApiPropertyOptional({
15+
description: 'Use recommended settings',
16+
type: Boolean,
17+
})
18+
@IsBoolean()
19+
@IsOptional()
20+
isRecommendedSettings?: boolean;
1221
}

redisinsight/api/src/modules/cloud/job/jobs/create-free-subscription-and-database.cloud-job.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { sortBy } from 'lodash';
12
import { CloudJob, CloudJobOptions, CreateFreeDatabaseCloudJob } from 'src/modules/cloud/job/jobs';
23
import { CloudTaskCapiService } from 'src/modules/cloud/task/cloud-task.capi.service';
34
import { CloudSubscriptionCapiService } from 'src/modules/cloud/subscription/cloud-subscription.capi.service';
@@ -10,15 +11,18 @@ import { Database } from 'src/modules/database/models/database';
1011
import { CloudDatabaseAnalytics } from 'src/modules/cloud/database/cloud-database.analytics';
1112
import { CloudCapiKeyService } from 'src/modules/cloud/capi-key/cloud-capi-key.service';
1213
import { CloudSubscription } from 'src/modules/cloud/subscription/models';
14+
import { CloudSubscriptionApiService } from '../../subscription/cloud-subscription.api.service';
15+
import { CloudSubscriptionPlanResponse } from '../../subscription/dto';
1316

1417
export class CreateFreeSubscriptionAndDatabaseCloudJob extends CloudJob {
1518
protected name = CloudJobName.CreateFreeSubscriptionAndDatabase;
1619

1720
constructor(
1821
readonly options: CloudJobOptions,
1922

20-
private readonly data: {
21-
planId: number,
23+
private data: {
24+
planId?: number,
25+
isRecommendedSettings?: boolean,
2226
},
2327

2428
protected readonly dependencies: {
@@ -28,12 +32,15 @@ export class CreateFreeSubscriptionAndDatabaseCloudJob extends CloudJob {
2832
cloudDatabaseAnalytics: CloudDatabaseAnalytics,
2933
databaseService: DatabaseService,
3034
cloudCapiKeyService: CloudCapiKeyService,
35+
cloudSubscriptionApiService: CloudSubscriptionApiService,
3136
},
3237
) {
3338
super(options);
3439
}
3540

3641
async iteration(): Promise<Database> {
42+
let planId = this.data?.planId;
43+
3744
this.logger.log('Create free subscription and database');
3845

3946
this.checkSignal();
@@ -42,9 +49,15 @@ export class CreateFreeSubscriptionAndDatabaseCloudJob extends CloudJob {
4249

4350
this.logger.debug('Get or create free subscription');
4451

52+
if (this.data?.isRecommendedSettings) {
53+
const plans = await this.dependencies.cloudSubscriptionApiService.getSubscriptionPlans(this.options.sessionMetadata);
54+
55+
planId = this.getRecommendedPlanId(plans);
56+
}
57+
4558
const freeSubscription: CloudSubscription = await this.runChildJob(
4659
CreateFreeSubscriptionCloudJob,
47-
this.data,
60+
{ planId },
4861
this.options,
4962
);
5063

@@ -72,4 +85,9 @@ export class CreateFreeSubscriptionAndDatabaseCloudJob extends CloudJob {
7285

7386
return database;
7487
}
88+
89+
private getRecommendedPlanId(plans: CloudSubscriptionPlanResponse[]) {
90+
const defaultPlan = sortBy(plans, ['details.displayOrder']);
91+
return defaultPlan[0]?.id;
92+
}
7593
}

redisinsight/api/src/modules/cloud/subscription/cloud-subscription.module.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { CloudSubscriptionCapiProvider } from './providers/cloud-subscription.ca
2525
],
2626
exports: [
2727
CloudSubscriptionCapiService,
28+
CloudSubscriptionApiService,
2829
],
2930
})
3031
export class CloudSubscriptionModule {}

redisinsight/api/src/modules/feature/constants/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export enum FeatureConfigConfigDestination {
2222
export enum KnownFeatures {
2323
InsightsRecommendations = 'insightsRecommendations',
2424
CloudSso = 'cloudSso',
25+
CloudSsoRecommendedSettings = 'cloudSsoRecommendedSettings',
2526
RedisModuleFilter = 'redisModuleFilter',
2627
}
2728

0 commit comments

Comments
 (0)