Skip to content

Lazy-Board/.github

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 

Repository files navigation

Lazier - 맞춤형 정보 조회 서비스

📜 기술 블로그

🙆‍♂️ 팀원 소개

image image image image image image
Front-End Front-End Back-End Back-End Back-End Back-End
김태영 장지연 👑하민성👑 서인덕 윤윤성 이혜린

👨‍💻 프로젝트 소개

🎇 Slogan - 바쁜 현대사회에서 조금 더 게으른 당신의 삶을 위해

lazy

❓ 기획 배경

image

  • 계좌 정보를 확인하려면 은행 사이트를, 뉴스를 보려면 신문사 뉴스 사이트/어플을 방문해야 한다.
    • 하지만 해당 어플리케이션에서 보는 기능은 제한적이다. 주로 단순한 정보를 이용한다. ('오늘 날씨', '오늘 할 일', '지금 뉴스')
  • 관심있는 나의 정보와 일정 등을 간편하고 한눈에 파악할 수 있는 웹 어플리케이션을 생각하게 되었다.

☝️ 해결 컨셉 : Easy One For All

  1. 나에게 필요한 정보만 골라서 직관적으로 편하게 보자
  2. 간편하게 모바일로 볼 수 있는 웹 어플리케이션

👨 목표: 기대 효과(USER)

  1. 여러 포털 사이트 / 앱을 사용하지 않아도 원하는 정보를 한 페이지에서 확인 할 수 있다.
  2. 원하지 않는 정보는 보지 않도록 모듈화된 기능을 선택하여 나만의 입맛에 맞는 페이지를 구성할 수 있다.

=> 최종 총 8개의 기능모듈 + 메인모듈로 구성된 모바일 웹 어플리케이션 구상.

🤝 협업 과정

🧭 Ground Rule

Ground Rule = Growth Rule

Rule : 모든 원칙은 우리의 성장과 공동의 목표 달성을 위해 존재합니다.

image

  • 스크럼 : 매일 노션 양식에 작성
  • 코드리뷰 : 주 2회 (요일 미정) / 개발기간은 백엔드, 프론트 파트별로 진행
  • 회의시간 : 월~금 / 일요일 오후 10시
  • 특이사항 : 매주 토요일은 회의 X, 텍스트로 작업내용 공유

💼 Work Time

image

✔ Daily Scrum : 정규 스크럼 주 6일 + @

image

👨‍👨‍👧‍👧 Google Meet - 미팅: Daily Scrum

image

🤼‍♀️ Gather - 협업공간: 수시 회의/협업

image

🔑 Git 전략: Branch & PR

image

