TIL

Node.js 백오피스 팀 프로젝트 (7)

황민도 2024. 6. 28. 04:58

내일배움캠프 스파르타 코딩클럽


< routers. petsitters.router.js >

import express from 'express';
import { prisma } from '../utils/prisma.utils.js';
import { PetsitterController } from '../controllers/petsitters.controller.js';
import { PetsitterRepository } from '../repositories/petsitters.repository.js';
import { PetsitterService } from '../services/petsitters.service.js';
import { requireAccessToken } from '../middlewares/require-access-token.middleware.js';
import { requireRoles } from '../middlewares/require-roles.middleware.js';
import { PetsitterServiceRepository } from '../repositories/petsitterService.repository.js';
import { PetsitterLocationRepository } from '../repositories/petsitterLocation.repository.js';
import { updateServiceValidator } from '../middlewares/validators/petsitter-service-validator.middleware.js';

const petsitterRouter = express.Router();

const petsitterRepository = new PetsitterRepository(prisma);
const petsitterServiceRepository = new PetsitterServiceRepository(prisma);
const petsitterLocationRepository = new PetsitterLocationRepository(prisma);
const petsitterService = new PetsitterService(
  petsitterRepository,
  petsitterServiceRepository,
  petsitterLocationRepository
);
const petsitterController = new PetsitterController(petsitterService);

// 펫시터 목록 조회
petsitterRouter.get('/', petsitterController.getList);

//펫시터 검색 기능
petsitterRouter.get('/search', petsitterController.lookForSitter);

//펫시터 지역별 필터링
petsitterRouter.get('/filter', petsitterController.petsitterLocation);

// 펫시터 상세 조회
petsitterRouter.get('/:id', petsitterController.sitterDetail);

// 펫시터 지원 서비스 추가
petsitterRouter.post(
  '/services ',
  requireAccessToken,
  requireRoles(['petsitter']),
  updateServiceValidator,
  petsitterController.serviceCreate
);

// 펫시터 서비스 지역 추가
petsitterRouter.post(
  '/locations',
  requireAccessToken,
  requireRoles(['petsitter']),
  petsitterController.locationCreate
);

export { petsitterRouter };

 

< controllers. petsitters.controller.js >

import { HTTP_STATUS } from '../constants/http-status.constant.js';

export class PetsitterController {
  constructor(petsitterService) {
    this.petsitterService = petsitterService;
  }

  // 펫시터 목록 조회
  getList = async (req, res, next) => {
    try {
      let data = await this.petsitterService.findSitter();

      return res.status(HTTP_STATUS.OK).json({
        status: HTTP_STATUS.OK,
        message: '펫시터 목록조회에 성공하였습니다',
        data,
      });
    } catch (err) {
      next(err);
    }
  };

  //펫시터 상세 조회
  sitterDetail = async (req, res, next) => {
    try {
      const { id } = req.params;
      console.log(id);

      let data = await this.petsitterService.readSitter(id);
      return res.status(HTTP_STATUS.OK).json({
        status: HTTP_STATUS.OK,
        message: '펫시터 상세조회에 성공하였습니다',
        data,
      });
    } catch (err) {
      next(err);
    }
  };

  //펫시터 검색 기능
  lookForSitter = async (req, res, next) => {
    try {
      const { query } = req.query;
      console.log('test');

      let data = await this.petsitterService.searchSitters(query);

      return res.status(HTTP_STATUS.OK).json({
        status: HTTP_STATUS.OK,
        message: '시터 검색에 성공하였습니다',
        data,
      });
    } catch (err) {
      next(err);
    }
  };

  //펫시터 지역별 필터링
  petsitterLocation = async (req, res, next) => {
    try {
      const { location } = req.query;

      let data = await this.petsitterService.findByLocation(location);

      return res.status(HTTP_STATUS.OK).json({
        status: HTTP_STATUS.OK,
        message: '지역별 검색에 성공하였습니다',
        data,
      });
    } catch (err) {
      next(err);
    }
  };

  //펫시터 지원 서비스 추가
  serviceCreate = async (req, res, next) => {
    try {
      const petsitterId = req.user.id;
      const { animalType, serviceType, price } = req.body;

      const data = await this.petsitterService.serviceCreate({
        petsitterId,
        animalType,
        serviceType,
        price: Number(price),
      });

      res
        .status(HTTP_STATUS.CREATED)
        .json({ message: '서비스를 추가했습니다.', data });
      return;
    } catch (error) {
      next(error);
    }
  };

  //펫시터 서비스 지역 추가
  locationCreate = async (req, res, next) => {
    try {
      const petsitterId = req.user.id;
      const { location, surcharge } = req.body;

      const data = await this.petsitterService.locationCreate({
        petsitterId,
        location,
        surcharge: surcharge ? Number(surcharge) : undefined,
      });

      res
        .status(HTTP_STATUS.CREATED)
        .json({ message: '서비스 지역을 추가했습니다.', data });
    } catch (error) {
      next(error);
    }
  };
}

 

< services. petsitters.service.js >

import { HttpError } from '../errors/http.error.js';

export class PetsitterService {
  constructor(
    petsitterRepository,
    petsitterServiceRepository,
    petsitterLocationRepository
  ) {
    this.petsitterRepository = petsitterRepository;
    this.petsitterServiceRepository = petsitterServiceRepository;
    this.petsitterLocationRepository = petsitterLocationRepository;
  }

