FastCampas X Yanolja BootCamp

패스트캠퍼스x야놀자 웹 프론트엔드 부트캠프 미니프로젝트 회고

취업하고싶다! 2023. 12. 19. 17:15

프로젝트 내용

패스트캠퍼스x야놀자 웹 프론트엔드 부트캠프 미니프로젝트를 진행했다.

주제는 다음과 같다.

 

본 프로젝트는 숙박 예약 서비스를 완성하는 것을 목표로 함

본 프로젝트의 개발 범위는 다음과 같다

- 회원 인증 ◼ 회원가입 ◼ 로그인

- 상품 조회 ◼ 전체 숙박 상품 목록 조회 (옵션) 카테고리를 임의 생성하여 분류하여 출력 ◼ 개별 숙박 상품 상세 소개

- 상품 선택 및 장바구니 담기 ◼ 숙박 상품 옵션 선택 ◼ 장바구니 담기 ◼ (또는) 바로 결제하기

- 장바구니 ◼ 장바구니 보기 ◼ 장바구니에서 주문하기 버튼 클릭 시, 예약(주문) 페이지로 이동

- 예약(주문) 하기 ◼ 만 14세 이상 이용 동의 (상세 설명서 X, 체크박스로만 간단히 처리) ◼ 결제하기 버튼 클릭 시, 상품을 주문한 것으로 처리 (별도 결제 로직 없음) ◼ 결제 성공 시 주문 결과 출력

- (옵션) 주문 내역 조회 ◼ 별도 주문 내역 페이지를 통해 주문 내역 확인

 

 

프로젝트 기간

2023년 11월 19일 ~ 2023년 12월 1일

 

 

배포사이트 및 깃허브 주소

배포사이트

 

Shimpyo

 

shimpyo.netlify.app

 

 

깃허브주소

 

Shimpyo-House

숙박 정보 조회/검색 및 숙박 예약 시스템 개발을 위한 Organization 입니다. Shimpyo-House has 3 repositories available. Follow their code on GitHub.

github.com

 

 

역할 분담

우리팀은 프론트 5명, 백엔드 3명으로 구성되었다.

프론트가 5명이라 기능에 따라 쉽게 역할분담을 할 수 있었다.

회원 인증 1명, 상품 전체 정보 조회 1명, 상품 상세 정보 조회 1명, 장바구니 1명, 예약하기 1명으로 나누기로 결정했고

나는 상품 상세 정보 조회 페이지가 가장 재밌고 배울 것이 많을 것 같아서 이 기능을 맡아서 하기로 했다.

 

 

진행 과정

나를 포함한 프론트 5명 모두 백엔드와의 협업은 처음이었지만 백엔드에는 프론트와 협업 경험을 한 사람이 있었기에 그 분이 주도해서 프로젝트를 이끌었다.

프로젝트는 23/11/19 ~ 23/12/1까지 총 2주간의 기간동안 진행되었고 백엔드가 api 명세서를 만들동안 프론트는 화면설계를 시작했다. 그리고 mock data를 만들어 미리 데이터를 연결하는 과정을 진행했다.

그리고 백엔드가 Api를 전달해줘 api 명세서를 토대로 백엔드와 연결하는 작업을 진행했다.

 

 

결과물

- 숙소 상세 정보 및 장바구니 post

 

- 받아온 인원 count에 따라 장바구니 담기&예약하기 가능 여부 처리 및 예약하기 post

 

 

 

 

- 날짜에 따른 장바구니 담기 가능 여부 처리

 

 

문제점

백엔드와의 협업이 처음이다 보니 뭐가 필요한지 정확하게 파악하는게 어려웠다.

따라서 백엔드가 제공해준 api만 사용하고 있었는데, 마감 전 날 밤에 문제점을 발견했다.

 

지금 숙소상세페이지에 나오는 숙소 리스트들은 개수가 각각 1개씩이다. 즉, 각각의 객체가 다 다른 방이고 그 각각은 개수가 1개이라는 뜻이다.

 

찾은 문제점은 다음과 같다.

내가 위의 영상처럼 SAND(101호)방을 12월 1일부터 12월 2일까지 장바구니에 담으면, 같은 날짜의 같은 객실을 또 장바구니에 담을 수 없어야한다. 

왜냐면 각각의 방 객체는 1개씩이므로 날짜마다 1개씩만 장바구니에 담는 것이 맞는 로직이기 때문이다. 방 개수가 1개인데, 2개를 장바구니에 담는 것은 말이 안되기 때문이다.

하지만 내가 장바구니에 post 요청을 할 때, 해당 방이 장바구니에 담겨서 더 이상 장바구니에 담을 수 없는 로직이 백엔드가 제공해준 api에 존재하지 않았다.

 

이 사실을 마감 전날 밤에 알았고 일단 급한대로 프론트 로직으로 해결해보기로 하였다.

