핏메이트 개발 보고서

1. 프로젝트 개요 (Project Overview)

  • 핏메이트는 운동 전문가(강사)와 운동을 배우고 싶은 유저를 연결하여, 1:1 맞춤형 운동 프로그램을 제공하는 서비스입니다.

        유저는 자신의 운동 목표, 선호도에 맞는 운동 강사를 찾아 맞춤형 운동 지도를 받을 수 있으며

        이를 통해 보다 효율적이고 지속 가능한 운동 계획을 세울 수 있습니다.

        강사는 유저의 목표와 상황에 맞춘 체계적인 운동 계획을 제시하고 지도를 통해 유저가 올바른 운동 습관을 형성하도록 돕습니다.


2. 담당한 작업 (Task & Contribution)

맡은 작업
Front-End
컴포넌트
  • Dropdown
  • 체크박스 필터
  • Search
  • SNS 공유
  • Tab
  • 카드 컨테이너
  • 모달 컨테이너
  • 모달: 견적 보내기, 반려 요청, 모바일 필터
  • 카드 템플릿: 트레이너 정보, 레슨 정보, 견적 정보
강사님 찾기 페이지
  • 강사님찾기 페이지 UI 구현
  • 강사님 목록 조회 API 구현 및 연결
  • 검색, 필터 / 필터 초기화, 정렬 기능 구현 및 연결
  • 찜한 강사님 목록 API 연결 (비회원은 목록 숨기기)
강사님 상세 페이지
  • 강사님 상세 페이지 UI 구현
  • 강사님 프로필 조회 API 구현 및 연결
  • 리뷰 목록 조회 API 및 페이지네이션 컴포넌트에 데이터 연결
  • 강사님찾기 카드 컴포넌트에 데이터 연결
  • SNS 공유 컴포넌트에 데이터 연결
  • 지정견적 요청 API 구현 및 기능 연결
대기중인 견적 페이지
  • 대기중인 견적 페이지 UI 구현
  • 내 레슨 목록 API 구현 및 연결
  • 무한 스크롤링 구현
  • 데이터가 비어있을 때 처리 구현
  • 견적 확정 및 반려하기 API 구현 및 연결
대기중인 견적 상세 페이지
  • 대기중인 견적 상세 페이지 UI 구현
  • 견적 상세 조회 API 구현 및 연결
  • SNS 공유 컴포넌트 및 레슨 정보 데이터 연결
  • 견적 확정 API 연결
진행중인 레슨 페이지
  • 진행중인 레슨 페이지 UI 구현
  • 내 레슨 목록 API 연결
  • 데이터가 비어있을 때 처리 구현
받았던 레슨 페이지
  • 받았던 레슨 페이지 UI 구현
  • 내 레슨 목록 API 연결
  • 무한 스크롤링 구현
  • 데이터가 비어있을 때 처리 구현
  • 드롭다운 컴포넌트에 기능 연결
받았던 레슨 상세 페이지
  • 받았던 레슨 상세 페이지 UI 구현
  • 견적 상세 조회 API 구현 및 연결
  • SNS 공유 컴포넌트 및 레슨 정보 데이터 연결
  • 확정 견적 유무 메시지 표출
레슨 내역 페이지
  • 레슨 내역 페이지 UI 구현
  • 내 레슨 목록 API 연결
  • 대기중, 만료된, 취소된 레슨 목록 조회 가능
  • 툴팁 구현
받은 요청 페이지
  • 받은 요청 페이지 UI 구현
  • 레슨 요청 목록 API 구현 및 연결
  • 무한 스크롤링 구현
  • 체크박스 필터 컴포넌트에 기능 연결
  • 정렬, 검색 기능 연결
  • 견적 보내기 및 반려하기 API 구현 및 연결
랜딩페이지 제작
  • 랜딩 페이지 제작
404 페이지 제작
  • 잘못된 경로일 시 표출되는 404 페이지 제작
접근 제한 페이지 제작
  • 접근 제한 페이지 접속 시 표출되는 접근 제한 페이지 제작
웹 아이콘 제작
  • 웹 아이콘 제작
전체 UI 수정
  • 서비스 전체 UI 수정
공통 컴포넌트 및 역할 분배
  • 요구사항에 맞춰 역할 분배
프론트엔드 기초 세팅
  • 패키지 설치 및 config 설정, 파일 구조 설정
PR 템플릿 세팅
  • PR 템플릿 작성하여 해당 템플릿으로 자동 적용되도록 설정
프론트엔드 일정 관리
  • 초기에 일정 회의 후 일정에 맞게 구현 상황 파악
팀 노션 정리
  • 프론트엔드 및 비어있는 문서 작성
README.md 작성
  • 프론트엔드 README 작성
유저 / 페이지 플로우 제작
  • 피그마를 이용하여 유저 / 페이지 플로우 제작
최종 발표 PPT 제작
  • 최종 발표 PPT 제작

