diff --git a/package-lock.json b/package-lock.json index b172b7f..3cc3e69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "prisma-todo-app", + "name": "nestjs_backend", "version": "0.0.1", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "prisma-todo-app", + "name": "nestjs_backend", "version": "0.0.1", "license": "UNLICENSED", "dependencies": { diff --git a/package.json b/package.json index 1128289..bb61e33 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "prisma-todo-app", + "name": "nestjs_backend", "version": "0.0.1", "description": "", "author": "", @@ -76,5 +76,8 @@ ], "coverageDirectory": "../coverage", "testEnvironment": "node" + }, + "prisma": { + "seed": "ts-node prisma/seed.ts" } } diff --git a/prisma/seed.ts b/prisma/seed.ts new file mode 100644 index 0000000..8013d32 --- /dev/null +++ b/prisma/seed.ts @@ -0,0 +1,132 @@ +import { Prisma, PrismaClient } from '@prisma/client' + +const prisma = new PrismaClient() + +//필요 설치 : npm install -D typescript ts-node @types/node +//Project 디렉토리에서 실행: npx prisma db seed +const userDatas: Prisma.UserCreateInput[] = [ + { + email: 'choi.jh@idcjp.jp', + name: '최준흠', + password: '1234', + role: 'ADMIN' + }, + { + email: 'user1@idcjp.jp', + name: '사용자1', + password: '1234', + role: 'USER' + }, + { + email: 'user2@idcjp.jp', + name: '사용자2', + password: '1234', + role: 'USER' + }, + { + email: 'user3@idcjp.jp', + name: '사용자3', + password: '1234', + role: 'USER' + } +] + +const transferUser = async () => { + const users = [] + for (const userData of userDatas) { + const user = prisma.user.create({ data: userData }) + users.push(user) + } + return await prisma.$transaction(users) +} + +const todoDatas: Prisma.TodoCreateInput[] = [ + { + title: '타이틀_1', + content: '내용_1' + }, + { + title: '타이틀_2', + content: '내용_2' + }, + { + title: '타이틀_3', + content: '내용_3' + }, + { + title: '타이틀_4', + content: '내용_4' + }, + { + title: '타이틀_5', + content: '내용_5' + }, + { + title: '타이틀_6', + content: '내용_6' + }, + { + title: '타이틀_7', + content: '내용_7' + }, + { + title: '타이틀_8', + content: '내용_8' + }, + { + title: '타이틀_9', + content: '내용_9' + }, + { + title: '타이틀_10', + content: '내용_10' + }, + { + title: '타이틀_11', + content: '내용_11' + }, + { + title: '타이틀_12', + content: '내용_12' + }, + { + title: '타이틀_13', + content: '내용_13' + }, + { + title: '타이틀_14', + content: '내용_14' + }, + { + title: '타이틀_15', + content: '내용_15' + } +] + +const transferTodo = async () => { + const todos = [] + for (const todoData of todoDatas) { + const todo = prisma.todo.create({ data: todoData }) + todos.push(todo) + } + return await prisma.$transaction(todos) +} + +const main = async () => { + console.log(`Start User seeding ...`) + await transferUser() + console.log(`Seeding User finished.`) + + console.log(`Start Todo seeding ...`) + await transferTodo() + console.log(`Seeding Todo finished.`) +} + +main() + .catch((e) => { + console.error(e) + process.exit(1) + }) + .finally(async () => { + await prisma.$disconnect() + }) diff --git a/src/app.module.ts b/src/app.module.ts index d773b51..f484ca3 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,13 +1,13 @@ -import { Module } from '@nestjs/common'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; -import { TodoModule } from './todo/todo.module'; -import { AuthModule } from './auth/auth.module'; -import { UsersModule } from './user/user.module'; +import { Module } from '@nestjs/common' +import { AppController } from './app.controller' +import { AppService } from './app.service' +import { TodoModule } from './todo/todo.module' +import { AuthModule } from './auth/auth.module' +import { UsersModule } from './user/user.module' @Module({ imports: [AuthModule, UsersModule, TodoModule], - //controllers: [AppController], - providers: [AppService], + controllers: [AppController], + providers: [AppService] }) export class AppModule {} diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index 679cb16..af11c0c 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -1,18 +1,18 @@ -import { Controller, Get, Post, Request, UseGuards } from '@nestjs/common'; -import { AuthService } from './auth.service'; -import { JwtAuthGuard } from './guards/jwt.authguard'; -import { LocalAuthGuard } from './guards/local-auth.guard'; +import { Controller, Get, Post, Request, UseGuards } from '@nestjs/common' +import { AuthService } from './auth.service' +import { JwtAuthGuard } from './guards/jwt.authguard' +import { LocalAuthGuard } from './guards/local-auth.guard' @Controller('auth') export class AuthController { - constructor(private authService: AuthService) { } - + constructor(private authService: AuthService) {} + //local.strategy.ts 사용 // @UseGuards(AuthGuard('local')) // @UseGuards(LocalAuthGuard) // @Post('login') // async login(@Request() req) { - // return this.authService.login(req.user); + // return req.user // } //Login용 @@ -20,13 +20,13 @@ export class AuthController { @UseGuards(LocalAuthGuard) @Post('login') async login(@Request() req) { - return this.authService.login(req.user); + return this.authService.login(req.user) } //Login여부 확인용 @UseGuards(JwtAuthGuard) @Get('islogin') getProfile(@Request() req) { - return req.user; + return req.user } } diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index f9b6586..03201b6 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -21,7 +21,12 @@ export class AuthService { } async login(user: any) { - const payload = { id: user.id, username: user.username, role: user.role } + const payload = { + id: user.id, + email: user.email, + name: user.name, + role: user.role + } return { access_token: this.jwtService.sign(payload) } } } diff --git a/src/auth/guards/jwt.strategy.ts b/src/auth/guards/jwt.strategy.ts index 452e997..7e809c0 100644 --- a/src/auth/guards/jwt.strategy.ts +++ b/src/auth/guards/jwt.strategy.ts @@ -1,7 +1,7 @@ -import { ExtractJwt, Strategy } from 'passport-jwt'; -import { PassportStrategy } from '@nestjs/passport'; -import { Injectable } from '@nestjs/common'; -import { jwtConstants } from './constants'; +import { ExtractJwt, Strategy } from 'passport-jwt' +import { PassportStrategy } from '@nestjs/passport' +import { Injectable } from '@nestjs/common' +import { jwtConstants } from './constants' @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { @@ -9,11 +9,16 @@ export class JwtStrategy extends PassportStrategy(Strategy) { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), ignoreExpiration: false, - secretOrKey: jwtConstants.secret, - }); + secretOrKey: jwtConstants.secret + }) } async validate(payload: any) { - return { id: payload.id, username: payload.username, role: payload.role }; + return { + id: payload.id, + email: payload.email, + name: payload.name, + role: payload.role + } } -} \ No newline at end of file +} diff --git a/src/auth/guards/local.strategy.ts b/src/auth/guards/local.strategy.ts index 8f76d69..d17d5bf 100644 --- a/src/auth/guards/local.strategy.ts +++ b/src/auth/guards/local.strategy.ts @@ -1,19 +1,21 @@ -import { Strategy } from 'passport-local'; -import { PassportStrategy } from '@nestjs/passport'; -import { Injectable, UnauthorizedException } from '@nestjs/common'; -import { AuthService } from 'src/auth/auth.service'; +import { Strategy } from 'passport-local' +import { PassportStrategy } from '@nestjs/passport' +import { Injectable, UnauthorizedException } from '@nestjs/common' +import { AuthService } from 'src/auth/auth.service' @Injectable() export class LocalStrategy extends PassportStrategy(Strategy) { constructor(private authService: AuthService) { - super(); + //super() + //If you want to check user authenticate with custom column like 'email', try pass it. + super({ usernameField: 'email' }) } - async validate(username: string, password: string): Promise { - const user = await this.authService.validateUser(username, password); + async validate(email: string, password: string): Promise { + const user = await this.authService.validateUser(email, password) if (!user) { - throw new UnauthorizedException(); + throw new UnauthorizedException() } - return user; + return user } } diff --git a/src/todo/todo.controller.ts b/src/todo/todo.controller.ts index ddee226..6b7831d 100644 --- a/src/todo/todo.controller.ts +++ b/src/todo/todo.controller.ts @@ -17,14 +17,16 @@ export class TodoController { constructor(private readonly todoService: TodoService) {} @Get() - async fetchAll( - @Query() queries: { page?: number; per_page?: number } - ): Promise { - queries.per_page = isNaN(queries.per_page) ? 20 : Number(queries.per_page) - queries.page = isNaN(queries.page) - ? 0 - : Number(queries.page) * queries.per_page - return this.todoService.fetchAll(queries) + async fetchAll(@Query() query): Promise { + const sql = { + take: isNaN(query.per_page) ? 20 : Number(query.per_page), + skip: isNaN(query.page) ? 0 : Number(query.page) * query.per_page, + //where: { is_done: true }, + orderBy: { id: 'desc' } + } + //console.log(query) + //console.log(sql) + return this.todoService.fetchAll(sql) } @Get(':id') diff --git a/src/todo/todo.service.ts b/src/todo/todo.service.ts index 1e883eb..74f746b 100644 --- a/src/todo/todo.service.ts +++ b/src/todo/todo.service.ts @@ -9,18 +9,8 @@ export class TodoService { //참고: https://intrepidgeeks.com/tutorial/05-instagram-clone-code-5-user-summary //전체조회 - async fetchAll(params: { - page?: number - per_page?: number - }): Promise { - const { page, per_page } = params - - return this.prismaService.todo.findMany({ - skip: page, - take: per_page, - //where: { is_done: true }, - orderBy: { id: 'desc' } - }) + async fetchAll(sql: any): Promise { + return this.prismaService.todo.findMany(sql) } //단일 조회 diff --git a/src/user/user.controller.ts b/src/user/user.controller.ts index ed921ae..430c612 100644 --- a/src/user/user.controller.ts +++ b/src/user/user.controller.ts @@ -17,14 +17,16 @@ export class UserController { constructor(private readonly userService: UserService) {} @Get() - async fetchAll( - @Query() queries: { page?: number; per_page?: number } - ): Promise { - queries.per_page = isNaN(queries.per_page) ? 20 : Number(queries.per_page) - queries.page = isNaN(queries.page) - ? 0 - : Number(queries.page) * queries.per_page - return this.userService.fetchAll(queries) + async fetchAll(@Query() query): Promise { + const sql = { + take: isNaN(query.per_page) ? 20 : Number(query.per_page), + skip: isNaN(query.page) ? 0 : Number(query.page) * query.per_page, + //where: { is_done: true }, + orderBy: { id: 'desc' } + } + //console.log(query) + //console.log(sql) + return this.userService.fetchAll(sql) } @Get(':id') diff --git a/src/user/user.service.ts b/src/user/user.service.ts index 3d311cd..2387d51 100644 --- a/src/user/user.service.ts +++ b/src/user/user.service.ts @@ -13,18 +13,8 @@ export class UserService { } //전체조회 - async fetchAll(params: { - page?: number - per_page?: number - }): Promise { - const { page, per_page } = params - - return this.prismaService.user.findMany({ - skip: page, - take: per_page, - //where: { is_done: true }, - orderBy: { id: 'desc' } - }) + async fetchAll(sql: any): Promise { + return this.prismaService.user.findMany(sql) } //단일 조회 diff --git a/test/init_todo.ts b/test/init_todo.ts deleted file mode 100644 index 0657b67..0000000 --- a/test/init_todo.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { Prisma, PrismaClient } from '@prisma/client' - -const prisma = new PrismaClient() - -//실행 방법: npx ts-node scripts.ts -async function main() { - let todos: Prisma.TodoCreateInput[] = [ - { - title: '타이틀_1', - content: '내용_1' - }, - { - title: '타이틀_2', - content: '내용_2' - }, - { - title: '타이틀_3', - content: '내용_3' - }, - { - title: '타이틀_4', - content: '내용_4' - }, - { - title: '타이틀_5', - content: '내용_5' - }, - { - title: '타이틀_6', - content: '내용_6' - }, - { - title: '타이틀_7', - content: '내용_7' - }, - { - title: '타이틀_8', - content: '내용_8' - }, - { - title: '타이틀_9', - content: '내용_9' - }, - { - title: '타이틀_10', - content: '내용_10' - }, - { - title: '타이틀_11', - content: '내용_11' - }, - { - title: '타이틀_12', - content: '내용_12' - }, - { - title: '타이틀_13', - content: '내용_13' - }, - { - title: '타이틀_14', - content: '내용_14' - }, - { - title: '타이틀_15', - content: '내용_15' - } - ] - - await Promise.all( - todos.map(async (todo) => { - await prisma.todo.create({ data: todo }) - }) - ) -} - -main() - .then(async () => { - await prisma.$disconnect() - }) - .catch(async (e) => { - console.error(e) - await prisma.$disconnect() - process.exit(1) - }) diff --git a/test/init_user.ts b/test/init_user.ts deleted file mode 100644 index bb8677b..0000000 --- a/test/init_user.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Prisma, PrismaClient } from '@prisma/client' - -const prisma = new PrismaClient() - -//실행 방법: npx ts-node scripts.ts -async function main() { - let users: Prisma.UserCreateInput[] = [ - { - email: 'choi.jh@idcjp.jp', - name: '최준흠', - password: '1234', - role: 'ADMIN' - }, - { - email: 'user1@idcjp.jp', - name: '사용자1', - password: '1234', - role: 'USER' - }, - { - email: 'user2@idcjp.jp', - name: '사용자2', - password: '1234', - role: 'USER' - }, - { - email: 'user3@idcjp.jp', - name: '사용자3', - password: '1234', - role: 'USER' - } - ] - - await Promise.all( - users.map(async (user) => { - await prisma.user.create({ data: user }) - }) - ) -} - -main() - .then(async () => { - await prisma.$disconnect() - }) - .catch(async (e) => { - console.error(e) - await prisma.$disconnect() - process.exit(1) - })