[토이프로젝트] 1차 MVP 기획

2025. 2. 7. 11:12
728x90

1. 프로젝트 개요 (1차 MVP)

  • 프로젝트명 : 우리집에 가면 (공유하는 마이홈 냉장고 재고관리 시스템)
  • 버전 : MVP 1.0
  • 목표 
    • 식료품 및 생활용품의 재고를 디지털로 관리
    • 유통기한 알림을 통해 폐기 및 낭비를 줄이고, 적절한 시점에 소비
    • 공동 구성원(가족/룸메이트 등) 간 재고 공유
  • 주요 기능
    • 사용자 가입/인증
    • 그룹 생성/초대/관리
    • 재고(품목) CRUD
    • 유통기한 알림 (이메일/대시보드)
    • 간단한 대시보드 (현재 재고 목록, 임박 품목 표시)

 

2. 기능 상세 기획

1) 사용자 가입 및 인증

기능 개요 - SNS 로그인만 사용
- 로그인 시 JWT 토큰 발급
- 로그아웃 시 클라이언트 측 토큰 폐기
사용자 스토리 SNS 로그인
- 사용자는 SNS 로그인 버튼 클릭 후 SNS 인증 페이지로 리다이렉트 -> 사용자 로그인 후 SNS 측에서 Authorization Code/Access Token 발급 -> 콜백(redirect URI)로 돌아옴
- 서버가 SNS API를 통해 사용자 정보(고유 id, 이메일, 이름 등)을 받아와 서버 DB에서 해당 고유 id를 검색 
- 이미 존재하는 유저이면 로그인 처리
- 없으면 신규 유저 레코드 생성 후 로그인 처리
- JWT 토큰 발급하여 클라이언트에 전달, 만료 시간 설정(15분~1시간)
- Refresh Token을 두어 Access Token이 만료되어도 재로그인 없이 새 Access Token을 받을 수 있도록 함, 만료기간 (7일~30일) 설정
- 리프레시 토큰을 서버 단(DB 또는 캐시(Redis))에서 저장
- 프론트에서 토큰(쿠키/스토리지)을 저장 후 API 요청 시 헤더에 포함
로그아웃
- 서버가 해당 Refresh Token을 삭제하거나 블랙리스트에 올려 무효화
인증 보안
- JWT 토큰 발급, 만료 후 재발급 로직 설정
- HTTPS 적용
API 설계 로그인 GET /auth/{provider}  (미정)
로그인 처리 및 JWT 발급 GET /auth/{provider}/callback (미정)
로그아웃 POST /api/auth/logout
토큰 갱신 POST /api/auth/refresh

 

⬇️ SNS 로그인 처리 세부 플로우 (아직 미정)

더보기

1. 사용자가 프론트에서 SNS 로그인 버튼 클릭

2. 프론트가 SNS 인증 페이지로 이동(redirect)

3. 사용자가 SNS 인증/동의를 거치면 SNS가 프론트 쪽 콜백 URL로 authorization code를 넘겨줌 

4. 프론트는 URL에서 code를 추출한 뒤 백엔드 API로 전송 (ex. POST /api/auth/google) 

5. 백엔드는 JSON으로 code를 받고, 해당 code로 SNS에 access token으로 교환 

6. 그 access token으로 SNS 사용자 정보 조회

7. DB에서 provider, provider_user_id로 조회하여 가입처리 혹은 로그인 처리

8. JWT 발급 & JSON 응답 

 

2) 그룹 생성 및 초대/관리

기능 개요 - 그룹 : 하나의 공동체를 나타내는 단위
- 초대 : 그룹에 새 멤버를 추가할 때
- 사용자 한 명은 여러 그룹에 속할 수 있음 (추가 확장 고려)
사용자 스토리 그룹 생성
- 로그인한 사용자가 그룹 생성 버튼 클릭
- 그룹 이름 입력
- 서버에 생성 요청 -> 그룹 생성 & 생성한 사용자는 그룹 admin 권한
- admin 권한은 그룹명 수정/멤버 추방 가능
- 그룹 이름 중복 여부는 중요치 않음 (UID로 구분)
그룹 초대
- 그룹 상세 페이지에서 '멤버 초대' 클릭
- 초대 링크 생성 또는 이메일로 초대 전송 (ex.myhome.com/invite/토큰)
- 초대 링크 유효기간 설정 (ex. 3일)
- 새로운 사용자가 초대 링크 접속 -> 로그인/회원가입 후 그룹에 조인
그룹 목록
- 로그인 후 사용자가 속한 그룹들을 조회
- 하나를 선택하면 해당 그룹의 재고 대시보드로 이동
API 설계 그룹 생성  POST /api/groups
그룹 초대 POST /api/groups/{groupId}/invite
그룹 목록 GET /api/groups
그룹명 수정 PUT /api/groups/{groupId}
멤버 추방 DELETE /api/groups/{groupId}/members/{memberId}

 

3) 재고 CRUD

