diff --git a/.eslintrc.json b/.eslintrc.json index 6709dd4..eb0d110 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -20,6 +20,7 @@ "rules": { "prettier/prettier": "error", "@typescript-eslint/no-var-requires": "error", + "@typescript-eslint/no-empty-interface": ["error",{ "allowSingleExtends": true }], "new-cap": ["error", { "capIsNew": false }], "no-prototype-builtins": "off", "no-self-assign": "off", diff --git a/src/controllers/ReviewController.ts b/src/controllers/ReviewController.ts new file mode 100644 index 0000000..4f8d481 --- /dev/null +++ b/src/controllers/ReviewController.ts @@ -0,0 +1,44 @@ +import { Request, Response } from 'express'; +import { validationResult } from 'express-validator'; +import { ReviewCreateDto } from '../interfaces/review/ReviewCreateDto'; +import message from '../modules/responseMessage'; +import statusCode from '../modules/statusCode'; +import util from '../modules/util'; +import { ReviewService } from '../services'; + +const getReviewList = async (req: Request, res: Response): Promise => { + try { + const data = await ReviewService.getReviewList(); + if (!data) { + res.status(statusCode.NOT_FOUND).send(util.fail(statusCode.NOT_FOUND, message.NOT_FOUND)); + } + res.status(statusCode.OK).send(util.success(statusCode.OK, message.READ_MAINPAGE_REVIEW_SUCCESS, data)); + } catch (error) { + console.log(error); + res.status(statusCode.INTERNAL_SERVER_ERROR).send(util.fail(statusCode.INTERNAL_SERVER_ERROR, message.INTERNAL_SERVER_ERROR)); + } +}; + +const createReview = async (req: Request, res: Response): Promise => { + const error = validationResult(req); + if (!error.isEmpty()) { + return res.status(statusCode.BAD_REQUEST).send(util.fail(statusCode.BAD_REQUEST, message.BAD_REQUEST)); + } + + const reviewCreateDto: ReviewCreateDto = req.body; + try { + const data = await ReviewService.createReview(reviewCreateDto); + if (!data) { + res.status(statusCode.NOT_FOUND).send(util.fail(statusCode.NOT_FOUND, message.NOT_FOUND)); + } + res.status(statusCode.CREATED).send(util.success(statusCode.CREATED, message.CREATE_REVIEW_SUCCESS, data)); + } catch (error) { + console.log(error); + res.status(statusCode.INTERNAL_SERVER_ERROR).send(util.fail(statusCode.INTERNAL_SERVER_ERROR, message.INTERNAL_SERVER_ERROR)); + } +}; + +export default { + getReviewList, + createReview, +}; diff --git a/src/controllers/SubscribeController.ts b/src/controllers/SubscribeController.ts new file mode 100644 index 0000000..1776f2b --- /dev/null +++ b/src/controllers/SubscribeController.ts @@ -0,0 +1,20 @@ +import { Request, Response } from 'express'; +import message from '../modules/responseMessage'; +import statusCode from '../modules/statusCode'; +import util from '../modules/util'; +import SubscribeService from '../services/SubscribeService'; + +const getSubscribeOptions = async (req: Request, res: Response) => { + try { + const data = await SubscribeService.getSubscribeOptions(); + if (!data) { + res.status(statusCode.NOT_FOUND).send(util.fail(statusCode.NOT_FOUND, message.NOT_FOUND)); + } + res.status(statusCode.OK).send(util.success(statusCode.OK, message.READ_SUBSCRIBE_OPTION_SUCCESS, data)); + } catch (error) { + console.log(error); + res.status(statusCode.INTERNAL_SERVER_ERROR).send(util.fail(statusCode.INTERNAL_SERVER_ERROR, message.INTERNAL_SERVER_ERROR)); + } +}; + +export default { getSubscribeOptions }; diff --git a/src/controllers/index.ts b/src/controllers/index.ts index 388066c..2c84a0f 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -1,3 +1,4 @@ -// controller index file -export { }; +import ReviewController from './ReviewController'; +import SubscribeController from './SubscribeController'; +export { ReviewController, SubscribeController }; diff --git a/src/interfaces/common/PostBaseResponseDto.ts b/src/interfaces/common/PostBaseResponseDto.ts index 6af2f99..fb2bb10 100644 --- a/src/interfaces/common/PostBaseResponseDto.ts +++ b/src/interfaces/common/PostBaseResponseDto.ts @@ -1,5 +1,5 @@ -import mongoose from "mongoose"; +import mongoose from 'mongoose'; export interface PostBaseResponseDto { - _id: mongoose.Schema.Types.ObjectId; -} \ No newline at end of file + _id: mongoose.Schema.Types.ObjectId; +} diff --git a/src/interfaces/period/PeriodInfo.ts b/src/interfaces/period/PeriodInfo.ts index db38be7..81adb6e 100644 --- a/src/interfaces/period/PeriodInfo.ts +++ b/src/interfaces/period/PeriodInfo.ts @@ -1,3 +1,3 @@ export interface PeriodInfo { - option: string; -} \ No newline at end of file + option: string; +} diff --git a/src/interfaces/quantity/QuantityInfo.ts b/src/interfaces/quantity/QuantityInfo.ts index a333da3..1c2578e 100644 --- a/src/interfaces/quantity/QuantityInfo.ts +++ b/src/interfaces/quantity/QuantityInfo.ts @@ -1,3 +1,3 @@ export interface QuantityInfo { - option: string; -}; \ No newline at end of file + option: string; +} diff --git a/src/interfaces/review/ReviewCreateDto.ts b/src/interfaces/review/ReviewCreateDto.ts new file mode 100644 index 0000000..c20dc0a --- /dev/null +++ b/src/interfaces/review/ReviewCreateDto.ts @@ -0,0 +1,3 @@ +import { ReviewInfo } from './ReviewInfo'; + +export interface ReviewCreateDto extends ReviewInfo {} diff --git a/src/interfaces/review/ReviewInfo.ts b/src/interfaces/review/ReviewInfo.ts index 71e065d..1ff1ebb 100644 --- a/src/interfaces/review/ReviewInfo.ts +++ b/src/interfaces/review/ReviewInfo.ts @@ -1,8 +1,8 @@ export interface ReviewInfo { - userName: String; - thumbnail?: String; - description: Text; - rates: Number; - packageName: string; - product: String; -} \ No newline at end of file + userName: string; + thumbnail?: string; + description: Text; + rates: number; + packageName: string; + product: string[]; +} diff --git a/src/interfaces/review/ReviewResponseDto.ts b/src/interfaces/review/ReviewResponseDto.ts new file mode 100644 index 0000000..1069d29 --- /dev/null +++ b/src/interfaces/review/ReviewResponseDto.ts @@ -0,0 +1,10 @@ +import mongoose from 'mongoose'; + +export interface ReviewResponseDto { + _id: mongoose.Types.ObjectId; + userName: string; + description: Text; + productList: string[]; + reviewDate: string; + thumbnail: string; +} diff --git a/src/interfaces/subscribe/SubscribeInfo.ts b/src/interfaces/subscribe/SubscribeInfo.ts index e1361e7..e81242b 100644 --- a/src/interfaces/subscribe/SubscribeInfo.ts +++ b/src/interfaces/subscribe/SubscribeInfo.ts @@ -1,7 +1,7 @@ -import { PeriodInfo } from "../period/PeriodInfo"; -import { QuantityInfo } from "../quantity/QuantityInfo"; +import { PeriodInfo } from '../period/PeriodInfo'; +import { QuantityInfo } from '../quantity/QuantityInfo'; export interface SubscribeInfo { - period: PeriodInfo; - quantity: QuantityInfo; -}; \ No newline at end of file + period: PeriodInfo; + quantity: QuantityInfo; +} diff --git a/src/interfaces/subscribe/SubscribeOptionDto.ts b/src/interfaces/subscribe/SubscribeOptionDto.ts new file mode 100644 index 0000000..75468a0 --- /dev/null +++ b/src/interfaces/subscribe/SubscribeOptionDto.ts @@ -0,0 +1,7 @@ +import { PeriodInfo } from '../period/PeriodInfo'; +import { QuantityInfo } from '../quantity/QuantityInfo'; + +export interface SubscribeOptionDto { + deliveryPeriodOptions: PeriodInfo[]; + deliveryQuantityOptions: QuantityInfo[]; +} diff --git a/src/loaders/db.ts b/src/loaders/db.ts index 02661ed..3564d45 100644 --- a/src/loaders/db.ts +++ b/src/loaders/db.ts @@ -1,5 +1,9 @@ import mongoose from 'mongoose'; import config from '../config'; +import Period from '../models/Period'; +import Quantity from '../models/Quantity'; +import Review from '../models/Review'; +import Subscribe from '../models/Subscribe'; const connectDB = async () => { try { @@ -15,6 +19,22 @@ const connectDB = async () => { mongoose.set('autoIndex', true); console.log('Mongoose Connected ...'); + + Period.createCollection().then(collection => { + console.log('Period collection is created!!'); + }); + + Quantity.createCollection().then(collection => { + console.log('Quantity collection is created!!'); + }); + + Review.createCollection().then(collection => { + console.log('Review collection is created!!'); + }); + + Subscribe.createCollection().then(collection => { + console.log('Subscribe collection is created!!'); + }); } catch (err: any) { console.error(err.message); process.exit(1); diff --git a/src/models/Period.ts b/src/models/Period.ts index 8cea839..dfe8e30 100644 --- a/src/models/Period.ts +++ b/src/models/Period.ts @@ -1,11 +1,11 @@ -import mongoose from "mongoose"; -import { PeriodInfo } from "../interfaces/period/PeriodInfo"; +import mongoose from 'mongoose'; +import { PeriodInfo } from '../interfaces/period/PeriodInfo'; -const PeriodSchema = new mongoose.Schema ({ - option: { - type: String, - required: true - } +const PeriodSchema = new mongoose.Schema({ + option: { + type: String, + required: true, + }, }); -export default mongoose.model("Period", PeriodSchema) \ No newline at end of file +export default mongoose.model('Period', PeriodSchema); diff --git a/src/models/Quantity.ts b/src/models/Quantity.ts index 32acec6..4307931 100644 --- a/src/models/Quantity.ts +++ b/src/models/Quantity.ts @@ -1,11 +1,11 @@ -import mongoose from "mongoose"; -import { QuantityInfo } from "../interfaces/quantity/QuantityInfo"; +import mongoose from 'mongoose'; +import { QuantityInfo } from '../interfaces/quantity/QuantityInfo'; -const QuantitySchema = new mongoose.Schema ({ - option: { - type: String, - required: true - } +const QuantitySchema = new mongoose.Schema({ + option: { + type: String, + required: true, + }, }); -export default mongoose.model("Queantity", QuantitySchema) \ No newline at end of file +export default mongoose.model('Quantity', QuantitySchema); diff --git a/src/models/Review.ts b/src/models/Review.ts index 6a89712..71c7ea7 100644 --- a/src/models/Review.ts +++ b/src/models/Review.ts @@ -1,32 +1,33 @@ -import mongoose from "mongoose"; -import { ReviewInfo } from "../interfaces/review/ReviewInfo"; +import mongoose from 'mongoose'; +import { ReviewInfo } from '../interfaces/review/ReviewInfo'; -const ReviewSchema = new mongoose.Schema ({ +const ReviewSchema = new mongoose.Schema( + { userName: { - type: String, - required: true + type: String, + required: true, }, - thumbnanil: { - type: String + thumbnail: { + type: String, }, description: { - type: String, - required: true + type: String, + required: true, }, rates: { - type: Number, - required: true + type: Number, + required: true, }, packageName: { - type: String, - required: true + type: String, + required: true, }, product: { - type: String, - required: true - } -}, -{timestamps: true} + type: Array, + required: true, + }, + }, + { timestamps: true }, ); -export default mongoose.model("Review", ReviewSchema) \ No newline at end of file +export default mongoose.model('Review', ReviewSchema); diff --git a/src/models/Subscribe.ts b/src/models/Subscribe.ts index 39cd8a9..ef781d0 100644 --- a/src/models/Subscribe.ts +++ b/src/models/Subscribe.ts @@ -1,19 +1,19 @@ -import mongoose from "mongoose"; -import { SubscribeInfo } from "../interfaces/subscribe/SubscribeInfo"; +import mongoose from 'mongoose'; +import { SubscribeInfo } from '../interfaces/subscribe/SubscribeInfo'; -const SubscribeSchema = new mongoose.Schema ({ - period: { - option: { - type: String, - required: true - } +const SubscribeSchema = new mongoose.Schema({ + period: { + option: { + type: String, + required: true, }, - quantity: { - option: { - type: String, - required: true - } - } + }, + quantity: { + option: { + type: String, + required: true, + }, + }, }); -export default mongoose.model("Subscribe", SubscribeSchema) \ No newline at end of file +export default mongoose.model('Subscribe', SubscribeSchema); diff --git a/src/modules/responseMessage.ts b/src/modules/responseMessage.ts index bd575b2..0ece097 100644 --- a/src/modules/responseMessage.ts +++ b/src/modules/responseMessage.ts @@ -3,6 +3,11 @@ const message = { NOT_FOUND: '존재하지 않는 자원', BAD_REQUEST: '잘못된 요청', INTERNAL_SERVER_ERROR: '서버 내부 오류', + + READ_MAINPAGE_REVIEW_SUCCESS: '메인 페이지 리뷰 조회 성공', + CREATE_REVIEW_SUCCESS: '리뷰 등록 성공', + + READ_SUBSCRIBE_OPTION_SUCCESS: '라면 구독 옵션 조회 성공', }; export default message; diff --git a/src/routes/ReviewRouter.ts b/src/routes/ReviewRouter.ts new file mode 100644 index 0000000..fd6e9b2 --- /dev/null +++ b/src/routes/ReviewRouter.ts @@ -0,0 +1,10 @@ +import { Router } from 'express'; +import { body } from 'express-validator'; +import { ReviewController } from '../controllers'; + +const router: Router = Router(); + +router.get('/', ReviewController.getReviewList); +router.post('/', [body('userName').notEmpty(), body('description').notEmpty(), body('rates').notEmpty(), body('packageName').notEmpty(), body('product').notEmpty()], ReviewController.createReview); + +export default router; diff --git a/src/routes/SubscribeRouter.ts b/src/routes/SubscribeRouter.ts new file mode 100644 index 0000000..be94296 --- /dev/null +++ b/src/routes/SubscribeRouter.ts @@ -0,0 +1,8 @@ +import { Router } from 'express'; +import { SubscribeController } from '../controllers'; + +const router: Router = Router(); + +router.get('/', SubscribeController.getSubscribeOptions); + +export default router; diff --git a/src/routes/index.ts b/src/routes/index.ts index ce06ee3..1aab9ce 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,6 +1,11 @@ // router index file import { Router } from 'express'; +import ReviewRouter from './ReviewRouter'; +import SubScribeRouter from './SubscribeRouter'; -const router = Router(); +const router: Router = Router(); + +router.use('/review', ReviewRouter); +router.use('/subscribe', SubScribeRouter); export default router; diff --git a/src/services/ReviewService.ts b/src/services/ReviewService.ts new file mode 100644 index 0000000..6ba313b --- /dev/null +++ b/src/services/ReviewService.ts @@ -0,0 +1,52 @@ +import { PostBaseResponseDto } from '../interfaces/common/PostBaseResponseDto'; +import { ReviewCreateDto } from '../interfaces/review/ReviewCreateDto'; +import { ReviewResponseDto } from '../interfaces/review/ReviewResponseDto'; +import Review from '../models/Review'; + +const getReviewList = async (): Promise => { + try { + const reviews = await Review.find(); + if (!reviews) { + return null; + } + const mainPageReviews: ReviewResponseDto[] = await Promise.all( + reviews.map((review: any) => { + const result = { + _id: review._id, + userName: review.userName, + thumbnail: review.thumbnail, + description: review.description, + packageName: review.packageName, + productList: review.product, + reviewDate: review.createdAt, + }; + return result; + }), + ); + return mainPageReviews; + } catch (error) { + console.log(error); + throw error; + } +}; + +const createReview = async (reviewCreateDto: ReviewCreateDto): Promise => { + try { + const review = new Review(reviewCreateDto); + await review.save(); + + const data = { + _id: review._id, + }; + + return data; + } catch (error) { + console.log(error); + throw error; + } +}; + +export default { + getReviewList, + createReview, +}; diff --git a/src/services/SubscribeService.ts b/src/services/SubscribeService.ts new file mode 100644 index 0000000..1188aac --- /dev/null +++ b/src/services/SubscribeService.ts @@ -0,0 +1,26 @@ +import { SubscribeOptionDto } from '../interfaces/subscribe/SubscribeOptionDto'; +import Period from '../models/Period'; +import Quantity from '../models/Quantity'; + +const getSubscribeOptions = async (): Promise => { + try { + const periodOptions = await Period.find(); + const quantityOptions = await Quantity.find(); + + if (!periodOptions || !quantityOptions) { + return null; + } + + const subscribeOptionList = { + deliveryPeriodOptions: periodOptions, + deliveryQuantityOptions: quantityOptions, + }; + + return subscribeOptionList; + } catch (error) { + console.log(error); + throw error; + } +}; + +export default { getSubscribeOptions }; diff --git a/src/services/index.ts b/src/services/index.ts index 3209921..5e7cc2b 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -1,3 +1,4 @@ // service index file -export { }; +import ReviewService from './ReviewService'; +export { ReviewService };