Skip to content

Commit

Permalink
refactor the hole app
Browse files Browse the repository at this point in the history
  • Loading branch information
Anas Abbal committed Jun 19, 2024
1 parent f4e3bd4 commit 8a84378
Show file tree
Hide file tree
Showing 17 changed files with 196 additions and 54 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:

strategy:
matrix:
app: [driver, notification, gateway, ride, user-service]
app: [driver, notification, gateway, ride, user-service, auth]

steps:
- name: Checkout code
Expand Down
6 changes: 3 additions & 3 deletions RUN.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ $ npm install

```bash
# development
$ nest start nuber-app
$ nest start gateway
$ nest start <name-service>

# watch mode
$ nest start --watch nuber-app
$ nest start --watch gateway
$ nest start --watch <name-service>
```

## Help

Please run the nuber-app first and after run each service in node terminal or window... and check your db config
Please run each service in node terminal or window... and check your db config

After runing the nuber-app check the http:localhost:3000/api for Swagger
22 changes: 22 additions & 0 deletions apps/auth/src/auth.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';

describe('AuthController', () => {
let authController: AuthController;

beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AuthController],
providers: [AuthService],
}).compile();

authController = app.get<AuthController>(AuthController);
});

describe('root', () => {
it('should return "Hello World!"', () => {
expect(authController.getHello()).toBe('Hello World!');
});
});
});
12 changes: 12 additions & 0 deletions apps/auth/src/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Controller, Get } from '@nestjs/common';
import { AuthService } from './auth.service';

@Controller()
export class AuthController {
constructor(private readonly authService: AuthService) {}

@Get()
getHello(): string {
return this.authService.getHello();
}
}
10 changes: 10 additions & 0 deletions apps/auth/src/auth.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';

@Module({
imports: [],
controllers: [AuthController],
providers: [AuthService],
})
export class AuthModule {}
6 changes: 6 additions & 0 deletions apps/auth/src/auth.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Injectable } from '@nestjs/common';

@Injectable()
export class AuthService {

}
17 changes: 17 additions & 0 deletions apps/auth/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { NestFactory } from '@nestjs/core';
import { AuthModule } from './auth.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';

async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AuthModule,
{
transport: Transport.TCP,
options: {
port: 3005,
},
},
);
await app.listen();
}
bootstrap();
24 changes: 24 additions & 0 deletions apps/auth/test/app.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AuthModule } from './../src/auth.module';

describe('AuthController (e2e)', () => {
let app: INestApplication;

beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AuthModule],
}).compile();

app = moduleFixture.createNestApplication();
await app.init();
});

it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
});
9 changes: 9 additions & 0 deletions apps/auth/test/jest-e2e.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testEnvironment": "node",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}
9 changes: 9 additions & 0 deletions apps/auth/tsconfig.app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"declaration": false,
"outDir": "../../dist/apps/auth"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
}
3 changes: 2 additions & 1 deletion apps/gateway/src/gateway.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { UserController } from './rest/user.controller';
import { DriversController } from './rest/driver.controller';
import { UserService } from './services/user-service';
import { DriverService } from './services/driver-service';
import { AuthService } from './services/auth.service';

@Module({
imports: [
Expand Down Expand Up @@ -46,6 +47,6 @@ import { DriverService } from './services/driver-service';
}),
],
controllers: [AuthController, UserController, DriversController],
providers: [UserService, DriverService]
providers: [UserService, DriverService, AuthService]
})
export class GatewayModule {}
7 changes: 4 additions & 3 deletions apps/gateway/src/rest/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Body, Controller, Get, Param, Post } from '@nestjs/common';
import { UserService } from '../services/user-service';
import { UserCreateCommand } from '@app/shared/commands/auth/user.create.cmd';
import { DriverCreateCmd } from '@app/shared/commands/driver/driver.create.cmd';
import { AuthService } from '../services/auth.service';



Expand All @@ -10,18 +11,18 @@ import { DriverCreateCmd } from '@app/shared/commands/driver/driver.create.cmd';

@Controller('auth')
export class AuthController {
constructor(private readonly userService: UserService) {}
constructor(private readonly authService: AuthService) {}


@Post('register/:userTypeId')
async register(@Body() createUserDto: UserCreateCommand | DriverCreateCmd,
@Param('userTypeId') userTypeId: string
) {
return this.userService.register(userTypeId,createUserDto);
return this.authService.register(userTypeId,createUserDto);
}

@Post('login')
async login(@Body() loginUserDto: any) {
return this.userService.login(loginUserDto);
return this.authService.login(loginUserDto);
}
}
60 changes: 60 additions & 0 deletions apps/gateway/src/services/auth.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { UserCreateCommand } from "@app/shared/commands/auth/user.create.cmd";
import { DriverCreateCmd } from "@app/shared/commands/driver/driver.create.cmd";
import { BadRequestException, ConflictException, Inject, Injectable, InternalServerErrorException, UnauthorizedException } from "@nestjs/common";
import { ClientProxy } from "@nestjs/microservices";
import { UserService } from "./user-service";
import { DriverService } from "./driver-service";





