π μλΉμ€λͺ : μ¨μ¬μ΄μ¦
π μλΉμ€ νμ€μκ° : μ½κ³ λλν λμ μΌν λμ°λ―Έ, μ¨μ¬μ΄μ¦
π μλΉμ€ κ°μΉμ μ :
- λ¨μν / Simple : λͺ λ²μ ν΄λ¦λ§μΌλ‘ μ¬μ΄μ¦λ₯Ό μΆμ²λ°κ³ λμ μ·μ₯μ μ μ₯ν΄μ
- κ°μΈνλ / Personalize : μ€λ‘μ§ λλ§μ κΈ°μ€μΌλ‘ μ·μ μΆμ²λ°κ³ λΆλ₯ν΄μ
- λλν / Smart : μ΅μ€ν μ μ ν΅ν΄ λ³΄λ€ λλνκ² μΌνν΄μ
π μλΉμ€ λ¬Έμ μ μ :
- μ¬μ΄μ¦ μ€ν¨λ‘ μΈν΄ λ°μνκ² λ νλΆ, κ΅ν, λ°μ‘μ λν μ€νΈλ μ€
- μ νν μ¬μ΄μ¦λ₯Ό κ³ λ₯΄κ³ μ λ€μν μ 보λ₯Ό μμ§νλ κ³Όμ μ λ²κ±°λ‘μ
π μλΉμ€ νκ²μ μ :
- ν¨μ μ κ΄μ¬μ΄ λ§μ μ¨λΌμΈμμ λ€μν μλ₯ λ° κ΄λ ¨μ 보λ₯Ό μ°Ύμ보며 ꡬ맀λ₯Ό κ²°μ νλ κ³ κ°
- μ¨λΌμΈμμμ μ¬μ΄μ¦ μ€ν¨ κ²½νμΌλ‘ μΈν΄ μ€νλΌμΈ μΌνμΌλ‘ μ νν κ³ κ°
κΉλμ¬ | μ‘°νμ |
ehdwoKIM | yanh2 |
κΈ°λ₯λͺ | μλν¬μΈνΈ | λ΄λΉ | μλ£ |
---|---|---|---|
νμκ°μ λ° λ‘κ·ΈμΈ | [POST] /auth/login | μ‘°νμ | β |
μ 체 μ·μ₯ μ‘°ν | [GET] /allCloset | κΉλμ¬ | β |
μ 체 μ·μ₯ μλ₯ μ 보 μμ | [PUT] /allCloset/:productId | κΉλμ¬ | β |
μ 체 μ·μ₯ μλ₯ μμ | [DELETE] /allCloset/:productId | κΉλμ¬ | β |
ν¬ν¨λ μΉ΄ν κ³ λ¦¬ id μ‘°ν | [GET] /allCloset/:productId | κΉλμ¬ | β |
μΉ΄ν κ³ λ¦¬μ μλ₯ μΆκ° | [POST] /allCloset/toCategory | κΉλμ¬ | β |
μΉ΄ν κ³ λ¦¬ μ 체 μ‘°ν | [GET] /category | κΉλμ¬ | β |
μΉ΄ν κ³ λ¦¬ μμ± | [POST] /category/createCategory | κΉλμ¬ | β |
μΉ΄ν κ³ λ¦¬ μμ | [DELETE] /category/:categoryId | κΉλμ¬ | β |
μΉ΄ν κ³ λ¦¬ μμ | [PUT] /category/:categoryId | κΉλμ¬ | β |
μΉ΄ν κ³ λ¦¬ μμΈ μ‘°ν | [GET] /category/:categoryId | κΉλμ¬ | β |
μΉ΄ν κ³ λ¦¬ λ΄ μλ₯ ν κ³ μ /ν΄μ | [PUT] /category/:categoryId/:productId | κΉλμ¬ | β |
μΉ΄ν κ³ λ¦¬ λ΄ μλ₯ μμ | [DELETE] /category/:categoryId/:inClothId | κΉλμ¬ | β |
λ§μ΄μ¬μ΄μ¦ μ‘°ν | [GET] /mysize | μ‘°νμ | β |
λ΄ μμ μ¬μ΄μ¦ μ 보 μ λ ₯ | [POST] /mysize/topSize | μ‘°νμ | β |
λ΄ νμ μ¬μ΄μ¦ μ 보 μ λ ₯ | [POST] /mysize/bottomSize | μ‘°νμ | β |
λ§μ΄νμ΄μ§ μ‘°ν | [GET] /mypage | μ‘°νμ | β |
μ¬μ΄μ¦ μΆμ² κΈ°λ‘ μ‘°ν | [GET] /mypage/history | μ‘°νμ | β |
μ 체 μ·μ₯μ μ μ₯ | [POST] /extesion/toAllCloset | κΉλμ¬ | β |
ν¬λ‘€λ§ν μ¬μ΄μ¦ν μ μ₯ | [POST] /extesion/saveCrawling | κΉλμ¬ | β |
μ¬μ΄μ¦ μΆμ² κ²°κ³Ό μ μ₯ | [POST] /extension/saveBest | κΉλμ¬ | β |
λΉκ΅ μ¬μ΄μ¦ μλ μ λ ₯ | [POST] /extension/inputSize | κΉλμ¬ | β |
λ³μλͺ
- Camel Case μ¬μ©
- ν¨μμ κ²½μ° λμ¬+λͺ μ¬ μ¬μ© ( ex) getUser() )
- μ½μ΄λ λλλ‘ μ¬μ©νμ§ μμ
μ£Όμ
- ν μ€ μ£Όμ μ¬μ© //
- ν¨μ μ£Όμ
/**
* @route
* @desc
* @access
**/
getUser()
μ΄ μΈ ESLint λΌμ΄λΈλ¬λ¦¬ λ¬Έλ²μ λ°λ₯Έλ€.
Branch μ΄λ¦ | μ©λ |
---|---|
main | μ΄κΈ° μΈν |
develop | λ°°ν¬ branch (api λ‘μ§ κ΅¬ν μλ£) |
feature/#μ΄μλ²νΈ | μ΄μλ³ api λ‘μ§ κ΅¬ν |
- feature -> development : Pull Request (μ½λ 리뷰 μμ΄ merge λΆκ°)
[λΈλμΉ μ΄λ¦] κΈ°λ₯ (λλ λ³κ²½μ¬ν) κ°λ΅ μ€λͺ
(70μ)
- 보좩 μ€λͺ
μ΄ νμν κ²½μ°
- Headμ νμΉΈμ λμ΄μ μμ±
issue tracker: μ΄μ λ²νΈ (option)
3-Layer Architecture κΈ°λ°
π src
|_ π constants
|_ π controller
|_ π interfaces
|_ π middlewares
|_ π modules
|_ π router
|_ π service
|_ π test
|_ index.ts
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id(map: "user_pk") @unique(map: "user_id_uindex") @default(autoincrement())
name String? @db.VarChar(10)
email String @unique @db.VarChar(50)
userImage String? @db.VarChar(500)
token String? @db.VarChar(500)
AllCloset AllCloset[]
AllSizeBottom AllSizeBottom[]
AllSizeTop AllSizeTop[]
Category Category[]
Recommend Recommend[]
}
model AllCloset {
id Int @id(map: "Archive_pkey") @unique(map: "Archive_id_key") @default(autoincrement())
userId Int @default(autoincrement())
image String? @db.VarChar(500)
productName String? @db.VarChar(36)
size String? @db.VarChar(10)
memo String? @db.VarChar(50)
isRecommend Boolean?
isPin Boolean @default(false)
mallName String? @db.VarChar(50)
productUrl String? @db.VarChar(500)
faviconUrl String? @db.VarChar(500)
createdAt String? @db.VarChar(20)
User User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "allcloset_user_id_fk")
AllCloset_Category AllCloset_Category[]
}
model AllSizeBottom {
id Int @id @unique @default(autoincrement())
size String? @db.VarChar(10)
bottomLength Int?
waist Int?
thigh Int?
rise Int?
hem Int?
isWidthOfBottom Boolean?
isManual Boolean?
topOrBottom Int?
manualInputNum Int?
bottomItemId Int?
userId Int @default(autoincrement())
User User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "allsizebottom_user_id_fk")
}
model AllSizeTop {
id Int @id @unique @default(autoincrement())
size String? @db.VarChar(10)
topLength Int?
shoulder Int?
chest Int?
isWidthOfTop Boolean?
isManual Boolean?
topOrBottom Int?
manualInputNum Int?
topItemId Int?
userId Int @default(autoincrement())
User User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "allsizetop_user_id_fk")
}
model MySize {
id Int @id @unique @default(autoincrement())
userId Int @unique @default(autoincrement())
topLength Int?
shoulder Int?
chest Int?
isWidthOfTop Boolean?
bottomLength Int?
waist Int?
thigh Int?
rise Int?
hem Int?
isWidthOfBottom Boolean?
}
model Category {
id Int @id @unique @default(autoincrement())
categoryName String? @db.VarChar(20)
isPinCategory Boolean?
image String[] @db.VarChar
userId Int @default(autoincrement())
AllCloset_Category AllCloset_Category[]
User User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "category_user_id_fk")
}
model AllCloset_Category {
id Int @id @unique @default(autoincrement())
productId Int @default(autoincrement())
categoryId Int @default(autoincrement())
isInPin Boolean?
AllCloset AllCloset @relation(fields: [productId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "allcloset_category_allcloset_id_fk")
Category Category @relation(fields: [categoryId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "allcloset_category_category_id_fk")
}
model Recommend {
id Int @id @unique @default(autoincrement())
userId Int @default(autoincrement())
url String? @db.VarChar(200)
recommendSize String? @db.VarChar(10)
topItemId Int?
bottomItemId Int?
User User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "recommend_user_id_fk")
}
{
"name": "Server",
"version": "1.0.0",
"main": "index.js",
"repository": "https://github.com/OWN-SIZE/Server.git",
"author": "ehdwoKIM <kinbell19@gmail.com>",
"license": "MIT",
"scripts": {
"dev": "nodemon",
"build": "tsc && node dist",
"db:pull": "npx prisma db pull",
"db:push": "npx prisma db push",
"generate": "npx prisma generate"
},
"dependencies": {
"@prisma/client": "^4.6.1",
"bcryptjs": "^2.4.3",
"express": "^4.18.2",
"express-validator": "^6.14.2",
"prisma": "^4.6.1",
"typescript": "^4.9.3"
},
"devDependencies": {
"@types/bcryptjs": "^2.4.2",
"@types/express": "^4.17.14",
"@types/express-validator": "^3.0.0",
"@types/node": "^18.11.9",
"nodemon": "^2.0.20",
"ts-node": "^10.9.1"
}
}
- κ°λ° νκ²½ : Typescript, Express(Node.js)
- λ°μ΄ν°λ² μ΄μ€ : PostgreSQL, AWS S3
- μλ² νκ²½ : AWS EC2, PM2