Skip to content

Commit 6939e0d

Browse files
authored
Merge pull request #52 from techknowledge-blog/feature/users-module
Users module
2 parents 4cfd9fd + efcaf80 commit 6939e0d

File tree

11 files changed

+218
-17
lines changed

11 files changed

+218
-17
lines changed

src/app.module.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,14 @@ import { PostsService } from './modules/posts/posts.service';
55
import { PrismaService } from './prisma.service';
66
import { PostsModule } from './modules/posts/posts.module';
77
import { AuthModule } from './modules/auth/auth.module';
8+
import { UsersModule } from './modules/users/users.module';
9+
import { UsersController } from './modules/users/users.controller';
10+
import { UsersService } from './modules/users/users.service';
811

912
@Module({
10-
imports: [
11-
// GraphQLModule.forRoot<ApolloDriverConfig>({
12-
// driver: ApolloDriver,
13-
// autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
14-
// definitions: {
15-
// path: join(process.cwd(), 'src/graphql.ts'),
16-
// },
17-
// }),
18-
PostsModule,
19-
AuthModule
20-
],
21-
controllers: [AppController],
22-
providers: [AppService, PrismaService, PostsService],
13+
imports: [PostsModule, AuthModule, UsersModule],
14+
controllers: [AppController, UsersController],
15+
providers: [AppService, PrismaService, PostsService, UsersService],
2316
exports: [PrismaService],
2417
})
2518
export class AppModule {}

src/main.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { NestFactory } from '@nestjs/core';
22
import { AppModule } from './app.module';
33
import * as dotenv from 'dotenv';
4+
import { ValidationPipe } from '@nestjs/common';
45
dotenv.config();
56

67
async function bootstrap() {
@@ -9,6 +10,8 @@ async function bootstrap() {
910
origin: '*',
1011
credentials: true,
1112
});
13+
14+
app.useGlobalPipes(new ValidationPipe({ transform: true }));
1215
await app.listen(3000);
1316
}
1417
bootstrap();

src/modules/auth/auth.module.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ import { JwtStrategy } from './jwt.strategy';
88

99
@Module({
1010
imports: [
11-
PassportModule.register({ defaultStrategy: 'jwt' }), // ✅ registers 'jwt'
11+
PassportModule.register({ defaultStrategy: 'jwt' }),
1212
JwtModule.register({
13-
secret: 'secretKey', // replace with process.env.JWT_SECRET in production
14-
signOptions: { expiresIn: '1h' }, // token expiry time
13+
secret: 'secretKey',
14+
signOptions: { expiresIn: '1h' },
1515
}),
1616
],
1717
controllers: [AuthController],
18-
providers: [AuthService, PrismaService, JwtStrategy], // ✅ provide JwtStrategy
18+
providers: [AuthService, PrismaService, JwtStrategy],
1919
exports: [AuthService],
2020
})
2121
export class AuthModule {}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import {
2+
IsEmail,
3+
IsNotEmpty,
4+
IsOptional,
5+
IsString,
6+
IsUrl,
7+
} from 'class-validator';
8+
9+
export class CreateUserDto {
10+
@IsEmail()
11+
@IsNotEmpty()
12+
email: string;
13+
14+
@IsString()
15+
@IsNotEmpty()
16+
name: string;
17+
18+
@IsOptional()
19+
@IsUrl()
20+
avatarLink?: string;
21+
22+
@IsOptional()
23+
@IsString()
24+
passwordHash?: string;
25+
26+
@IsString()
27+
@IsNotEmpty()
28+
function: string;
29+
30+
@IsOptional()
31+
@IsString()
32+
role?: string;
33+
34+
@IsOptional()
35+
@IsString()
36+
description?: string;
37+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { PartialType } from '@nestjs/mapped-types';
2+
import { CreateUserDto } from './create-user.dto';
3+
4+
export class UpdateUserDto extends PartialType(CreateUserDto) {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { PipeTransform, Injectable, BadRequestException } from '@nestjs/common';
2+
import { isNumber } from 'class-validator';
3+
4+
@Injectable()
5+
export class ParseIdPipe implements PipeTransform {
6+
transform(value: number) {
7+
if (!isNumber(value)) {
8+
throw new BadRequestException('ID invalid!');
9+
}
10+
11+
return value;
12+
}
13+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Test, TestingModule } from '@nestjs/testing';
2+
import { UsersController } from './users.controller';
3+
4+
describe('UsersController', () => {
5+
let controller: UsersController;
6+
7+
beforeEach(async () => {
8+
const module: TestingModule = await Test.createTestingModule({
9+
controllers: [UsersController],
10+
}).compile();
11+
12+
controller = module.get<UsersController>(UsersController);
13+
});
14+
15+
it('should be defined', () => {
16+
expect(controller).toBeDefined();
17+
});
18+
});
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {
2+
Body,
3+
Controller,
4+
Delete,
5+
Get,
6+
Param,
7+
Patch,
8+
Post,
9+
} from '@nestjs/common';
10+
import { UsersService } from './users.service';
11+
import { CreateUserDto } from './dto/create-user.dto';
12+
import { ParseIdPipe } from './pipes/parse-id.pipe';
13+
import { UpdateUserDto } from './dto/update-user.dto';
14+
15+
@Controller('users')
16+
export class UsersController {
17+
constructor(private userService: UsersService) {}
18+
19+
@Post()
20+
create(@Body() dto: CreateUserDto) {
21+
return this.userService.create(dto);
22+
}
23+
24+
@Get()
25+
findAll() {
26+
return this.userService.findAll();
27+
}
28+
29+
@Get(':id')
30+
findOne(@Param('id', ParseIdPipe) id: number) {
31+
return this.userService.findOne(id);
32+
}
33+
34+
@Patch(':id')
35+
update(@Param('id', ParseIdPipe) id: number, @Body() dto: UpdateUserDto) {
36+
return this.userService.update(id, dto);
37+
}
38+
39+
@Delete(':id')
40+
remove(@Param('id', ParseIdPipe) id: number) {
41+
return this.userService.remove(id);
42+
}
43+
}

src/modules/users/users.module.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Module } from '@nestjs/common';
2+
import { UsersController } from './users.controller';
3+
import { UsersService } from './users.service';
4+
import { PrismaService } from 'src/prisma.service';
5+
6+
@Module({
7+
controllers: [UsersController],
8+
providers: [UsersService, PrismaService],
9+
})
10+
export class UsersModule {}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Test, TestingModule } from '@nestjs/testing';
2+
import { UsersService } from './users.service';
3+
4+
describe('UsersService', () => {
5+
let service: UsersService;
6+
7+
beforeEach(async () => {
8+
const module: TestingModule = await Test.createTestingModule({
9+
providers: [UsersService],
10+
}).compile();
11+
12+
service = module.get<UsersService>(UsersService);
13+
});
14+
15+
it('should be defined', () => {
16+
expect(service).toBeDefined();
17+
});
18+
});

0 commit comments

Comments
 (0)