@Injectable()
export class AuthService {
constructor(
@Inject('USER_SERVICE') private readonly userClient: ClientProxy,
private readonly userService: UserService,
private readonly driverService: DriverService
){}

async register(userTypeId: string, command: UserCreateCommand | DriverCreateCmd): Promise<string> {
try {
const userType = await this.userService.findUserTypeById(userTypeId);
console.log(`User type with id ${userType.id} found`);
if(userType.id == userTypeId){
return await this.driverService.createDriver(command);
}else {
return await this.userService.createUser(command, userTypeId);
}
} catch (error) {
// log the error for debugging purposes
console.error('Error occurred during user registration:', error);
// decide how to handle different types of errors
if (error.response && error.response.status === 409) {
throw new ConflictException('User with this email already exists');
} else if (error.response && error.response.status === 400) {
throw new BadRequestException('Invalid user data provided');
} else {
// if the error is unexpected, throw an Internal Server Error
throw new InternalServerErrorException('Failed to register user');
}
}
}
async login(loginUserDto: any): Promise<any> {
try {
const result = await this.userClient.send({ cmd: 'login' }, loginUserDto).toPromise();
return result;
} catch (error) {
// log the error for debugging purposes
console.error('Error occurred during user login:', error);

// decide how to handle different types of errors
if (error.response && error.response.status === 401) {
throw new UnauthorizedException('Invalid credentials');
} else {
// if the error is unexpected, throw an Internal Server Error
throw new InternalServerErrorException('Failed to login');
}
}
}
}
4 changes: 4 additions & 0 deletions apps/gateway/src/services/driver-service.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DriverCreateCmd } from "@app/shared/commands/driver/driver.create.cmd";
import { DriverDto } from "@app/shared/events/driver/driver.dto";
import { Inject, Injectable, Logger, LoggerService } from "@nestjs/common";
import { ClientProxy } from "@nestjs/microservices";
Expand All @@ -16,6 +17,9 @@ export class DriverService {
){}


async createDriver(cmd: DriverCreateCmd): Promise<string> {
return await this.driverClient.send({ cmd: 'create' }, cmd).toPromise();
}
async getDrivers(): Promise<DriverDto[]> {
try {
const response = await this.driverClient.send<DriverDto[]>({ cmd: 'get_all_driver' }, {}).toPromise();
Expand Down
48 changes: 3 additions & 45 deletions apps/gateway/src/services/user-service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { UserCreateCommand } from '@app/shared/commands/auth/user.create.cmd';
import { DriverCreateCmd } from '@app/shared/commands/driver/driver.create.cmd';
import { GetUserEvent } from "@app/shared/events/user/user.get";
import { UserTypeDto } from "@app/shared/events/user/user.type.dto";
import { BadRequestException, ConflictException, Inject, Injectable, InternalServerErrorException, Logger, LoggerService, Post, UnauthorizedException } from "@nestjs/common";
import { BadRequestException, ConflictException, Inject, Injectable, InternalServerErrorException, LoggerService } from "@nestjs/common";
import { ClientProxy } from "@nestjs/microservices";
import { WINSTON_MODULE_NEST_PROVIDER } from "nest-winston";

Expand All @@ -13,7 +12,6 @@ export class UserService {

constructor(
@Inject('USER_SERVICE') private readonly userClient: ClientProxy,
@Inject('DRIVER_SERVICE') private readonly driverClient: ClientProxy,
@Inject(WINSTON_MODULE_NEST_PROVIDER) private readonly logger: LoggerService,
) {}

Expand All @@ -37,48 +35,8 @@ export class UserService {
}
}
}

async register(userTypeId: string, command: UserCreateCommand | DriverCreateCmd): Promise<string> {
try {
const userType = await this.findUserTypeById(userTypeId);
console.log(`User type with id ${userType.id} found`);
if(userType.id == userTypeId){
return await this.driverClient.send({ cmd: 'create' }, command).toPromise();
}else {
return await this.userClient.send({ cmd: 'register' }, { userTypeId, command: command }).toPromise();
}
} catch (error) {
// log the error for debugging purposes
console.error('Error occurred during user registration:', error);
// decide how to handle different types of errors
if (error.response && error.response.status === 409) {
throw new ConflictException('User with this email already exists');
} else if (error.response && error.response.status === 400) {
throw new BadRequestException('Invalid user data provided');
} else {
// if the error is unexpected, throw an Internal Server Error
throw new InternalServerErrorException('Failed to register user');
}
}
}


async login(loginUserDto: any): Promise<any> {
try {
const result = await this.userClient.send({ cmd: 'login' }, loginUserDto).toPromise();
return result;
} catch (error) {
// log the error for debugging purposes
console.error('Error occurred during user login:', error);

// decide how to handle different types of errors
if (error.response && error.response.status === 401) {
throw new UnauthorizedException('Invalid credentials');
} else {
// if the error is unexpected, throw an Internal Server Error
throw new InternalServerErrorException('Failed to login');
}
}
async createUser(command: UserCreateCommand, userTypeId: string): Promise<string> {
return await this.userClient.send({ cmd: 'register' }, { userTypeId, command: command }).toPromise();
}
async getAll(): Promise<any[]> {
try {
Expand Down
2 changes: 1 addition & 1 deletion apps/user-service/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Controller, Logger, Request, UseGuards } from '@nestjs/common';
import { MessagePattern, Payload } from '@nestjs/microservices';
import { AuthService } from './auth.service';
import { JwtAuthGuard } from './jwt.guard';
import { UserCreateCommand } from '@app/shared/commands/auth/user.create.cmd';
import { UserLoginCmd } from '@app/shared/commands/auth/user.login.cmd';
import { JwtAuthGuard } from './jwt.guard';

@Controller('auth')
export class AuthController {
Expand Down
9 changes: 9 additions & 0 deletions nest-cli.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@
"compilerOptions": {
"tsConfigPath": "apps/gateway/tsconfig.app.json"
}
},
"auth": {
"type": "application",
"root": "apps/auth",
"entryFile": "main",
"sourceRoot": "apps/auth/src",
"compilerOptions": {
"tsConfigPath": "apps/auth/tsconfig.app.json"
}
}
}
}

0 comments on commit 8a84378

Please sign in to comment.