Skip to content

Commit

Permalink
feat(src): Add onboarding proccess to load names
Browse files Browse the repository at this point in the history
  • Loading branch information
Victor Pino committed Aug 26, 2024
1 parent e7593e6 commit e161bff
Show file tree
Hide file tree
Showing 18 changed files with 632 additions and 9 deletions.
1 change: 0 additions & 1 deletion src/common/services/crud/crud.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
Injectable,
BadRequestException,
ConflictException,
Inject,
} from '@nestjs/common';
import {
Repository,
Expand Down
2 changes: 2 additions & 0 deletions src/modules/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { JwtStrategy } from './strategies/jwt.strategy';
import { LocalStrategy } from './strategies/local.strategy';
import { AuthController } from './auth.controller';
import { CustomerModule } from '../customer/customer.module';
import { IndividualCustomerModule } from '../individual-customer/individual-customer.module';

@Module({
imports: [
PassportModule,
CustomerModule,
IndividualCustomerModule,
JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
Expand Down
25 changes: 19 additions & 6 deletions src/modules/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ import { MESSAGES } from '../../common/constans/messages';
import { CustomerService } from '../customer/customer.service';
import { Customer } from '../customer/entities/customer.entity';
import { CreateCustomerDto } from '../customer/dtos/create.customer.dto';
import { IndividualCustomerService } from '../individual-customer/individual-customer.service';
import { LoginResponse } from './interfaces/LoginResponse';
import { IndividualCustomer } from '../individual-customer/entities/individual-customer.entity';

@Injectable()
export class AuthService {
constructor(
private customerService: CustomerService,
private individualCustomerService: IndividualCustomerService,

private jwtService: JwtService,
) {}

async validateCustomer(email: string, password: string): Promise<Customer> {
async validateCustomer(email: string, password: string): Promise<LoginResponse> {
const response: ResponseDTO<Customer> = await this.customerService.findOne({
email,
});
Expand All @@ -26,29 +31,37 @@ export class AuthService {

const customer = response.data;

const individualCustomer: ResponseDTO<IndividualCustomer> = await this.individualCustomerService.findOne(
{ customerId: { id: customer.id } }
);

const individual = individualCustomer.data

const comparePass = await bcrypt.compare(password, customer.password);

if (!comparePass) {
throw new UnauthorizedException(MESSAGES.INVALID_CREDENTIALS_ERROR);
}

return customer;
return {customer, individual};
}

async login(data: AuthValidation): Promise<ResponseDTO> {
const customer = await this.validateCustomer(data.email, data.password);
const response = await this.validateCustomer(data.email, data.password);

const payload = {
email: customer.email,
_id: customer.id,
email: response.customer.email,
id: response.customer.id,
};

const accessToken = this.jwtService.sign(payload);

return {
data: {
status: customer.isActive,
status: response.customer.isActive,
access_token: accessToken,
individual: response.individual,
id: response.customer.id
},
};
}
Expand Down
7 changes: 7 additions & 0 deletions src/modules/auth/interfaces/LoginResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Customer } from "src/modules/customer/entities/customer.entity";
import { IndividualCustomer } from "src/modules/individual-customer/entities/individual-customer.entity";

export interface LoginResponse {
customer: Customer,
individual: IndividualCustomer
}
17 changes: 17 additions & 0 deletions src/modules/customer/customer.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { kycRequirements } from './dtos/kyc.requirements.dto';
import { SkipJwtAuth } from 'src/common/decorators/skip-guard.decorator';
import { SubmitKycDto } from './dtos/submit.kyc.dto';
import { UpdateKycDto } from './dtos/update.kyc.dto';
import { LoadNamesDTO } from '../individual-customer/dtos/load-names.dto';

@ApiBearerAuth('JWT-auth')
@ApiTags('Customer')
Expand Down Expand Up @@ -125,4 +126,20 @@ export class CustomerController {
return error;
}
}


@Put(':id/load-names')
@ApiOperation({ summary: 'Load Names for an individual customer' })
@ApiResponse({
status: 200,
description: 'The names have been successfully loaded.',
})
async updateLoadNames(
@Param('id') id: string,
@Body() loadNamesDTO: LoadNamesDTO,
): Promise<ResponseDTO> {
const data = await this.customerService.updateLoadNames(id, loadNamesDTO);
return { data };
}

}
49 changes: 49 additions & 0 deletions src/modules/customer/customer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import { CreateCustomerDto } from './dtos/create.customer.dto';
import { IResponseCustomer } from './interfaces/response.customer.interface';
import { IResponseIndividualCustomer } from './interfaces/response.individual-customer.interface';
import { StatusKyc } from 'src/common/enums/customer.enums';
import { IndividualCustomer } from '../individual-customer/entities/individual-customer.entity';
import { LoadNamesDTO } from '../individual-customer/dtos/load-names.dto';
import { StatusOnboarding } from '../individual-customer/enums/individual-customer.enum';

@Injectable()
export class CustomerService extends CrudService<Customer> {
Expand Down Expand Up @@ -300,4 +303,50 @@ export class CustomerService extends CrudService<Customer> {
throw error;
}
}

async findOrCreateIndividualCustomer(
customerId: string,
): Promise<IndividualCustomer> {
const customer = await this.customerRepository.findOne({
where: { id: customerId },
});

if (!customer) {
throw new NotFoundException(`Customer with ID ${customerId} not found`);
}

let individualCustomer = await this.individualCustomerService.findOne(
{ customerId: { id: customerId } },
);

if (!individualCustomer.data) {
const newIndividualCustomer = await this.individualCustomerService.create({
customerId: customer,
});

individualCustomer.data = newIndividualCustomer;
}

return individualCustomer.data;
}

async updateLoadNames(
id: string,
loadNamesDTO: LoadNamesDTO,
): Promise<ResponseDTO> {
try {
const individualCustomer = await this.findOrCreateIndividualCustomer(id);

individualCustomer.firstName = loadNamesDTO.firstName;
individualCustomer.lastName = loadNamesDTO.lastName;
individualCustomer.status = StatusOnboarding.IDENTITY_DOCUMENT;

return await this.individualCustomerService.update(
individualCustomer.id,
individualCustomer,
);
} catch (error) {
throw error;
}
}
}
36 changes: 36 additions & 0 deletions src/modules/individual-customer/dtos/address.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, Length } from 'class-validator';

export class AddressDTO {
@ApiProperty({
description: 'Address of the individual customer',
example: '123 Main St',
})
@IsString()
@Length(1, 200)
address: string;

@ApiProperty({
description: 'State of the individual customer',
example: 'California',
})
@IsString()
@Length(1, 100)
state: string;

@ApiProperty({
description: 'City of the individual customer',
example: 'Los Angeles',
})
@IsString()
@Length(1, 100)
city: string;

@ApiProperty({
description: 'Town or locality',
example: 'Downtown',
})
@IsString()
@Length(1, 100)
town: string;
}
59 changes: 59 additions & 0 deletions src/modules/individual-customer/dtos/company-info.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, Length, IsPhoneNumber, IsNumberString } from 'class-validator';

export class CompanyInfoDTO {
@ApiProperty({
description: 'Name of the company',
example: 'Tech Solutions Inc.',
})
@IsString()
@Length(1, 100)
name: string;

@ApiProperty({
description: 'Phone number of the company',
example: '+1-800-123-4567',
})
@IsPhoneNumber(null)
phone: string;

@ApiProperty({
description: 'Address of the company',
example: '456 Business Rd',
})
@IsString()
@Length(1, 200)
address: string;

@ApiProperty({
description: 'State where the company is located',
example: 'New York',
})
@IsString()
@Length(1, 100)
state: string;

@ApiProperty({
description: 'City where the company is located',
example: 'New York City',
})
@IsString()
@Length(1, 100)
city: string;

@ApiProperty({
description: 'Year the company was founded or the individual joined',
example: '2015',
})
@IsNumberString()
@Length(4, 4)
year: string;

@ApiProperty({
description: 'Month the company was founded or the individual joined',
example: 'March',
})
@IsString()
@Length(1, 50)
month: string;
}
11 changes: 11 additions & 0 deletions src/modules/individual-customer/dtos/contact-info.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsPhoneNumber } from 'class-validator';

