1번째 수정..
This commit is contained in:
parent
e63763500a
commit
2d0c7b38f2
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "prisma-todo-app",
|
"name": "nestjs_backend",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "prisma-todo-app",
|
"name": "nestjs_backend",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "prisma-todo-app",
|
"name": "nestjs_backend",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"description": "",
|
"description": "",
|
||||||
"author": "",
|
"author": "",
|
||||||
@ -76,5 +76,8 @@
|
|||||||
],
|
],
|
||||||
"coverageDirectory": "../coverage",
|
"coverageDirectory": "../coverage",
|
||||||
"testEnvironment": "node"
|
"testEnvironment": "node"
|
||||||
|
},
|
||||||
|
"prisma": {
|
||||||
|
"seed": "ts-node prisma/seed.ts"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
132
prisma/seed.ts
Normal file
132
prisma/seed.ts
Normal file
@ -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()
|
||||||
|
})
|
||||||
@ -1,13 +1,13 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common'
|
||||||
import { AppController } from './app.controller';
|
import { AppController } from './app.controller'
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service'
|
||||||
import { TodoModule } from './todo/todo.module';
|
import { TodoModule } from './todo/todo.module'
|
||||||
import { AuthModule } from './auth/auth.module';
|
import { AuthModule } from './auth/auth.module'
|
||||||
import { UsersModule } from './user/user.module';
|
import { UsersModule } from './user/user.module'
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [AuthModule, UsersModule, TodoModule],
|
imports: [AuthModule, UsersModule, TodoModule],
|
||||||
//controllers: [AppController],
|
controllers: [AppController],
|
||||||
providers: [AppService],
|
providers: [AppService]
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
import { Controller, Get, Post, Request, UseGuards } from '@nestjs/common';
|
import { Controller, Get, Post, Request, UseGuards } from '@nestjs/common'
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service'
|
||||||
import { JwtAuthGuard } from './guards/jwt.authguard';
|
import { JwtAuthGuard } from './guards/jwt.authguard'
|
||||||
import { LocalAuthGuard } from './guards/local-auth.guard';
|
import { LocalAuthGuard } from './guards/local-auth.guard'
|
||||||
|
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
constructor(private authService: AuthService) { }
|
constructor(private authService: AuthService) {}
|
||||||
|
|
||||||
//local.strategy.ts 사용
|
//local.strategy.ts 사용
|
||||||
// @UseGuards(AuthGuard('local'))
|
// @UseGuards(AuthGuard('local'))
|
||||||
// @UseGuards(LocalAuthGuard)
|
// @UseGuards(LocalAuthGuard)
|
||||||
// @Post('login')
|
// @Post('login')
|
||||||
// async login(@Request() req) {
|
// async login(@Request() req) {
|
||||||
// return this.authService.login(req.user);
|
// return req.user
|
||||||
// }
|
// }
|
||||||
|
|
||||||
//Login용
|
//Login용
|
||||||
@ -20,13 +20,13 @@ export class AuthController {
|
|||||||
@UseGuards(LocalAuthGuard)
|
@UseGuards(LocalAuthGuard)
|
||||||
@Post('login')
|
@Post('login')
|
||||||
async login(@Request() req) {
|
async login(@Request() req) {
|
||||||
return this.authService.login(req.user);
|
return this.authService.login(req.user)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Login여부 확인용
|
//Login여부 확인용
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Get('islogin')
|
@Get('islogin')
|
||||||
getProfile(@Request() req) {
|
getProfile(@Request() req) {
|
||||||
return req.user;
|
return req.user
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,12 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async login(user: any) {
|
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) }
|
return { access_token: this.jwtService.sign(payload) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { ExtractJwt, Strategy } from 'passport-jwt';
|
import { ExtractJwt, Strategy } from 'passport-jwt'
|
||||||
import { PassportStrategy } from '@nestjs/passport';
|
import { PassportStrategy } from '@nestjs/passport'
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common'
|
||||||
import { jwtConstants } from './constants';
|
import { jwtConstants } from './constants'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class JwtStrategy extends PassportStrategy(Strategy) {
|
export class JwtStrategy extends PassportStrategy(Strategy) {
|
||||||
@ -9,11 +9,16 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
|
|||||||
super({
|
super({
|
||||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||||
ignoreExpiration: false,
|
ignoreExpiration: false,
|
||||||
secretOrKey: jwtConstants.secret,
|
secretOrKey: jwtConstants.secret
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async validate(payload: any) {
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,19 +1,21 @@
|
|||||||
import { Strategy } from 'passport-local';
|
import { Strategy } from 'passport-local'
|
||||||
import { PassportStrategy } from '@nestjs/passport';
|
import { PassportStrategy } from '@nestjs/passport'
|
||||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
import { Injectable, UnauthorizedException } from '@nestjs/common'
|
||||||
import { AuthService } from 'src/auth/auth.service';
|
import { AuthService } from 'src/auth/auth.service'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LocalStrategy extends PassportStrategy(Strategy) {
|
export class LocalStrategy extends PassportStrategy(Strategy) {
|
||||||
constructor(private authService: AuthService) {
|
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<any> {
|
async validate(email: string, password: string): Promise<any> {
|
||||||
const user = await this.authService.validateUser(username, password);
|
const user = await this.authService.validateUser(email, password)
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new UnauthorizedException();
|
throw new UnauthorizedException()
|
||||||
}
|
}
|
||||||
return user;
|
return user
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,14 +17,16 @@ export class TodoController {
|
|||||||
constructor(private readonly todoService: TodoService) {}
|
constructor(private readonly todoService: TodoService) {}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
async fetchAll(
|
async fetchAll(@Query() query): Promise<Todo[]> {
|
||||||
@Query() queries: { page?: number; per_page?: number }
|
const sql = {
|
||||||
): Promise<Todo[]> {
|
take: isNaN(query.per_page) ? 20 : Number(query.per_page),
|
||||||
queries.per_page = isNaN(queries.per_page) ? 20 : Number(queries.per_page)
|
skip: isNaN(query.page) ? 0 : Number(query.page) * query.per_page,
|
||||||
queries.page = isNaN(queries.page)
|
//where: { is_done: true },
|
||||||
? 0
|
orderBy: { id: 'desc' }
|
||||||
: Number(queries.page) * queries.per_page
|
}
|
||||||
return this.todoService.fetchAll(queries)
|
//console.log(query)
|
||||||
|
//console.log(sql)
|
||||||
|
return this.todoService.fetchAll(sql)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
|
|||||||
@ -9,18 +9,8 @@ export class TodoService {
|
|||||||
|
|
||||||
//참고: https://intrepidgeeks.com/tutorial/05-instagram-clone-code-5-user-summary
|
//참고: https://intrepidgeeks.com/tutorial/05-instagram-clone-code-5-user-summary
|
||||||
//전체조회
|
//전체조회
|
||||||
async fetchAll(params: {
|
async fetchAll(sql: any): Promise<Todo[]> {
|
||||||
page?: number
|
return this.prismaService.todo.findMany(sql)
|
||||||
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' }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//단일 조회
|
//단일 조회
|
||||||
|
|||||||
@ -17,14 +17,16 @@ export class UserController {
|
|||||||
constructor(private readonly userService: UserService) {}
|
constructor(private readonly userService: UserService) {}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
async fetchAll(
|
async fetchAll(@Query() query): Promise<User[]> {
|
||||||
@Query() queries: { page?: number; per_page?: number }
|
const sql = {
|
||||||
): Promise<User[]> {
|
take: isNaN(query.per_page) ? 20 : Number(query.per_page),
|
||||||
queries.per_page = isNaN(queries.per_page) ? 20 : Number(queries.per_page)
|
skip: isNaN(query.page) ? 0 : Number(query.page) * query.per_page,
|
||||||
queries.page = isNaN(queries.page)
|
//where: { is_done: true },
|
||||||
? 0
|
orderBy: { id: 'desc' }
|
||||||
: Number(queries.page) * queries.per_page
|
}
|
||||||
return this.userService.fetchAll(queries)
|
//console.log(query)
|
||||||
|
//console.log(sql)
|
||||||
|
return this.userService.fetchAll(sql)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
|
|||||||
@ -13,18 +13,8 @@ export class UserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//전체조회
|
//전체조회
|
||||||
async fetchAll(params: {
|
async fetchAll(sql: any): Promise<User[]> {
|
||||||
page?: number
|
return this.prismaService.user.findMany(sql)
|
||||||
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' }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//단일 조회
|
//단일 조회
|
||||||
|
|||||||
@ -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)
|
|
||||||
})
|
|
||||||
@ -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)
|
|
||||||
})
|
|
||||||
Loading…
Reference in New Issue
Block a user