[토이프로젝트] 1차 MVP 기획
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 설계 | 로그인 | |
로그인 처리 및 JWT 발급 | ||
로그아웃 | 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로 변경 & 배지 카운트 사라짐
'Project > toy project' 카테고리의 다른 글
[우리집에 가면] 25.02.17 - AWS RDS, 도커 이미지 (0) | 2025.02.17 |
---|---|
[우리집에 가면] 25.02.14 - EC2 생성 (0) | 2025.02.14 |
[우리집에 가면] 25.02.13 - JPA, Swagger, Security config, 구조 (1) | 2025.02.13 |
[우리집에 가면] 25.02.11 - MVP 기획 수정, DB 모델링 (1) | 2025.02.11 |
[토이프로젝트] 아이디어 기획 (2) | 2025.01.23 |