1번째 수정..

This commit is contained in:
최준흠 2022-08-17 16:57:03 +09:00
parent 4558da3cda
commit e63763500a
14 changed files with 278 additions and 101 deletions

View File

@ -1,4 +1,8 @@
{ {
"semi": false,
"bracketSapcing": true,
"singleQuote": true, "singleQuote": true,
"trailingComma": "all" "useTabs": false,
"trailingComma": "none",
"printWith": 80
} }

View File

@ -1,9 +0,0 @@
-- CreateTable
CREATE TABLE `Todo` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`title` VARCHAR(191) NOT NULL,
`content` VARCHAR(191) NULL,
`is_don` BOOLEAN NULL DEFAULT false,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

View File

@ -1,19 +0,0 @@
/*
Warnings:
- You are about to drop the column `is_don` on the `todo` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE `todo` DROP COLUMN `is_don`,
ADD COLUMN `is_done` BOOLEAN NULL DEFAULT false;
-- CreateTable
CREATE TABLE `User` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`username` VARCHAR(191) NOT NULL,
`password` VARCHAR(191) NOT NULL,
`is_done` BOOLEAN NULL DEFAULT false,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

View File

@ -1,2 +0,0 @@
-- AlterTable
ALTER TABLE `user` ADD COLUMN `role` VARCHAR(191) NULL DEFAULT 'user';

View File

@ -0,0 +1,26 @@
-- CreateTable
CREATE TABLE `User` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`email` VARCHAR(191) NOT NULL,
`password` VARCHAR(191) NOT NULL,
`name` VARCHAR(191) NOT NULL,
`role` VARCHAR(191) NOT NULL DEFAULT 'USER',
`is_done` BOOLEAN NULL DEFAULT false,
`updatedAt` TIMESTAMP(0) NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
UNIQUE INDEX `User_email_key`(`email`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Todo` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`title` VARCHAR(191) NOT NULL,
`content` VARCHAR(191) NULL,
`is_done` BOOLEAN NULL DEFAULT false,
`updatedAt` TIMESTAMP(0) NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

View File

@ -3,6 +3,7 @@
generator client { generator client {
provider = "prisma-client-js" provider = "prisma-client-js"
previewFeatures = ["interactiveTransactions"]
} }
//데이터베이스 연동 //데이터베이스 연동
@ -11,18 +12,23 @@ datasource db {
url = env("DATABASE_URL") url = env("DATABASE_URL")
} }
model User {
id Int @id @default(autoincrement())
email String @unique
password String
name String
role String @default("USER")
is_done Boolean? @default(false)
updatedAt DateTime? @db.Timestamp(0)
createdAt DateTime @default(now())
}
//만들려는 모델 //만들려는 모델
model Todo { model Todo {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
title String title String
content String? content String?
is_done Boolean? @default(false) is_done Boolean? @default(false)
} updatedAt DateTime? @db.Timestamp(0)
createdAt DateTime @default(now())
model User {
id Int @id @default(autoincrement())
username String
password String
role String? @default("user")
is_done Boolean? @default(false)
} }

View File

@ -1,27 +1,27 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common'
import { UserService } from 'src/user/user.service'; import { UserService } from 'src/user/user.service'
import { JwtService } from '@nestjs/jwt'; import { JwtService } from '@nestjs/jwt'
@Injectable() @Injectable()
export class AuthService { export class AuthService {
constructor( constructor(
private userService: UserService, private userService: UserService,
private jwtService: JwtService, private jwtService: JwtService
) {} ) {}
//app.controller.ts에서 @UseGuards(AuthGuard('local'))용 //app.controller.ts에서 @UseGuards(AuthGuard('local'))용
async validateUser(username: string, password: string): Promise<any> { async validateUser(email: string, password: string): Promise<any> {
const user = await this.userService.findOne(username); const user = await this.userService.fetchOneByEmail(email)
if (user && user.password === password) { if (user && user.password === password) {
const { password, ...result } = user; const { password, ...result } = user
// result는 password 를 제외한 user의 모든 정보를 포함한다. // result는 password 를 제외한 user의 모든 정보를 포함한다.
return result; return result
} }
return null; return null
} }
async login(user: any) { async login(user: any) {
const payload = { id: user.id, username: user.username, role: user.role }; const payload = { id: user.id, username: user.username, role: user.role }
return { access_token: this.jwtService.sign(payload) }; return { access_token: this.jwtService.sign(payload) }
} }
} }

View File

@ -6,37 +6,44 @@ import {
Param, Param,
Post, Post,
Put, Put,
} from '@nestjs/common'; Query
import { Todo } from '@prisma/client'; } from '@nestjs/common'
import { TodoDTO } from './dtos/todo.dto'; import { Todo } from '@prisma/client'
import { TodoService } from './todo.service'; import { TodoDTO } from './dtos/todo.dto'
import { TodoService } from './todo.service'
@Controller('todo') @Controller('todo')
export class TodoController { export class TodoController {
constructor(private readonly todoService: TodoService) {} constructor(private readonly todoService: TodoService) {}
@Get() @Get()
async fetchAll(): Promise<Todo[]> { async fetchAll(
return this.todoService.fetchAll(); @Query() queries: { page?: number; per_page?: number }
): Promise<Todo[]> {
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)
} }
@Get(':id') @Get(':id')
async fetchOne(@Param('id') id: number): Promise<Todo | undefined> { async fetchOne(@Param('id') id: number): Promise<Todo | undefined> {
return this.todoService.fetchOne(id); return this.todoService.fetchOne(id)
} }
@Delete(':id') @Delete(':id')
async delete(@Param('id') id: number): Promise<Todo | undefined> { async delete(@Param('id') id: number): Promise<Todo | undefined> {
return this.todoService.remove(id); return this.todoService.remove(id)
} }
@Post() @Post()
async add(@Body() data: Todo): Promise<Todo> { async add(@Body() data: Todo): Promise<Todo> {
return this.todoService.add(data); return this.todoService.add(data)
} }
@Put(':id') @Put(':id')
async update(@Param('id') id: number, @Body() data: TodoDTO): Promise<Todo> { async update(@Param('id') id: number, @Body() data: TodoDTO): Promise<Todo> {
return this.todoService.update(id, data); return this.todoService.update(id, data)
} }
} }

View File

@ -1,37 +1,48 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common'
import { Todo } from '@prisma/client'; import { Todo, Prisma } from '@prisma/client'
import { PrismaService } from 'src/prisma.service'; import { PrismaService } from 'src/prisma.service'
import { TodoDTO } from './dtos/todo.dto'; import { TodoDTO } from './dtos/todo.dto'
@Injectable() @Injectable()
export class TodoService { export class TodoService {
constructor(private prismaService: PrismaService) {} constructor(private prismaService: PrismaService) {}
//참고: https://intrepidgeeks.com/tutorial/05-instagram-clone-code-5-user-summary
//전체조회 //전체조회
async fetchAll(): Promise<Todo[]> { async fetchAll(params: {
return this.prismaService.todo.findMany(); page?: number
per_page?: number
}): Promise<Todo[]> {
const { page, per_page } = params
return this.prismaService.todo.findMany({
skip: page,
take: per_page,
//where: { is_done: true },
orderBy: { id: 'desc' }
})
} }
//단일 조회 //단일 조회
async fetchOne(id: number): Promise<Todo | undefined> { async fetchOne(id: number): Promise<Todo | undefined> {
return this.prismaService.todo.findUnique({ where: { id: Number(id) } }); return this.prismaService.todo.findUnique({ where: { id: Number(id) } })
} }
//단일 삭제 //단일 삭제
async remove(id: number): Promise<Todo | undefined> { async remove(id: number): Promise<Todo | undefined> {
return this.prismaService.todo.delete({ where: { id: Number(id) } }); return this.prismaService.todo.delete({ where: { id: Number(id) } })
} }
//단일 추가 //단일 추가
async add(data: Todo): Promise<Todo> { async add(data: Todo): Promise<Todo> {
return this.prismaService.todo.create({ data: data }); return this.prismaService.todo.create({ data: data })
} }
//단일 수정 //단일 수정
async update(id: number, data: TodoDTO): Promise<Todo | undefined> { async update(id: number, data: TodoDTO): Promise<Todo | undefined> {
return this.prismaService.todo.update({ return this.prismaService.todo.update({
where: { id: Number(id) }, where: { id: Number(id) },
data: data, data: data
}); })
} }
} }

View File

@ -1,6 +1,7 @@
export class UserDTO { export class UserDTO {
username: string; email: string
password: string; password: string
role: string; name: string
is_done: boolean; role: string
is_done: boolean
} }

View File

@ -6,37 +6,44 @@ import {
Param, Param,
Post, Post,
Put, Put,
} from '@nestjs/common'; Query
import { User } from '@prisma/client'; } from '@nestjs/common'
import { UserDTO } from './dtos/user.dto'; import { User } from '@prisma/client'
import { UserService } from './user.service'; import { UserDTO } from './dtos/user.dto'
import { UserService } from './user.service'
@Controller('user') @Controller('user')
export class UserController { export class UserController {
constructor(private readonly userService: UserService) {} constructor(private readonly userService: UserService) {}
@Get() @Get()
async fetchAll(): Promise<User[]> { async fetchAll(
return this.userService.fetchAll(); @Query() queries: { page?: number; per_page?: number }
): Promise<User[]> {
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)
} }
@Get(':id') @Get(':id')
async fetchOne(@Param('id') id: number): Promise<User | undefined> { async fetchOne(@Param('id') id: number): Promise<User | undefined> {
return this.userService.fetchOne(id); return this.userService.fetchOne(id)
} }
@Delete(':id') @Delete(':id')
async delete(@Param('id') id: number): Promise<User | undefined> { async delete(@Param('id') id: number): Promise<User | undefined> {
return this.userService.remove(id); return this.userService.remove(id)
} }
@Post() @Post()
async add(@Body() data: User): Promise<User> { async add(@Body() data: User): Promise<User> {
return this.userService.add(data); return this.userService.add(data)
} }
@Put(':id') @Put(':id')
async update(@Param('id') id: number, @Body() data: UserDTO): Promise<User> { async update(@Param('id') id: number, @Body() data: UserDTO): Promise<User> {
return this.userService.update(id, data); return this.userService.update(id, data)
} }
} }

View File

@ -1,41 +1,52 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common'
import { User } from '@prisma/client'; import { User } from '@prisma/client'
import { PrismaService } from 'src/prisma.service'; import { PrismaService } from 'src/prisma.service'
import { UserDTO } from './dtos/user.dto'; import { UserDTO } from './dtos/user.dto'
@Injectable() @Injectable()
export class UserService { export class UserService {
constructor(private prismaService: PrismaService) {} constructor(private prismaService: PrismaService) {}
async findOne(username: string): Promise<User | undefined> { //단일 조회 ByEmail
return this.prismaService.user.findFirst({ where: { username: username } }); async fetchOneByEmail(email: string): Promise<User | undefined> {
return this.prismaService.user.findUnique({ where: { email: email } })
} }
//전체조회 //전체조회
async fetchAll(): Promise<User[]> { async fetchAll(params: {
return this.prismaService.user.findMany(); page?: number
per_page?: number
}): Promise<User[]> {
const { page, per_page } = params
return this.prismaService.user.findMany({
skip: page,
take: per_page,
//where: { is_done: true },
orderBy: { id: 'desc' }
})
} }
//단일 조회 //단일 조회
async fetchOne(id: number): Promise<User | undefined> { async fetchOne(id: number): Promise<User | undefined> {
return this.prismaService.user.findUnique({ where: { id: Number(id) } }); return this.prismaService.user.findUnique({ where: { id: Number(id) } })
} }
//단일 삭제 //단일 삭제
async remove(id: number): Promise<User | undefined> { async remove(id: number): Promise<User | undefined> {
return this.prismaService.user.delete({ where: { id: Number(id) } }); return this.prismaService.user.delete({ where: { id: Number(id) } })
} }
//단일 추가 //단일 추가
async add(data: User): Promise<User> { async add(data: User): Promise<User> {
return this.prismaService.user.create({ data: data }); return this.prismaService.user.create({ data: data })
} }
//단일 수정 //단일 수정
async update(id: number, data: UserDTO): Promise<User | undefined> { async update(id: number, data: UserDTO): Promise<User | undefined> {
return this.prismaService.user.update({ return this.prismaService.user.update({
where: { id: Number(id) }, where: { id: Number(id) },
data: data, data: data
}); })
} }
} }

85
test/init_todo.ts Normal file
View File

@ -0,0 +1,85 @@
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)
})

49
test/init_user.ts Normal file
View File

@ -0,0 +1,49 @@
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)
})