// 장바구니 로직
  const addToCart = async (product: RequestProductDetail, room: Room) => {
    if (!product || !room) {
      console.error('Product or room information is missing');
      return;
    }

    const requestData = {
      roomId: room.roomId,
      roomName: room.roomName,
      price: parseFloat(`${room.price}`) * nights,
      desc: room.description,
      standard: room.standard,
      checkIn: room.checkIn,
      checkOut: room.checkOut,
      reserved: Boolean,
      startDate: defaultDate,
      endDate: defaultDatePlusDay,
    };
    try {
      const existingCartItems = localStorage.getItem('cartItems');
      const cartItems = existingCartItems ? JSON.parse(existingCartItems) : [];
      // 날짜 범위
      const newItemRange = {
        startDate: defaultDate,
        endDate: defaultDatePlusDay,
      };
      // 중복 여부 확인
      const isOverlapping = cartItems.some(
        (item: { startDate: string; endDate: string; roomId: number }) => {
          // 기존 장바구니 아이템의 날짜 범위
          const existingItemRange = {
            startDate: item.startDate,
            endDate: item.endDate,
          };
          // 날짜 범위 겹치는지 확인
          return (
            item.roomId === room.roomId &&
            newItemRange.startDate < existingItemRange.endDate &&
            newItemRange.endDate > existingItemRange.startDate
          );
        },
      );
      if (isOverlapping) {
        openModal();
        console.log('Item already exists in the cart');
      } else {
        cartItems.push(requestData);
        localStorage.setItem('cartItems', JSON.stringify(cartItems));
        const response = await axiosWithAccessToken.post(
          '/api/carts',
          requestData,
        );
        console.log('Added to cart:', response);
        console.log(requestData);
        openCartModal();
      }
    } catch (error) {
      console.error('Error adding to cart:', error);
    }
  };

 

위의 코드처럼 장바구니에 담겼는지 여부를 로컬스토리지에 저장을 해서, 장바구니 post를 할 때 마다 해당 날짜의 객실이 장바구니에 이미 담겼는지 판단해서 장바구니 담기 가능 여부를 체크했다. 

 

하지만 이렇게하니까, 사용자가 user1으로 로그인 후 장바구니에 12월 1일부터 12월 2일까지 a숙소의 b객실을 담고 로그아웃 후 같은 컴퓨터로 user2로 로그인 후 똑같이 12월 1일부터 12월 2일까지 a숙소의 b객실을 담으려하면 이미 장바구니에 담겼다는 모달이 뜨는 문제가 생겼다.

또한 user1으로 장바구니에 담고 다른 컴퓨터로 로그인하면 장바구니에 또 담기는 문제도 발생하였다.

 

따라서 해당 문제를 멘토님께 다음과 같이 여쭤보았다.

 

Q. 지금 현재 숙소 상세 페이지에서 숙소를 장바구니에 담을 때, 같은 날짜의 객실이 중복해서 담기는 것을 방지하려고 로컬 스토리지에 방 정보와 날짜를 저장하고,장바구니에 담을 때 그 숙소가 로컬 스토리지에 있는지 검사한 후 없으면 장바구니에 post하고 있으면 장바구니에 이미 담겨있다는 모달창을 띄우는 형식으로 개발을 진행했는데, 이렇게 하다 보니 같은 컴퓨터로 사용자가 로그아웃하고 다른 아이디로 접속하면 그 로컬 스토리지 정보 때문에 새로운 사용자가 장바구니에 숙소를 담지 않았음에도 담겨있다는 모달이 뜨는 문제가 발생했습니다. 로그아웃 시 로컬 스토리지 비워주면 이 문제는 해결할 수 있는데, 같은 아이디로 다른 컴퓨터로 접속했을 때도 장바구니에 담겨있으면 담기면 안되는데 담기는 문제도 발생해서 이렇게 하면 안될 것 같다고 생각했습니다. 백엔드 측에 장바구니에 담겨있는지 검사할 수 있는 api를 새로 요청해야 되는건지 아니면 어떤 방식으로 이 문제를 해결해야 되는건지 잘 모르겠어서 질문드립니다!

 

 

이렇게 여쭤보니 다음과 같이 답변해주셨다.

 

A. 프론트에서 판단하면 안되는 로직인거 같다. 장바구니에 상품을 담을 때 현재 동일한 상품이 있는지에 대한 체크를 장바구니 담는 api 혹은 그 전 api에서 무조건 체크가 되어야 함

 

 

로컬스토리지에 저장하는 방식 자체가 잘못되었음을 멘토님과의 멘토링 시간을 통해 알게 되었고, 해당 문제는 리팩토링 기간에 백엔드 측에 전달해서 api를 변경해줄 것을 요청했다.

 

 

 

회고

위의 요청사항을 프론트측에서 당연하게 요구했어야 하는 내용이었지만 이게 프론트에서 하는게 맞는지 백엔드에서 하는게 맞는지 확실히 몰랐기에, 해당 내용을 확실하게 처리해달라고 요청하지 못했었다. 이 경험을 통해 백엔드에 정당하게 요구할 수 있으려면, 기능 분류 및 정의가 확실하게 되어야하고 백엔드 지식 또한 어느정도 갖추고 있어야 한다고 느꼈다.