  // 펫시터 목록조회
  findSitter = async () => {
    const sitters = await this.petsitterRepository.findSitter();

    sitters.sort((a, b) => {
      return b.createdAt - a.createdAt;
    });

    return sitters.map((sitter) => {
      return {
        id: sitter.id,
        name: sitter.name,
        experience: sitter.experience,
        introduce: sitter.introduce,
        localtion: sitter.localtion,
        createdAt: sitter.createdAt,
      };
    });
  };
  //펫시터 상세조회
  readSitter = async (id) => {
    const sitter = await this.petsitterRepository.readSitter(id);

    return {
      id: sitter.id,
      name: sitter.name,
      experience: sitter.experience,
      email: sitter.email,
      profileImage: sitter.profileImage,
      introduce: sitter.introduce,
      createdAt: sitter.createdAt,
      updatedAt: sitter.updatedAt,
    };
  };

  //펫시터 검색
  searchSitters = async (query) => {
    const sitters = await this.petsitterRepository.searchSitters(query);

    sitters.sort((a, b) => {
      return b.createdAt - a.createdAt;
    });

    return sitters.map((sitter) => {
      return {
        id: sitter.id,
        name: sitter.name,
        experience: sitter.experience,
        introduce: sitter.introduce,
        localtion: sitter.localtion,
        profileImage: sitter.profileImage,
        createdAt: sitter.createdAt,
      };
    });
  };
  //펫시터 지역별 필터링
  findByLocation = async (location) => {
    const sitters = await this.petsitterRepository.findByLocation(location);

    sitters.sort((a, b) => {
      return b.createdAt - a.createdAt;
    });

    return sitters.map((sitter) => {
      return {
        id: sitter.id,
        name: sitter.name,
        experience: sitter.experience,
        introduce: sitter.introduce,
        localtion: sitter.petsitterLocation
          .map((loc) => loc.location)
          .join(', '),
        profileImage: sitter.profileImage,
        createdAt: sitter.createdAt,
      };
    });
  };

  serviceCreate = async ({ petsitterId, animalType, serviceType, price }) => {
    const existingService =
      await this.petsitterServiceRepository.findPetsitterService({
        petsitterId,
        animalType,
        serviceType,
      });

    if (existingService) {
      throw new HttpError.BadRequest('이미 저장된 서비스 내용입니다.');
    }

    const createData = await this.petsitterServiceRepository.createService({
      petsitterId,
      animalType,
      serviceType,
      price,
    });

    return createData;
  };

  locationCreate = async ({ petsitterId, location, surcharge }) => {
    const existingLocation =
      await this.petsitterLocationRepository.findPetsitterLocation({
        petsitterId,
        location,
      });

    if (existingLocation) {
      throw new HttpError.BadRequest('이미 저장된 서비스 지역입니다.');
    }

    const createData = await this.petsitterLocationRepository.createLocation({
      petsitterId,
      location,
      surcharge,
    });

    return createData;
  };
}

 

< repositories. poetsitters.repository.js >

export class PetsitterRepository {
  constructor(prisma) {
    this.prisma = prisma;
  }

  // 펫시터 목록 조회
  findSitter = async () => {
    const data = await this.prisma.petsitter.findMany();
    return data;
  };

  //펫시터 상세조회
  readSitter = async (id) => {
    const data = await this.prisma.petsitter.findUnique({
      where: { id: +id },
    });
    return data;
  };

  //펫시터 검색
  searchSitters = async (query) => {
    const data = await this.prisma.petsitter.findMany({
      where: {
        name: { contains: query },
      },
    });
    return data;
  };

  // 펫시터 지역별 정렬
  findByLocation = async (location) => {
    const data = await this.prisma.petsitter.findMany({
      where: {
        petsitterLocation: {
          some: {
            location: {
              contains: location,
            },
          },
        },
      },
      include: { petsitterLocation: true },
    });
    return data;
  };

  //펫시터 이메일로 찾기(로그인용)
  findPetsitterByEmail = async ({ email }) => {
    const petsitter = await this.prisma.petsitter.findUnique({
      where: { email },
    });

    return petsitter;
  };

  findPetsitterById = async ({ id }) => {
    const petsitter = await this.prisma.petsitter.findUnique({
      where: { id },
    });

    return petsitter;
  };

  //펫시터 회원가입
  createPetsitter = async ({
    email,
    password,
    name,
    experience,
    introduce,
    profileImage,
  }) => {
    const user = await this.prisma.petsitter.create({
      data: {
        email,
        password,
        name,
        experience,
        introduce,
        profileImage,
      },
    });

    return user;
  };

  //펫시터 찾기
  findPetsitterByIdWith = async ({ petsitterId }) => {
    const petsitter = await this.prisma.petsitter.findUnique({
      where: { id: petsitterId },
      include: {
        petsitterService: true,
        petsitterLocation: true,
      },
    });

    return petsitter;
  };
}

 

< repositories. petsitterLocation.repository.js >

export class PetsitterLocationRepository {
  constructor(prisma) {
    this.prisma = prisma;
  }

  findPetsitterLocation = async ({ petsitterId, location }) => {
    const existingLocation = await this.prisma.petsitterLocation.findFirst({
      where: { petsitterId, location },
    });

    return existingLocation;
  };

  createLocation = async ({ petsitterId, location, surcharge }) => {
    const createLocation = await this.prisma.petsitterLocation.create({
      data: {
        petsitterId,
        location,
        surcharge,
      },
    });

    return createLocation;
  };
}

 

< repositories. petsitterService.repository.js >

export class PetsitterServiceRepository {
  constructor(prisma) {
    this.prisma = prisma;
  }

  findPetsitterService = async ({ petsitterId, animalType, serviceType }) => {
    const existingService = await this.prisma.petsitterService.findFirst({
      where: { petsitterId, animalType, serviceType },
    });

    return existingService;
  };

  createService = async ({ petsitterId, animalType, serviceType, price }) => {
    const createData = await this.prisma.petsitterService.create({
      data: {
        petsitterId,
        animalType,
        serviceType,
        price,
      },
    });

    return createData;
  };
}