기능 개요 - 품목의 추가/조회/수정/삭제 기능
- 소비/폐기 기록
사용자 스토리 품목 추가
- 대시보드에서 '새 품목 추가' 버튼 클릭
- 이름, 카테고리, 유통기한, 수량 입력 후 저장
- 유통기한 날짜는 현재 날짜 이전이 입력되지 않도록 설정
- 카테고리는 사전에 정의된 목록
- 등록된 품목은 대시보드 목록에 표시
품목 조회
- 대시보드에서 해당 그룹 내 모든 품목 목록 표시
- 필요한 경우 검색/정렬 (이름/유통기한 순)
품목 수정
- 품목 상세 클릭 -> 편집 화면
- 수량, 유통기한, 카테고리 등 수정 가능
품목 삭제
- 더 이상 사용하지 않는 품목을 삭제
- 삭제 전에 폐기 처리 확인 모달
소비/폐기 기록
- actionType은 consume/discard 중 하나
- 소비/폐기 기록을 로그로 남김
- 수량은 음수가 되지 않도록 검증
API 설계 품목 추가 POST /api/groups/{groupId}/items
카테고리별 품목 조회 GET /api/groups/{groupId}/items
품목 상세 조회 GET /api/groups/{groupId}/items/{itemId}
품목 수정 PUT /api/groups/{groupId}/items/{itemId}
품목 삭제 DELETE /api/groups/{groupId}/items/{itemId}
소비/폐기 기록 POST /api/groups/{groupId}/items/{itemId}/consume
소비/폐기 기록 조회 GET /api/groups/{groupId}/consumption-logs

 

4) 유통기한 알림

기능 개요 - 유통기한 임박 품목에 대한 알림 발송
- 정해진 시점 (D-5, 당일)에 알림
사용자 스토리 유통기한 알림
- 사용자는 특정 품목이 유통기한에 다가오면 알림을 받음.
- 조건에 맞는 품목이 있으면 대시보드 알림 섹션에 목록 표시
API 설계 알림 조회 GET /api/notifications
   
   
   
   

 

⬇️ 고민사항 1)

더보기

1. 특정 시각에 DB의 모든 품목을 체크하는 방법에 대한 고민

1) 크론 잡 / 스케줄러 방식 : 매일 정해진 시각에 서버에서 DB의 모든 품목을 조회하고, 유통기한이 임밥한 품목을 찾아 알림을 전송

  • 장점 : 구현이 비교적 간단하고 직관적, 일정 시간에만 알림을 보내기 때문에 트래픽을 집중적으로 관리하기 수월
  • 단점 : 즉각성 부족, 품목 수가 엄청나게 많아지면 특정 시간대에 한거번에 조회하는 것이 부담될 수 있음. 

2) 실시간 (이벤트 기반) 체크 방식 : 품목이 등록/수정 될 때마다, 유통기한이 언제인지 계산하여 알림 스케줄을 예약하거나 트리거를 설정. -> 예약된 시점에 이벤트를 발생시키는 방식.

  • 장점 : 임박 시점에 맞춰 바로 알림을 트리거할 수 있으므로 사용자별 맞춤 알림 가능, 알림에 필요한 정보만 별도 큐/저장소에 쌓아두고, 해당 시점에만 알림 처리 (전체 DB를 매번 스캔할 필요가 없음)
  • 단점 : 구현 난이도와 인프라 복잡도가 증가. 소규모 서비스라면 오히려 과도한 설계가 될 가능성.

2. 이메일 알림 외에 앱 자체에서 알림을 받고 싶다.

1) 웹 애플리케이션에서의 알림

- 웹 푸시 (Web Push) 알림

- FCM을 통한 웹 푸시

- 인앱 알림 (실시간 웹소켓)

 

>> 이 부분에 대해서는 프론트 측과 논의 후 결정해야겠다. 현재 1차 MVP에서는 서비스 규모가 아직 작기 때문에 크론잡 형태가 가장 적절할 것 같다. 

⬇️ 알림 데이터 흐름

더보기

알림 데이터 흐름

1. 백엔드 

- 크론 잡 실행 (매일 9시)하여 DB에서 유통기한 임박 품목 조회하여 알림 생성.

- 알림 테이블을 두고, 새 알림이 생성되면 해당 사용자에게 is_read = false 상태로 저장

 

2. 프론트

- 초기 로드 시 : GET /api/notifications?is_read=false 호출하여 읽지 않은 알림의 수를 받아 배지에 표시. 

- 주기적 갱신 혹은 실시간 

  • 폴링 : 30초 ~ 1분 단위로 API를 재호출, 새로운 알림이 있는지 확인 >> 
  • 실시간 : 백엔드에서 새로운 알림이 생기면 클라이언트로 이벤트를 push, 프론트는 알림 아이콘의 배지를 즉시 업데이트

- 알림 아이콘 클릭 시 : 팝업/드롭다운 열림 -> GET /api/notifications?limit=10 목록을 화면에 표시 & 이때 PUT /api/notifications/{notiId}/read 호출해 is_read=true로 변경 & 배지 카운트 사라짐

 

728x90

BELATED ARTICLES

more