회원가입
- 회원, 비회원 별 사용할 수 있는 서비스가 차별화 되어 있음
- 가입자가 현재 구비하고 있는 베이스 술, 재료 입력 받을 수 있음. 이걸 저장해 놓을 수 있다.
- 이슈: OAuth 를 사용여부 + ㅁ
술장고 (로그인 필요)
- 현재 내가 가지고 있는 칵테일 재료를 기록해 놓는 기능
- 술+ 냉장고
- 사용자 기반 추천과 검색 결과 필터링에 사용될 예정
사용자가 보유한 재료로 만들 수 있는 칵테일 레시피 추천 (로그인 필요)
- A 사용자의 술장고 기반으로 제작할 수 있는 레시피를 검색하여 사용자에게 제시해주는 기능
- 로그인 하자마자 팝업창으로 '내 술장고'를 띄워주고, 변경없으면 OK 추천, 변경하게 하고 나서 추천.
레시피 재료 구매 중개
- 특정 칵테일을 제작하고자 할 때, 사용자가 추가로 구매해야 하는 재료들의 가격 정보를 알 수 있는 링크 제공하는 기능
- 검색/ 추천 결과로 제시된 칵테일 레시피는 칵테일 이미지 카드 형식으로 사용자에게 제공된다
- 사용자가 이 카드를 클릭 시 팝업창이 뜬다
- 레시피 카드 중앙에는 칵테일의 이미지가, 오른쪽에는 해당 칵테일을 만들기 위한 레시피가, 하단에는 사용자가 업로드한 자신의 레시피 사진이 작게 가로로 나열되어 있다
- 사용자가 레시피의 '재료' 중, 자신이 구매하고자 하는 재료를 클릭하면 해당 재료를 판매하는 외부 링크로 연결이 된다
테마별 칵테일 추천
- (만약 당신의 술장고에 재료가 없더라도, 또는 비회원이라도) 당신의 취향을 저격하는 칵테일을 추천받을 수 있다. ⇒ 기념일, 기분, mbti, 취미, 날씨 등등 다양한 테마에 따른 추천 기능
- 가벼운 유저들의 접근성 향상
- 테마 목록을 같이 정하고, key 값을 붙여 user 컬럼에 추가하면 되지 않을까?
- 그럼 어떤 테마?
- MBTI
- 모질
- 주량
- 좋아하는 색
- 좋아하는 동물
- 성별
- 기분
- 이성유혹
검색기능은 헤더에 Input으로 노골적으로 제시가 아닌, 챗봇으로 우회적으로 제시
- 이렇게 우회적으로 하도록 기획했던 이유는?
- 신생 서비스의 경우, 한 페이지에 너무 많은 기능을 제공하면 매력이 떨어짐.
- 우리 서비스의 특색있는 기능은 [술장고]를 베이스로 한 레시피 제공.
- 그런데 화면에 노골적으로 Input창이 있다면 주의가 분산될 수 있음.
- 명확한 레시피를 목표로 하는 유저는 우리 서비스가 아닌 유튜브나 구글을 사용할 것이라 판단.
- 하지만 검색기능은 있어야 하기 때문에, 주의를 덜 받는 챗봇으로 기획했음.
- 우측 하단에 챗봇처럼 - > 찾고 있는 레시피가 있나요? (귀여운 바텐더 꿀렁꿀렁~) → 그에 맞는 레시피를 결과로 출력해줌
- 베이스 술, 재료, 도구
- 도구로 인한 진입장벽을 낮추는 방법도 생각해 봐야 할 듯
- 크롤링을 통해서 주류판매 사이트 정보 긁어서 DB화 → 중개서비스
→ 검색만을 위한 페이지를 따로 두면 어떠한가?
업로드 - 별점, 좋아요, 후기/한 줄 코멘트 (로그인 필요)
- 사용자가 레시피대로 만든 칵테일 이미지 업로드
- 유저들이 뽐낼 수 있는 란 -대신 SNS가 아니라, '후기'의 개념으로. 레시피 별 [별점/좋아요, 후기/한 줄 코멘트]
- 칵테일 레시피에 대한 별점 + 좋아요, 후기/ 한 줄 코멘트
자기가 만든 칵테일을 포스팅하는게 불필요한 것은 아니라고 생각을 했다. 다만 걸리는 점은, 기능적으로 중복이 된다고 생각했다. 어떤 술이 들어갔고, 이걸 연결시킬 때 이미 제공되는 기능. → 그럼에도 불구하고, 유저가 직접 만든 사진이 필요한 요소가 있을 수 있다. 유저들의 제작 예시들이 다른 유저들의 행동을 유도할 수 있다. ⇒ 커뮤니티 기능을 따로 두는 것은 투머치. 레시피를 확인할 때, 유저들이 직접 만든 인증샷 정도를 부가적으로 보여주면 리뷰/인증/참고 등등의 역할을 할 수 있지 않을까? 마치 네이버 식당 사진 리뷰 or 쇼핑몰 후기 사이트 유저들이 뽐낼 수 있는 란 -대신 SNS가 아니라, '후기'의 개념으로. 레시피 별 [별점/좋아요, 후기/한 줄 코멘트]
휘발성 있는 히스토리 - 세션 스토리지 기준
- 최근 n개 정도
- 사용자가 예상치 못한 기능을 제공해 주는 상황에서 빛을 발할 수 있는 기능이라 생각됨
즐겨찾기 히스토리 (로그인 필요)
- 사용자가 선택하도록 해야 함
- 언제 봤는지 날짜 명시(2021-11-20에...)
실시간 대쉬보드
→ '어떤 칵테일이 일정 기간으로 핫하다' /'~테마가 일정 기간 핫하다'라는 실시간 대쉬보드로 합치면 안될까? (네이버 실시간 검색어처럼)
회원이면 할 수 있는 액션
→ 즐겨찾기에 많이 추가된 칵테일 (일단은 좋아요가 즐겨찾기랑 같은 것) 상위 최대 10개
좋아요을 즐겨찾기와 같게 설정한 이유는 우리의 서비스가 '커뮤니티'성이 적기 때문이라고 판단했기 때문. 내가 해당 정보를 추후에 사용하고자 하는 의지가 강한 사용자들이라 생각했기 때문에, 좋아요와 즐겨찾기가 같다고 판단하였음.
배경음악
- 재즈풍의 배경음악이 자동으로 나오고, 사용자가 조작을 통해 배경음악을 중지, 재생 시킬 수 있음
- 테마별로 음악이 달라졌으면 좋겠음
술장고에 있는 재료와 없는 재료 간 차이를 Highlight(색상)의 차이로 보여주기
- ex) 칵테일 레시피
그림
레시피 :
재료 : 보드카 , 라임주스 , 00럼
반응형
- 웹 화면 먼저 구성
- 이후 반응형으로 모바일 화면 구성
카카오톡으로 레시피 공유하기 (프론트)
모달에 쿼리 스트링으로 주소 주기
네이버 API 통해서 키워드 검색 결과 렌더링
버튼 호버하면 차오르듯이 뽀오오오옹 딱!
많이 겹치는 재료의 레시피 순으로 제시
아무것도 등록한 술장고가 없으면 등록하러 가기
우리 DB에 가지고 있는 재료를 select할 수 있도록
로딩 스피너로 칵테일 쉐이커 돌아가는 SVG
재료 구매 사이트 api ( 네이버 쇼핑 api )
약간의 API 명세서
// User // 회원가입 POST /signup request body { email: string, password: string, nickName: string, detail : {Gender, Age, MBTI} } response body { user: User{}, tokenId: token } // 로그인 POST /login request body { email, password } response body { // set-cookie: token ?? user: User{}, tokenId: token } // 유저인증 POST /auth-user request header { 'Authorization': tokenId } response body { user: User{} } // 로그아웃 POST /log-out // (회원탈퇴) // User Settings // Detail 변경 response: nickname, gender, age, mbti // MyIngredients update PUT response: Ingredient[] // Recipe // Theme 별 Recipe // Ingredients 별 레시피 // Search Recipe // Detail Recipe // 실시간 대시보드 (인기순) Recipe // Comment // Comment 작성 // Comment 삭제 // Comment 수정 // Comment 좋아요 // Comment 좋아요 취소 // Favorites // Recipe Favorite 등록 // Recipe Favorite 삭제
DB 설계 - 엔터티
데이터 타입
User = { id: string; nickName: string; Gender: boolean; Age: number; MBTI: string; myIngredients: Ingredient[]; //Refrigerator //멘토님 // Ingredient를 User에서 받고 싶었던 이유: // '술장고를 통한 레시피를 얻는 것'이 회원 유저가 반드시 하게 될 행동으로 //상정했음. 그래서 두 번의 API 콜보다는 한 번의 콜이 효율적이라 생각했음 Favorites: Recipe[];//사용자가 좋아요를 표시한 칵테일 레시피 //Detail: UserDetail; } //대시보드를 위한 필수 정보니, 입력받기는 해야 합니다 //UserDetail = { Gender: boolean; Age: number; MBTI: string; }
//테마별 레시피 받아오기 /mbti/infp /weather/sunny ThemeRecipes = Recipe[] //ThemeRecipes = { MBTI: Recipe[]; //가령, MBTI-INFP 인 레시피들 받기 weather: Recipe[];// weather-Cloudy 인 레시피들 받기 favoriteColor: Recipe[]; mood: Recipe[]; favoriteMusicGenre: Recipe[]; topRating: Recipe[]; }
// Cocktail (칵테일) Cocktail { id: string; name: string; // 칵테일의 이름 ingredients: [용량, Ingredient][];//칵테일 제조에 필요한 재료 // 백엔드 분들의 의견에 따르겠습니다~ // "1 and 3/4 cup of Lime Juice" // (프론트 쪽에서)술 재료와 술 아닌 재료를 분할해서 주었으면 좋겠다. // (프론트 쪽에서) 재료의 이미지가 화면에 같이 나오면 좋겠다. instruction: string; //제조법 imageUrl: string; // 완성된 칵테일 이미지 popular: boolean; // 얘를 고정할 지, 아니면 사용자의 별점 받는 기능으로 //갱신이 될 수 있는 필드인지 결정 //(초기니까)일단은 고정값으로 하자. theme: { MBTI: string; weather: string;//Sunny, Cloudy, Rainy color: string; mood: string;// Romantic, Lonely music: string; // 어떤 음악과 함께? } favorite: Number; //이 칵테일을 좋아요(즐겨찾기) 한 사람의 수! comments: Comment[];// averageRating: Number; //종합 별점 }
//Review Comment { id: string; author: userId; //작성한 유저의 id imageUrl: string; //사용자가 찍은 업로드한 이미지 rating: Number; //별점 description: string; //해당 레시피에 대한 한 줄 평 }
//재료 Ingredient { id: string; name: string; imageUrl: string; //relevantRecipes: Recipe[]; // 이 재료로 만들 수 있는 레시피들 //재료 id 또는 이름으로 다시 한 번 콜로 요청할 수 있다. isAlcohol: boolean;// 술인지 아닌지 // Recipe속 Ingredient; (measure): string; // 온즈, ml .. 단위 //(amount): number; } //민트, 설탕, 보드카, 레몬...