Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4주차] 기본과제+도전과제? 제출 #4

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

.DS_Store
node_modules
dist
.env
.vscode
3 changes: 3 additions & 0 deletions 4th_221105_seminar(advanced)/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
# Keep environment variables out of version control
.env
33 changes: 33 additions & 0 deletions 4th_221105_seminar(advanced)/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "seminar3-netflix(seminar4-advanced-assignment)",
"version": "1.0.0",
"description": "마수리남 넷플릭스 페이지를 설계",
"main": "index.js",
"author": "수화수화수화",
"license": "MIT",
"scripts": {
"dev": "nodemon",
"build": "tsc && node dist"
},
"devDependencies": {
"@types/express": "^4.17.14",
"@types/node": "^18.11.2",
"express": "^4.18.2",
"nodemon": "^2.0.20"
},
"nodemonConfig": {
"watch": [
"src",
".env"
],
"ext": "js,ts,json",
"ignore": [
"src/**/*.spec.ts"
],
"exec": "ts-node --transpile-only ./src/index.ts"
},
"dependencies": {
"@prisma/client": "^4.6.1",
"prisma": "^4.6.1"
}
}
51 changes: 51 additions & 0 deletions 4th_221105_seminar(advanced)/prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

model Like {
id Int @id @default(autoincrement())
user_id Int
media_id Int
Media Media @relation(fields: [media_id], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "like_media_id_fk")
User User @relation(fields: [user_id], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "like_user_id_fk")
}

model Media {
id Int @id @unique @default(autoincrement())
title String @unique @db.VarChar(400)
thumbnail String? @db.VarChar(1000)
length Int
quality String @db.VarChar(50)
seriesNum Int
age Int?
createYear Int
actors String?
genre String
character String @db.VarChar(300)
summary String @db.VarChar(1000)
Like Like[]
current_time current_time[]
}

model User {
id Int @id @unique @default(autoincrement())
userName String
age Int @default(5)
email String? @db.VarChar(400)
Like Like[]
current_time current_time[]
}

model current_time {
id Int @id @default(autoincrement())
user_id Int
media_id Int
current_time Int
Media Media @relation(fields: [media_id], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "current_time_media_id_fk")
User User @relation(fields: [user_id], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "current_time_user_id_fk")
}
1 change: 1 addition & 0 deletions 4th_221105_seminar(advanced)/src/controller/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as mediaController} from "./mediaController";
197 changes: 197 additions & 0 deletions 4th_221105_seminar(advanced)/src/controller/mediaController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
import { Request, Response } from "express";
import { detailInter } from "../interface/detailInter";
import { mediaService } from "../service";
import { Prisma, PrismaClient } from "@prisma/client";

//CRUD


//C : 넷플릭에 미디어 컨텐츠 추가
const createMedia = async (req : Request, res : Response) => {
const { title, thumbnail, length,
quality, seriesNum, actors, createYear,
age, genre, character, summary} = req.body;

//예외 1 : 필요한 정보(title, length, quality ~ summary)가 안들어왔을때
if ( !title || !length || !quality
|| !seriesNum || ! actors || !createYear
|| !age || !genre || !character || !summary){
return res.status(400).json({
status : 400,
message : "컨텐츠를 추가하기위한 정보가 부족하다."
})

}

const mediaInfo : detailInter = {
title : title,
mediaInfo : {
thumbnail : thumbnail,
length : +length,
quality : quality,
seriesNum : +seriesNum,
age : +age
},
contentInfo : {
createYear : createYear,
actors : actors,
genre : genre,
character : character,
summary : summary
}
}

const createdMedia = await mediaService.createMedia( mediaInfo);
//예외 2 : 같은 이름의 컨텐츠가 있음

if (!createdMedia || createdMedia instanceof Prisma.PrismaClientKnownRequestError){
return res.status(409).json({
status : 409,
message : `해당 ${title} 컨텐츠는 이미 존재합니다.`
});
}
//성공 : 잘 만들어짐
return res.status(201).json({
status : 200,
message : "만들기ok",
data : createdMedia
})
}

//R
// 전체 미디어 목록 조회
const getAllMedia = async (req : Request, res : Response) => {
const mediaList = await mediaService.getAllMedia();

return res.status(200).json({
status : 200,
message : "전체조회ok",
data : mediaList
})

}

// 미디어 목록 하나조회 - detail
const getMediaDetail = async (req : Request, res : Response) => {
const { mediaId } = req.params;

// 예외 1. 미디어 아이디 오류
if (!mediaId || isNaN(+mediaId)){
return res.status(400).json({
status : 400,
message : `${mediaId}는 유요한 아이디가 아닙니다.`
})
}

const mediaDetail = await mediaService.getMediaDetail(+mediaId);

//예외 2. 해당 미디어 아이디가 없는경우
if (!mediaDetail || mediaDetail instanceof Prisma.PrismaClientKnownRequestError){
return res.status(400).json({
status : 400,
message : `조회 실패 : 아이디 ${mediaId}의 데이터가 없습니다.`,
})
}
return res.status(400).json({
status : 400,
message : `${mediaId}하나조회ok`,
data : mediaDetail
})

}