export class ContactInfoDTO {
@ApiProperty({
description: 'Phone number of the individual customer',
example: '+1-555-555-5555',
})
@IsPhoneNumber(null)
phone: string;
}
28 changes: 28 additions & 0 deletions src/modules/individual-customer/dtos/education-data.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, Length, IsNumberString } from 'class-validator';

export class EducationDataDTO {
@ApiProperty({
description: 'Level of education',
example: 'Bachelor',
})
@IsString()
@Length(1, 100)
level: string;

@ApiProperty({
description: 'Area of specialization',
example: 'Computer Science',
})
@IsString()
@Length(1, 100)
area: string;

@ApiProperty({
description: 'Year of graduation or last year attended',
example: '2015',
})
@IsNumberString()
@Length(4, 4)
year: string;
}
28 changes: 28 additions & 0 deletions src/modules/individual-customer/dtos/housing-data.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, Length, IsNumberString } from 'class-validator';

export class HousingDataDTO {
@ApiProperty({
description: 'Type of housing',
example: 'Apartment',
})
@IsString()
@Length(1, 100)
type: string;

@ApiProperty({
description: 'Year of purchase or construction',
example: '2010',
})
@IsNumberString()
@Length(4, 4)
year: string;

@ApiProperty({
description: 'Month of purchase or construction',
example: 'June',
})
@IsString()
@Length(1, 50)
month: string;
}
28 changes: 28 additions & 0 deletions src/modules/individual-customer/dtos/identity-document.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, Length } from 'class-validator';

export class IdentityDocumentDTO {
@ApiProperty({
description: 'Country of the identity document',
example: 'USA',
})
@IsString()
@Length(2, 100)
country: string;

@ApiProperty({
description: 'Type of the identity document',
example: 'Passport',
})
@IsString()
@Length(2, 100)
typeDocument: string;

@ApiProperty({
description: 'Document number (DNI)',
example: '123456789',
})
@IsString()
@Length(1, 100)
dni: string;
}
Loading

0 comments on commit e161bff

Please sign in to comment.