1. Repository / Branch Manangement

  • 본 프로젝트는 메인 + 기능별 8개, 총 9개 모듈로 구성. 프론트 엔드/백엔드 서버 를 분리하여 레포지터리 구성.
  • 각 담당자는 담당모듈 레포지터리에 커밋/푸쉬할 베이스 프로젝트 생성/셋팅 후 터미널에서 아래의 커맨드로 초기 브랜치 셋팅 후 first commit.
    • main : 최종 배포를 위한 브랜치 (**master는 사용하지 않는다)
    • dev : 개발을 위한 브랜치 (모든 개발내용은 해당 브랜치위에서 feat단위로 서브 브랜치 생성/commit 후 해당 브랜치로 Merge한다.
    • test : 배포 전 테스트 서버 구동을 위한 브랜치.

2. PR Strategy

  • Release(Dev Branch로 Merge)는 전원의 감수 및 동의로 진행한다.
  • HotFix는 과반수(2명) 이상의 동의를 받는다.
  • 모든 파트원(Back : 4 / Front : 2)에게 리뷰(확인)를 받아야 Release를 진행할 수 있다.

👨‍🔧 기술 스택

Front-End

Back-End

Production & Deploy

Collaboration tool

⚙️ Architecture

image

📑 ERD

image

📱 Demo

회원 기능 뉴스
회원가입, 일반로그인, 소셜로그인, 비밀번호 찾기 뉴스 모듈
날씨 출근정보
날씨 모듈 출근정보
유튜브, 오늘의 명언, TODO 리스트 주식
유튜브, 오늘의 명언, 투두 리스트 주식
환율
환율

✨ 프로젝트 주요기능

🔐 회원 기능

🔑 회원가입 및 로그인, 비밀번호 찾기

  • 회원가입
    • 유효한 이메일 주소가 있으면 회원가입이 가능하다.
    • 이메일 인증을 시도한다.
  • 로그인
    • 회원가입을 통한 로그인과 OAuth를 통한 간편 로그인이 있다.
    • 모두 토큰 기반의 로그인으로 만료 시간이 지나면 토큰을 재발급하여 로그인 상태를 유지한다.
  • 비밀번호 찾기
    • 등록된 이메일과 연락처를 통해 비밀번호를 초기화할 수 있다.
    • 이메일과 연락처를 확인해서 회원의 이메일로 비밀번호 초기화 링크가 전송된다.

🗂️ 모듈 저장, 수정, 조회

모듈 저장, 수정, 조회
모듈등록 (2)
  • 모듈 저장
    • 처음 로그인할 시 보고 싶은 모듈을 체크할 수 있다.
  • 모듈 조회 및 수정
    • 메인 페이지에서 보고 싶은 모듈을 조회 및 업데이트한다.

💁‍♂️ 회원 수정, 🔏 비밀번호 변경 , 🤦🏻‍♀️ 회원 탈퇴

회원 수정, 비밀번호 변겅, 회원 탈퇴
회원 수정, 비밀번호 변경, 회원 탈퇴
  • 회원 수정
    • 회원가입 시 입력한 정보를 조회하고 수정할 수 있다.
    • 소셜 로그인 사용자는 비밀번호를 제외한 정보를 수정할 수 있다.
    • 프로필 사진을 등록, 수정, 삭제할 수 있다.
  • 비밀번호 변경
    • 일반 로그인 사용자는 비밀번호 변경을 이용할 수 있다.
    • OAuth 로그인 사용자는 이용할 수 없다.
  • 회원 탈퇴
    • 탈퇴 후에는 탈퇴한 사용자 계정으로 로그인할 수 없다.

🖥️ 모듈 기능

📰 뉴스

  • 각 언론사별 주요뉴스를 볼 수 있는 모듈이다.
  • 언론사는 총 61개의 언론사 정보를 가지고 있다.
  • 해당 모듈 최초 등록시 사용자의 정보는 기본값으로 설정되어 메인 페이지에서 기본으로 설정된 ‘연합뉴스’의 주요뉴스들을 최근 순으로 볼 수 있다.
  • 사용자는 메인에서 보고 싶은 언론사를 1개 선택 할 수 있고, 그 외 나머지 언론사의 뉴스 정보는 상세 페이지에서 확인 가능하다. (메인에서 볼 수 있는 주식 정보 선택은 수정이 가능하다.)
  • 사용 기술
    • BackEnd
      • JSoup을 이용하여 주식 정보를 Scraping 했다.
      • Spring Batch를 적용하여 1시간 마다 1번씩 뉴스 기사를 저장하고, 하루에 1번 오래된 뉴스 정보를 삭제 및 언론사 정보를 저장하도록 구현하였다.
    • FrontEnd
      • Axios를 이용하여 통신하였다.
      • recoil을 이용해 상태값을 저장, 사용하였다.

📈 주식

  • 주식 정보를 보여주는 모듈이다.
  • 주식 정보는 10개의 회사 주식 정보를 가진다.
  • 해당 모듈 최초 등록하면 3개 회사 주식 정보를 메인 페이지에서 볼 수 있다.
  • 상세페이지에서 메인화면에 보이는 주식 정보를 수정할 수 있다. (상세페이지 : 10개 회사 주식 정보 포함)
  • 사용 기술
    • BackEnd
      • JSoup을 이용하여 주식 정보를 Scraping 했다.
      • Spring Batch를 적용하여 1시간 마다 1번씩 정보를 삭제후 저장하도록 구현하였다.
    • FrontEnd
      • Axios를 이용하여 통신하였다.
      • recoil을 이용해 상태값을 저장, 사용하였다.

💰 환율

  • 환율 정보를 보여주는 모듈이다.
  • 환율정보는 10개 국가의 환율 정보를 가진다.
  • 해당 모듈 최초 등록하면 4개 국가의 환율 정보를 메인 페이지에서 볼 수 있다.
  • 상세페이지에서 메인화면에 보이는 환율 정보를 수정할 수 있다. (상세페이지 : 10개 국가의 환율 정보 포함)
  • 사용기술
    • BackEnd
      • JSoup을 이용하여 환율 정보를 Scraping 했다.
      • Spring Batch를 적용하여 1시간 마다 1번씩 정보를 삭제후 저장하도록 구현하였다.
    • FrontEnd
      • Axios, recoil을 사용해 비동기 통신 및 데이터를 저장, 관리했다.
      • 환율 정보 최대 4개까지만 체크 가능하도록 프론트단에서 처리했다.

🌦️ 날씨

  • 날씨 정보를 알려주는 모듈이다.
  • 모듈 등록시 사용자는 지역 정보를 등록해야 날씨 정보를 볼 수 있다.
  • 사용자는 1개의 지역 정보를 등록 할 수 있다. (지역 정보는 수정이 가능하다.)
  • 지역 정보가 잘못될 경우 Error가 발생한다.
  • 사용 기술
    • BackEnd
      • JSoup을 이용하여 날씨 정보를 Scraping 한다.
      • Spring Batch를 적용하여 1시간 마다 1번씩 정보를 저장하고, 하루에 1번씩 오래된 정보를 삭제하도록 구현하였다.
    • FrontEnd
      • Axios, React query, Recoil을 사용해 서버 데이터를 비동기적으로 관리하고 사용다.
      • React-query를 사용해 서버 데이터가 변경될 시 변경된 데이터가 새로고침 없이 fetch 되도록 했다.

🚗 출근정보

  • 출근길 소요 시간을 알려주는 모듈이다.
  • 사용자는 1개의 출근길 정보를 등록 할 수 있다. (출발지&도착지 정보는 수정이 가능하다.)
  • 주소가 잘못될 경우 Error가 발생한다.
  • 사용 기술
    • BackEnd
      • Naver API 를 사용해 위경도 정보를 저장한다.
      • Kakao API 를 활용해 출발지 도착지간 소요 시간을 조회한다.
    • FrontEnd
      • Axios, React query, Recoil을 사용해 서버 데이터를 비동기적으로 관리하고 사용하였다.
      • KAKAO MAP API를 사용해 카카오맵을 화면에 출력하고, 서버에 보낸 데이터를 받아 도착지 위치를 지도 중앙에 표시하도록 했다.
      • React-query를 사용해 서버 데이터가 변경될 시 변경된 데이터가 새로고침 없이 refetch 되도록 했다.

▶️ 유튜브 🧙 명언 📝 TODO 리스트

  • 유튜브: 크롤링
    • 실시간 급상승 동영상을 볼 수 있는 모듈이다.
    • 기술 설명 :
      • BackEnd
        • JSoup을 활용하여 Scraping 한다.
        • Spring Batch 를 적용하여 1시간 마다 1번씩 정보를 저장하고, 하루에 1번씩 오래된 정보를 삭제하도록 구현하였다.
      • FrontEnd
        • Axios를 이용하여 통신하였다.
        • recoil을 이용해 상태값을 저장, 사용하였다.
  • 명언
    • 명언을 볼 수 있고, 사용자가 설정한 개인 문구를 볼 수 있는 모듈이다.
    • 사용자 문구는 최대 1개의 문구만 등록이 가능하다. (문구는 수정 및 삭제가 가능하다.)
    • 명언은 DB에 미리 저장 되어 있어 랜덤으로 조회 하도록 구현하였다.
  • TODO 리스트
    • 사용자의 할 일 목록을 보여 줄 수 있는 모듈이다.
    • 사용자는 최대 3개의 할일 목록을 만들 수 있습니다. (목록은 완료 후 추가 가능하다.)

☄️ 회고 및 트러블 슈팅

○ Front-End

1. JWT Refresh 토큰

  • CORS 에러 발생
    • 따로 proxy 설정을 해줌.
    • 서버에 요청시 axios interceptor를 사용해 로그인 권한 오류가 발생했을 때, refresh 요청값을 전달해 주는데 refresh 과정에서 그전에 발급받은(유효기간이 만료된 토큰 값이 들어감 ) </React.StrictMode>가 렌더링을 두번 요청해서 로컬 스토리지 값이 변동됨.
    • recoile state 에서 토큰값 관리하여 해결

2. Minified React Error 310 오류

  • useRecoilValueLoadable 을 사용해 로딩처리를 해주는 과정에서, 로딩처리 내용이 react-hook 보다 먼저 선언되어 hooks 선언에 영향을 주는 부분이 있어 생긴 오류였다 로딩처리에 따른 조건부 렌더링으로 해결

3. GET한 데이터를 filter시 빈 배열로 출력되는 오류

  • object형태 데이터라 Object.entries().filter().map()으로 변환해 filter했으나 AxiosResponse에 필요한 타입이 제대로 지정되어 있지 않아 빈 배열로 출력됨
    • typescript type 설정해 filter된 데이터를 받아 조건부 렌더링함

4. Minified React Error 426 오류

  • 데이터 로드하는 동안 UI가 중단되는 상황이 발생해서 생기는 오류
    • useRecoilValue를 useRecoilValueLoadable로 변경해 loading 상태 처리

○ Back-End

1. JWT 토큰

  • CORS 충돌
    • allowedOrigins도 설정했는데도 CORS 충돌이 일어남. OPTION으로 요청이 왔을 때 Filter를 거치지 않도록 하여 해결

2. AWS S3

  • Url 클릭시 웹에서 열리지 않고 자동으로 다운되는 문제
    • content type을 지정해서 올리지 않으면 자동으로 "application/octet-stream"으로 고정이 되어 자동 다운이 돼서 타입 별로 content type을 지정해서 해결

3. CI/CD(Jenkins)

  • 도커로 Jenkins 이미지 받고 컨테이너로 실행한 상태에서 홈페이지가 열리지 않는 문제
    • EC2 인스턴스 보안 설정에서 인바운드 규칙 편집 후 해결

4. Spring Batch

  • 기존에 있던 DB에 배치를 적용하려던 중 Naming 으로 인한 Entity 에러 발생
    • Hibernate naming 을 "PhysicalNamingStrategyStandardImpl"로 적용하고, MariaDB 대소문자 구분 가능하도록 설정되어 있어서 생긴에러. ⇒ Hibernate naming 을 "SpringPhysicalNamingStrategy" 로 변경
    • MariaDB 대소문자 구분 안하도록 설정(AWS RDS 파라미터 그룹 메뉴에서 lower_case_table_names를 1로 변경

5. DataBase

  • 로컬 테스트시 사용한 H2 DB에서 발생한 에러
    • ID 값을 GenerationType.IDENTITY 로 설정시 H2 에서 에러 발생
    • H2에서 AUTO_INCREMENT를 사용하기 위해선 IDENTITY 보단 SEQUENCE를 사용한다는 것을 알게 됨(SEQUENCE 로 변경후 정상 작동 확인 완료) => DB마다 IDENTITY 생성에 사용하는 문법의 차이가 있다.

6. 크롤링 관련 Issue

1) Youtube 스크래핑시 데이터 구조의 문제: 크롤링시 구조가 깔끔하게 되어있지 않은 것도 많다.

→ 우아하게 스크래핑을 구현하려 했으나 데이터 형식상 Parsing이 어려운 문제로 인해 다중 Json 구조로 10회 정도의 Depth로 파고 들어가야 원하는 정보를 꺼내올 수 있었다.

image

2) Bot 차단: 빈번한 페이지 호출로 인해 해당 스크래핑 사이트에서 서버 IP를 차단

→ 사람으로 인식할 수 있도록 Connection객체의 http헤더 설정 / 크롤링시 일정시간 sleep 등의 프로세스 추가.

💡 느낀 점

Front-End

Fake Api가 아니라 실제 서버의 데이터를 받아서 적용해보고 여러가지 예상하지 못한 상황과 마주하며 많은 것을 배웠습니다.

Back-End

개발 업무의 전반적인 과정을 경험할 수 있었고, 많은 소통을 하면서 협업을 해야 좋은 결과물이 나올 수 있다는 것을 느꼈습니다. 많은 에러와 디버깅, 삽질로 채워진 날들이 많았지만 팀원들 모두가 책임을 다해 충실하게 수행해주신 덕분에 무사히 프로젝트를 완성할 수 있었다고 생각합니다.

아쉬운 점

다양한 기술을 시도해보고 싶었지만 기획 컨셉과 맞지 않아 제대로 시도해보지 못한 부분이 아쉬운 부분으로 남습니다.

About

사용자 맞춤형 정보조회 서비스

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published