3. 기술적 성과 (Technical Achievements)

  • 기술 스택
    - 공통
       Environment : VS Code, Prettier, ESLint, TypeScript, npm
       Infra: EC2, PM2, Nginx, Let's Encrypt SSL, GitHub Actions, docker, Git & GitHub, Amazon S3
       Real-time: SSE (Server-Sent Events), Socket.io
       Tools: Notion, Slack, Discord, Gather, Zoom

    - Front-End: Next.js, Tailwind CSS, React Query, Axios, Figma
    - Back-End: Node.js, NestJS, Express.js
       Authentication: JWT, OAuth 2.0, Passport, bcrypt, async-local-storage
       Scheduling: @nestjs/schedule
       Queue: BullMQ
       Email: Nodemailer
       Database: MongoDB, PostgreSQL, Redis
       Etc: Swagger

  • 구현한 주요 기능
    - 무한 스크롤링 : useInfiniteQueryreact-infinite-scroller 라이브러리를 이용하여 무한 스크롤링 구현
    - RoleGuard 훅 : 로그인 시 해당 Role에 따른 접근 제한 훅 구현, 접근 제한 경로로 접속 시 비회원은 로그인 페이지로,
                                 회원은 접근 제한 페이지로 이동
    - 체크박스 필터 : 서비스, 성별, 견적 요청 방식, 지역으로 필터링이 가능
    - Dropdown 컴포넌트 : 필터와 정렬 기능을 수행. 부모 컴포넌트인 Dropdown 컴포넌트 아래로 DropdownMenu,
                                           DropdownList
    컴포넌트를 추가하여 컴포넌트 세분화
    - 필터링 : 필터는 다중 선택 가능, 필터 초기화 버튼을 누르면 값과 선택된 값이 초기화되도록 구현
    - 유효성 검사 훅 : 견적 보낼 시 데이터 유효성 검사 커스텀 훅 구현
    - toast 라이브러리: toast 라이브러리를 활용하여 알림 UI 개선

4. 문제점 및 해결 과정 (Challenges & Solutions)

  • 문제점 : 사용자 로그인 시 데이터 불일치
  • 리액트 쿼리를 통해 데이터 페칭을 처리하는 과정에서, 사용자가 로그아웃하고 
    다른 사용자로 로그인할 때 이전 사용자의 데이터가 화면에 표출되었습니다.
     
    새로고침을 하지 않으면 현재 로그인한 사용자의 데이터로 업데이트되지 않고, 
    이전 사용자의 데이터가 그대로 남아 있었습니다.
     
    [문제 분석]
    리액트 쿼리는 쿼리 키를 기준으로 캐시된 데이터를 관리하는데,
    만약 쿼리 키가 고유하지 않으면 여러 사용자가 동일한 쿼리 키를 사용하면서 
    이전 사용자의 데이터를 계속해서 가져올 수 있다는 사실을 간과하고 있었습니다.
     
    따라서 로그아웃 후 다른 사용자가 로그인하더라도 쿼리 키가 동일하게 유지되며, 
    이전 사용자의 데이터가 캐시에서 계속 반환되어 화면에 표시되었던 것입니다.
     
    [해결 과정]
    쿼리 키에 사용자 고유 ID를 추가
    : 각 사용자의 데이터를 구분하기 위해 쿼리 키에 고유한 값인 
       userId를 포함시키는 방식으로 문제를 해결했습니다.

5. 협업 및 피드백 (Collaboration & Feedback)

  • 일정 파악 : 프론트엔드 팀장으로써 어느 정도 일정을 파악하며 진행하고 있었지만, 일정 내에 구현이 늦어지는 팀원에게 너무 무리와 부담을 주는 것 같아 일정에 관해 확실하게 말하지 못했습니다. 이로써 발표 전날까지 코드를 수정하는 일이 생겼고, 불완전하게 마무리를 한 것 같아서 아쉽습니다.
  • 무리한 역할 : 조금 많은 역할을 맡게 되어서 버겁기도 했지만, 하겠다고 한 이상 마무리를 하는 것이 맞다고 생각했습니다. 하지만 이로 인해 정작 제 코드를 수정할 시간이 줄어들고, 정한 일정에 맞지 않게 진행되는 것을 느끼면서 제 자신이 무리를 했다고 깨달았습니다.이렇게되면 자신 뿐만 아닌 팀원들에게도 피해를 끼치는 일이 될 수 있겠다 느꼈고, 다음부터는 적당한 분량을 맡으면서 퀄리티와 버그를 줄이는 것이 더 좋을 것 같다는 생각을 하게 되었습니다.

6. 코드 품질 및 최적화 (Code Quality & Optimization)

  • 유지 보수성 : 보는 사람들의 이해를 돕기 위해 최대한 각 컴포넌트, 페이지마다 너무 길거나 복잡한 로직을 단순화시키거나 보기 쉽게 작성했습니다.
  • 중복 코드 제거 : 최대한 중복된 코드를 줄이기 위해 공통적으로 쓸 수 있는 부분은 따로 빼서 사용했습니다.
  • 코드 리팩토링 : 기존 코드를 더 깔끔하게 리팩토링하고, 쿼리의 경우 여러 곳에 동일하게 쓰이는 부분이 많아서
                            따로 쿼리 파일을 모아 관리하였습니다. 이로 인해 중복 코드를 더 줄일 수 있었습니다.

7. 향후 개선 사항 및 제안 (Improvements & Recommendations)

  • 상수 활용 : 클래스네임 같은 경우, 동일한 스타일을 쓰게 되는 경우가 많았는데 이를 따로 상수로 빼서 사용하고 싶었지만 시간이 부족하여 진행하지 못했습니다. 이 점이 아쉬웠고, 나중에는 미리 상수로 작성한 뒤 골라쓰는 방식으로 하는 것이 좋을 것 같다는 생각을 했습니다.

8. 본인이 잘했다고 생각하는 PR

  • https://github.com/FS-part4-1team-FitMate/FitMate-FE/pull/60
  • 선정 이유 : 작성한 PR 제목에 맞춰서 해당 기능만을 수행한 PR이었고, 수정한 파일들 각각 어떤 부분을 수정했는지 간략히 적어놓았기 때문에 리뷰어가 보기 편했을 것이라 생각했습니다. 또한 제가 리뷰를 하게 될 경우, 이런 형식의 PR 내용을 본다면 편하겠다고 생각해서 선정했습니다.

+ Recent posts