Skip to content

Commit 13ea11a

Browse files
Feat/user onboard survey form (#729)
Added User Onboard Survey Form.
2 parents 1a516ec + 77edc45 commit 13ea11a

File tree

27 files changed

+439
-122
lines changed

27 files changed

+439
-122
lines changed

apps/api/src/app/auth/auth.controller.ts

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,19 @@ import {
1313
} from '@nestjs/common';
1414

1515
import { IJwtPayload } from '@impler/shared';
16+
import { AuthService } from './services/auth.service';
1617
import { IStrategyResponse } from '@shared/types/auth.types';
1718
import { CONSTANTS, COOKIE_CONFIG } from '@shared/constants';
1819
import { UserSession } from '@shared/framework/user.decorator';
1920
import { ApiException } from '@shared/exceptions/api.exception';
2021
import { StrategyUser } from './decorators/strategy-user.decorator';
21-
import { RegisterUserDto, LoginUserDto, RequestForgotPasswordDto, ResetPasswordDto } from './dtos';
22+
import { RegisterUserDto, LoginUserDto, RequestForgotPasswordDto, ResetPasswordDto, OnboardUserDto } from './dtos';
2223
import {
2324
RegisterUser,
2425
RegisterUserCommand,
2526
LoginUser,
2627
ResetPassword,
28+
OnboardUser,
2729
LoginUserCommand,
2830
ResetPasswordCommand,
2931
RequestForgotPassword,
@@ -36,8 +38,10 @@ import {
3638
@UseInterceptors(ClassSerializerInterceptor)
3739
export class AuthController {
3840
constructor(
39-
private registerUser: RegisterUser,
4041
private loginUser: LoginUser,
42+
private onboardUser: OnboardUser,
43+
private authService: AuthService,
44+
private registerUser: RegisterUser,
4145
private resetPassword: ResetPassword,
4246
private requestForgotPassword: RequestForgotPassword
4347
) {}
@@ -112,6 +116,38 @@ export class AuthController {
112116
response.send(registeredUser);
113117
}
114118

119+
@Post('/onboard')
120+
async onboardUserRoute(
121+
@Body() body: OnboardUserDto,
122+
@UserSession() user: IJwtPayload,
123+
@Res({ passthrough: true }) res: Response
124+
) {
125+
const projectWithEnvironment = await this.onboardUser.execute({
126+
_userId: user._id,
127+
projectName: body.projectName,
128+
role: body.role,
129+
companySize: body.companySize,
130+
source: body.source,
131+
});
132+
const token = this.authService.getSignedToken(
133+
{
134+
_id: user._id,
135+
firstName: user.firstName,
136+
lastName: user.lastName,
137+
email: user.email,
138+
profilePicture: user.profilePicture,
139+
accessToken: projectWithEnvironment.environment.apiKeys[0].key,
140+
},
141+
projectWithEnvironment.project._id
142+
);
143+
res.cookie(CONSTANTS.AUTH_COOKIE_NAME, token, {
144+
...COOKIE_CONFIG,
145+
domain: process.env.COOKIE_DOMAIN,
146+
});
147+
148+
return projectWithEnvironment;
149+
}
150+
115151
@Post('/login')
116152
async login(@Body() body: LoginUserDto, @Res() response: Response) {
117153
const loginUser = await this.loginUser.execute(

apps/api/src/app/auth/auth.module.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
import { Global, MiddlewareConsumer, Module, NestModule, Provider, RequestMethod } from '@nestjs/common';
2-
import { JwtModule } from '@nestjs/jwt';
31
import * as passport from 'passport';
2+
import { JwtModule } from '@nestjs/jwt';
3+
import { PassportModule } from '@nestjs/passport';
4+
import { Global, MiddlewareConsumer, Module, NestModule, Provider, RequestMethod } from '@nestjs/common';
5+
46
import { USE_CASES } from './usecases';
57
import { CONSTANTS } from '@shared/constants';
6-
import { PassportModule } from '@nestjs/passport';
78
import { AuthController } from './auth.controller';
9+
import { PaymentAPIService } from '@impler/services';
810
import { AuthService } from './services/auth.service';
911
import { SharedModule } from '../shared/shared.module';
10-
import { GitHubStrategy } from './services/passport/github.strategy';
11-
import { JwtStrategy } from './services/passport/jwt.strategy';
1212
import { LeadService } from '@shared/services/lead.service';
13-
import { PaymentAPIService } from '@impler/services';
13+
import { JwtStrategy } from './services/passport/jwt.strategy';
14+
import { GitHubStrategy } from './services/passport/github.strategy';
1415

1516
const AUTH_STRATEGIES: Provider[] = [JwtStrategy];
1617

@@ -33,7 +34,7 @@ if (process.env.GITHUB_OAUTH_CLIENT_ID) {
3334
}),
3435
],
3536
controllers: [AuthController],
36-
providers: [AuthService, ...AUTH_STRATEGIES, ...USE_CASES, LeadService, PaymentAPIService],
37+
providers: [AuthService, LeadService, ...AUTH_STRATEGIES, ...USE_CASES, PaymentAPIService],
3738
exports: [AuthService],
3839
})
3940
export class AuthModule implements NestModule {

apps/api/src/app/auth/dtos/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export * from './register-user.dto';
22
export * from './login-user.dto';
33
export * from './request-forgot-password.dto';
44
export * from './reset-password.dto';
5+
export * from './onboard-user.dto';
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { IsDefined, IsString } from 'class-validator';
2+
import { ApiProperty } from '@nestjs/swagger';
3+
4+
export class OnboardUserDto {
5+
@ApiProperty({
6+
description: 'Size of the company',
7+
})
8+
@IsString()
9+
@IsDefined()
10+
companySize: string;
11+
12+
@ApiProperty({
13+
description: 'Role of the user',
14+
})
15+
@IsString()
16+
@IsDefined()
17+
role: string;
18+
19+
@ApiProperty({
20+
description: 'Source from where the user heard about us',
21+
})
22+
@IsString()
23+
@IsDefined()
24+
source: string;
25+
26+
@ApiProperty({
27+
description: 'Name of the Project',
28+
})
29+
@IsString()
30+
@IsDefined()
31+
projectName: string;
32+
}

apps/api/src/app/auth/services/auth.service.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ import { JwtService } from '@nestjs/jwt';
33
import { Injectable, UnauthorizedException } from '@nestjs/common';
44

55
import { IJwtPayload } from '@impler/shared';
6-
import { CONSTANTS } from '@shared/constants';
6+
import { CONSTANTS, LEAD_SIGNUP_USING } from '@shared/constants';
77
import { PaymentAPIService } from '@impler/services';
8-
import { LeadService } from '@shared/services/lead.service';
98
import { UserEntity, UserRepository, EnvironmentRepository } from '@impler/dal';
109
import { UserNotFoundException } from '@shared/exceptions/user-not-found.exception';
1110
import { IAuthenticationData, IStrategyResponse } from '@shared/types/auth.types';
@@ -15,7 +14,6 @@ import { IncorrectLoginCredentials } from '@shared/exceptions/incorrect-login-cr
1514
export class AuthService {
1615
constructor(
1716
private jwtService: JwtService,
18-
private leadService: LeadService,
1917
private userRepository: UserRepository,
2018
private environmentRepository: EnvironmentRepository,
2119
private paymentAPIService: PaymentAPIService
@@ -32,16 +30,11 @@ export class AuthService {
3230
email: profile.email,
3331
firstName: profile.firstName,
3432
lastName: profile.lastName,
33+
signupMethod: LEAD_SIGNUP_USING.GITHUB,
3534
profilePicture: profile.avatar_url,
3635
...(provider ? { tokens: [provider] } : {}),
3736
};
3837
user = await this.userRepository.create(userObj);
39-
await this.leadService.createLead({
40-
'First Name': user.firstName,
41-
'Last Name': user.lastName,
42-
'Lead Email': user.email,
43-
'Lead Source': 'Github Signup',
44-
});
4538
userCreated = true;
4639

4740
const userData = {
Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,41 @@
11
import { LoginUser } from './login-user/login-user.usecase';
2+
import { OnboardUser } from './onboard-user/onboard-user.usecase';
23
import { RegisterUser } from './register-user/register-user.usecase';
34
import { ResetPassword } from './reset-password/reset-password.usecase';
45
import { RequestForgotPassword } from './request-forgot-password/request-forgot-pasword.usecase';
56

67
import { LoginUserCommand } from './login-user/login-user.command';
8+
import { OnboardUserCommand } from './onboard-user/onboard-user.command';
79
import { RegisterUserCommand } from './register-user/register-user.command';
810
import { ResetPasswordCommand } from './reset-password/reset-password.command';
911
import { RequestForgotPasswordCommand } from './request-forgot-password/request-forgot-pasword.command';
12+
import { CreateProject } from 'app/project/usecases';
13+
import { SaveSampleFile, UpdateImageColumns } from '@shared/usecases';
14+
import { CreateEnvironment, GenerateUniqueApiKey } from 'app/environment/usecases';
15+
import { CreateTemplate, UpdateCustomization, UpdateTemplateColumns } from 'app/template/usecases';
1016

1117
export const USE_CASES = [
1218
RegisterUser,
1319
LoginUser,
20+
OnboardUser,
1421
ResetPassword,
22+
CreateProject,
23+
SaveSampleFile,
24+
CreateTemplate,
25+
CreateEnvironment,
26+
UpdateImageColumns,
27+
UpdateCustomization,
28+
GenerateUniqueApiKey,
29+
UpdateTemplateColumns,
1530
RequestForgotPassword,
1631
//
1732
];
1833

19-
export { RegisterUser, LoginUser, RequestForgotPassword, ResetPassword };
20-
export { RegisterUserCommand, LoginUserCommand, RequestForgotPasswordCommand, ResetPasswordCommand };
34+
export { RegisterUser, LoginUser, RequestForgotPassword, ResetPassword, OnboardUser };
35+
export {
36+
LoginUserCommand,
37+
OnboardUserCommand,
38+
RegisterUserCommand,
39+
ResetPasswordCommand,
40+
RequestForgotPasswordCommand,
41+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export class OnboardUserCommand {
2+
_userId: string;
3+
projectName: string;
4+
companySize: string;
5+
role: string;
6+
source: string;
7+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { UserRepository } from '@impler/dal';
3+
import { LEAD_SIGNUP_USING } from '@shared/constants';
4+
import { OnboardUserCommand } from './onboard-user.command';
5+
import { LeadService } from '@shared/services/lead.service';
6+
import { CreateProject, CreateProjectCommand } from 'app/project/usecases';
7+
8+
@Injectable()
9+
export class OnboardUser {
10+
constructor(
11+
private leadService: LeadService,
12+
private createProject: CreateProject,
13+
private userRepository: UserRepository
14+
) {}
15+
16+
async execute(command: OnboardUserCommand) {
17+
const createdProject = await this.createProject.execute(
18+
CreateProjectCommand.create({
19+
_userId: command._userId,
20+
name: command.projectName,
21+
onboarding: true,
22+
})
23+
);
24+
25+
await this.userRepository.update(
26+
{ _id: command._userId },
27+
{
28+
role: command.role,
29+
companySize: command.companySize,
30+
source: command.source,
31+
}
32+
);
33+
34+
const updatedUser = await this.userRepository.findOne({ _id: command._userId });
35+
if (updatedUser) {
36+
await this.leadService.createLead({
37+
'First Name': updatedUser.firstName,
38+
'Last Name': updatedUser.lastName,
39+
'Lead Email': updatedUser.email,
40+
'Lead Source': updatedUser.source,
41+
'Mentioned Role': updatedUser.role,
42+
'Signup Method': updatedUser.signupMethod as LEAD_SIGNUP_USING,
43+
'Company Size': updatedUser.companySize,
44+
});
45+
}
46+
47+
return createdProject;
48+
}
49+
}

apps/api/src/app/auth/usecases/register-user/register-user.usecase.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ import { PaymentAPIService } from '@impler/services';
66
import { AuthService } from '../../services/auth.service';
77
import { RegisterUserCommand } from './register-user.command';
88
import { UniqueEmailException } from '@shared/exceptions/unique-email.exception';
9-
import { LeadService } from '@shared/services/lead.service';
9+
import { LEAD_SIGNUP_USING } from '@shared/constants';
1010

1111
@Injectable()
1212
export class RegisterUser {
1313
constructor(
1414
private userRepository: UserRepository,
1515
private authService: AuthService,
16-
private leadService: LeadService,
1716
private paymentAPIService: PaymentAPIService
1817
) {}
1918

@@ -31,13 +30,7 @@ export class RegisterUser {
3130
firstName: command.firstName.toLowerCase(),
3231
lastName: command.lastName?.toLowerCase(),
3332
password: passwordHash,
34-
});
35-
36-
await this.leadService.createLead({
37-
'First Name': user.firstName,
38-
'Last Name': user.lastName,
39-
'Lead Email': user.email,
40-
'Lead Source': 'Website Signup',
33+
signupMethod: LEAD_SIGNUP_USING.EMAIL,
4134
});
4235

4336
const userData = {

apps/api/src/app/shared/constants.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,9 @@ export const VARIABLES = {
8282
export const DATE_FORMATS = {
8383
COMMON: 'DD MMM YYYY',
8484
};
85+
86+
// eslint-disable-next-line @typescript-eslint/naming-convention
87+
export enum LEAD_SIGNUP_USING {
88+
GITHUB = 'Github',
89+
EMAIL = 'Email',
90+
}

0 commit comments

Comments
 (0)