// U : 미디어 컨텐츠 정보 변경

const updateMedia = async (req : Request, res : Response) => {
const { mediaId } = req.params;
const { thumbnail, length,
quality, seriesNum, actors, createYear,
age, genre, character, summary} = req.body;

// 예외 1. 미디어 아이디 오류
if (!mediaId || isNaN(+mediaId)){
return res.status(400).json({
status : 400,
message : `${mediaId}는 유요한 아이디가 아닙니다.`
})
}
const mediaInfo : detailInter = {
title : "",
mediaInfo : {
thumbnail : thumbnail,
length : +length,
quality : quality,
seriesNum : +seriesNum,
age : +age
},
contentInfo : {
createYear : createYear,
actors : actors,
genre : genre,
character : character,
summary : summary
}
}

const updatedMedia= await mediaService.updateMedia(mediaInfo , +mediaId);

//예외2 : 해당 미디어 아이디의 데이터가 없는경우
if (!updatedMedia || updatedMedia instanceof Prisma.PrismaClientKnownRequestError){
return res.status(400).json({
status : 400,
message : `업데이트실패 : 아이디 ${mediaId}의 데이터가 없습니다.`,
})
}
return res.status(200).json({
status : 200,
message : `아이디 ${mediaId } 업데이트ok`,
data : updatedMedia
})

}

// D : 미디어 정보 삭제
const deleteMedia = async (req : Request, res : Response) => {
const { mediaId } = req.params;

//미디어 아이디 오류
if (!mediaId || isNaN(+mediaId) ){
return res.status(400).json({
status : 400,
message : `삭제 실패 : 아이디 ${mediaId}가 유효하지 않습니다.`,
})

}

const deletedMedia = await mediaService.deleteMedia(+mediaId);

//미디어 삭제할 데이터가 없을때
if(!deletedMedia || deletedMedia instanceof Prisma.PrismaClientKnownRequestError ){
return res.status(400).json({
status : 400,
message : `삭제 실패 : 아이디 ${mediaId}의 데이터가 없습니다.`,
});
}
else{
return res.status(200).json({
status : 200,
message : `${mediaId}삭제ok`,
data : deletedMedia
});
}


}

const mediaController={
createMedia,
getAllMedia,
getMediaDetail,
updateMedia,
deleteMedia

};

export default mediaController;


20 changes: 20 additions & 0 deletions 4th_221105_seminar(advanced)/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import express, { NextFunction, Request, Response } from "express";
import router from "./router";

const app = express();
const PORT = 3000;

app.use(express.json());

app.use("/", router);

app.get("/",(req : Request, res : Response, next : NextFunction)=>{
res.send("~~~~~서버서버서버~~~~~");
});

app.listen(PORT,()=>{
console.log(`*****************************************
${PORT}번 포트에서 듣고 있는 중~~*
********************************************`);

});
21 changes: 21 additions & 0 deletions 4th_221105_seminar(advanced)/src/interface/detailInter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export interface detailInter{
title: string,
mediaInfo : {
thumbnail ?: string,
length : number,
quality : string,
seriesNum : number,
age : number
},
contentInfo : {
createYear: number,
actors : string,
genre : string,
character : string,
summary : string
},
userInfo ? : {
currentTime : number,
isLike : boolean
}
}
14 changes: 14 additions & 0 deletions 4th_221105_seminar(advanced)/src/router/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Router } from "express";
import mediaRouter from "./mediaRouter";


const router : Router = Router();

router.use("/media",mediaRouter);


export default router;




25 changes: 25 additions & 0 deletions 4th_221105_seminar(advanced)/src/router/mediaRouter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Router, Request, Response } from "express";
import { mediaController } from '../controller';

const mediaRouter : Router = Router();
//CRUD

//C : 넷플릭에 미디어 컨텐츠 추가
mediaRouter.post("/",mediaController.createMedia);
//R
// 전체 미디어 목록 조회
mediaRouter.get("/",mediaController.getAllMedia);

// 미디어 목록 하나조회 - detail
mediaRouter.get("/:mediaId/detail",mediaController.getMediaDetail);

// U : 미디어 컨텐츠 정보 변경
mediaRouter.patch("/:mediaId",mediaController.updateMedia);

// D : 미디어 정보 삭제
mediaRouter.delete("/:mediaId",mediaController.deleteMedia);




export default mediaRouter;
1 change: 1 addition & 0 deletions 4th_221105_seminar(advanced)/src/service/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as mediaService} from "./mediaService";
Loading