Skip to content

Conversation

@win-luck
Copy link
Contributor

@win-luck win-luck commented Dec 9, 2023

프로젝트 개요

<다이어릿>은 음식을 촬영하면 칼로리를 대략적으로 계산해주는 기존 서비스에서 영감을 받아, 가공식품의 영양성분표를 촬영하면 칼로리를 추출해주는 OCR 기능을 추가로 결합해 식습관 기록의 사각지대를 해소하는 데 기여하는 Food Capture 서비스입니다.

  • 음식이나 영양성분표를 촬영하면 일정 시간 후 영양성분을 추출하실 수 있습니다.
    • 실제 음식의 경우 두잉랩의 foodlens에서 제공하는 외부 API를 사용합니다.
    • 영양성분표의 경우 Pororo OCR을 기반으로 자체 구축한 OCR 서버를 활용합니다.

Diary

  • [오늘의 영양] 화면에서 오늘 촬영한 음식들에 대한 영양분이 실시간으로 결산됩니다.
  • [다이어리] 화면에서 오늘 촬영한 음식들에 대한 정보를 확인할 수 있습니다.
  • [즐겨찾기] 기능을 통해 자주 먹는 음식을 등록하여 재촬영 없이 편리한 다이어리 추가가 가능합니다.
  • [프로필] 화면에서 개인정보 및 목표로 설정된 기준섭취량을 확인하고 직접 수정하실 수 있습니다.

Analysis

  • [일기 분석] 화면에서 최근 7일 및 4주 간의 영양소별 섭취 현황을 그래프로 제공합니다.
  • [자세히 보기]를 통해 이번 주의 구체적인 식습관 점수 현황, 최근 Best, Worst 음식들을 확인하실 수 있습니다.
  • [주간 랭킹] 화면에서 검색 기능을 통해 특정 유저를 팔로우 혹은 팔로우 취소할 수 있고, 자신이 팔로우한 유저들의 주간 식습관 점수를 확인하실 수 있습니다.
  • 친구들과 함께 앱을 사용하며 식습관 개선 목표를 달성하기 위해 서로 경쟁해보세요!

Springboot 궁금증

  • mySQL, JPA를 기반으로 2명이서 user/food 패키지를 중심으로 서로 협업하며 약 2~3개월간 프로젝트를 진행했습니다.
  • 테스트코드를 중심으로 기능 구현을 풀어나가고자 했으며, 원래 실제 DB에 의존하여 작성하였는데, Mockito로 바꾸었습니다.
    • 다만 Mockito의 주요 테스트 관련 메서드(given, when)들이 반환값이 없는 메서드(수정, 삭제 등)에 대한 원활한 테스트 어려웠습니다.
    • 서포터분들은 수정과 삭제에 대한 반환값을 void로 처리하시는지, 아니면 따로 반환값을 잡아주시는지 궁금합니다. 저는 수정과 삭제의 경우 클라이언트가 Status Code 200만 확인해도 무방하다고 생각하여 둘 다 void로 처리했습니다.
  • 후반부 Redis로 ResponseDto에 대한 캐싱을 하려다가 직렬화 관련 오류가 과하게 발생해 캐싱을 중단했습니다. 따로 인덱스는 없이 캐싱을 시도했는데, 인덱싱은 조회 기능의 성능을 높이는 대신 생성/수정/삭제의 성능을 낮추는 걸로 알고 있습니다.
    • 클라이언트 입장에서 데이터의 변동을 일으키는 트리거가 많을 경우 따로 백에서 캐싱이나 인덱싱을 무리하게 도입하지 않는 것이 더 나은 방법일까요?
  • RequestDto에 대한 @Valid 기반 유효성 검사를 진행했고 문제 발생 시 GlobalExceptionHandler를 통해 대응했습니다.
  • Jwt 토큰을 관리하되, 따로 Controller 매개변수에 삽입하지는 않았습니다. 저희 프로젝트는 @PathVariable로 userId를 가져오는데, 보통 토큰에서 유저id를 빼내는 것으로 알고 있습니다.
    • 그렇다면 유저id가 필요한 모든 Controller 메서드에 다 토큰 -> 유저Id 메서드가 강요되는 걸까요? 혹시 더 나은 방안이 있는지 알고 싶습니다.
  • 기능 이슈가 있었습니다. 즐겨찾기에서 특정 음식을 즐찾 해제하면, 음식은 별을 가지지 않습니다. 저는 음식 -> 즐겨찾는 음식은 일대 다로 하되 예외처리로 같은 음식은 하나만 등록되게 만들었고, 즐겨찾는 음식 -> 음식은 제약 없는 일대다를 유지하였습니다.
    • 즐겨찾기에서 특정 음식을 해제했을 때, 이 음식으로부터 바로 태어난 음식들의 FK가 null로 자동으로 바뀔 줄 알았는데 그렇지 않아서 따로 명시적으로 처리해 주었습니다.
  • 그래프에 넣을 데이터를 위해 필드에 선언된 ArrayList가 꽤 많습니다. 혹시 이런 통계 관련 데이터를 백에서 넘겨줘야 할 때 더 바람직한 구조가 있을지 여쭙고 싶습니다.
  • 1+N 문제도 일부 Repository에 발생 중입니다. 다양한 대응 방법이 있는 것으로 알고 있는데 저는 따로 Repository 메서드에 FETCH JOIN 연산을 도입하고자 합니다. 혹시 서포터님들께선 실전에서 어떤 전략을 채택하시는지 알고 싶습니다. QueryDSL을 도입해야 할까요?

synoti21 and others added 30 commits November 6, 2023 18:53
Feat: FoodService 분석 및 FoodControllerTest 구현 (#50)
�Fix: 카카오로그인 에러 수정 (#51)
Refactor: 카카오로그인 응답 형식 수정 (#58)
win-luck and others added 30 commits January 16, 2024 15:31
Refactor: �즐찾음식 관계단절 이슈 등 리팩토링 (#142)
Refactor: jwt 토큰 추출 방식 개선 관련 food 패키지 리팩토링 (#145)
…h-token

Feat: JWT AccessToken & RefreshToken 구현
hotfix: 메소드 이름 변경에 의해 테스트 코드 수정
Fix: ResponseJwtDto에 userId 추가 (#152)
Fix: Jwt 일부 코드 복구 및 RefreshToken 만료 관련 예외처리 반영 (#152)
Fix: UserRepository entityGraph 관련 오류 수정 (#152)
Fix: user객체 roles 지연로딩 삭제(#152)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants