[Weeeating] 위코더가 추천하는 맛집 사이트! 프로젝트 후기

김예진·2021년 3월 11일
2

프로젝트

목록 보기
1/1

👉🏻 www.weeeating.com

: 위이팅을 직접 확인하실 수 있습니다! 아직 반응형 작업이 완료되지 않아 모바일보다 PC로 접속하시길 추천드립니다! 😊

🎬 구현 영상


👫 팀원

  • 김예진 : PM, 기획, 디자인, 백엔드
  • 김정현 : 기획, 디자인, 프론트
  • 백은진 : 기획, 디자인, 프론트
  • 전민승 : 기획, 디자인, 프론트

0. 프로젝트 시작

위코드의 모든 과정을 마치고 수료했다. 이력서를 수정하고, 알고리즘을 풀고, 데이터베이스에 대해 공부하고, 동기들과 함께 스터디도 진행했다.

"이러다 코드치는 방법을 까먹을 것 같아요."

동기들과 웃으며 그런 이야기를 주고 받기도 했다. 그러던 중 우리끼리 프로젝트를 해보자던 은진님 말에 '그거 정말 좋은 생각이다' 싶었지만 섣불리 시작할 수는 없었다.
프로젝트를 시작하게 된다면 완성된 사이트를 클론하는 게 아닌 기획부터 디자인까지 모두 처음부터 만들어가는 프로젝트를 하고 싶었다. 시작했다면 꼭 완성, 배포까지 하고 싶었다. 위코드에서 프로젝트를 진행했을 때는 모든 팀원들의 1순위 목표가 "프로젝트의 완성" 이었겠지만, 수료 이후 취직을 준비하는 지금은 누군가에게는 취직이, 또 누군가에게는 프로젝트 완성이 1순위 목표이기 때문에. 그래서 프로젝트를 시작하는 것이, 함께하자고 말하는 것조차 조심스러워했던 기억이 난다. (내 조심스러운 제안에 제일 먼저 흔쾌히 대답해준 정현님께 소심한 감사를 전합니다. 아마 정현님이 아니었다면 조용히 [언젠가는 만들고 싶은 기획] 폴더에만 남겨졌을 기획서가 되었을 지도 모른다..)


1. 기획

우리가 기획부터 시작하는 프로젝트를 하고 싶다고 마음 먹은 뒤에 이 시기에 적절한 사이즈(?)로, 즐겁게 만들 수 있는 아이디어가 뭐가 있을까에 고민했다. 위코드를 시작하고 선릉에서 처음 밥을 먹게 되었을 때가 생각났다. 무엇을 먹어야하는지 다함께 여기저기 돌아다니다 결국 위코드에서 제일 가까운 음식점에서 밥을 먹었던 기억이 났다. 시간이 지난 뒤 어느정도 적응은 됐지만 매일 돌아오는 밥에 대한 고민과 결정은 가끔 귀찮아지기도 했다. 이런 고민이 우리에게만 있으라는 법이 없다고 생각했다. 이후에 위코드를 수강할 사람들에게도 분명히 일어날 수 있으니 미리 공유되면 좋지 않을까? 로 시작된 프로젝트, we + e(귀엽잖아) + eating == weeeating 이었다.

- 기획 의도

: 위코드 신입 수강생들의 먹거리 걱정을 덜어주자!

👉🏻 어떻게?

위코드를 수료한 수강생들에게 위코드 근처 맛집을 추천받아 정리하자!

- 기획 목적

: ...사실 신입 위코더들의 밥 걱정을 덜어준다! 보다 우리의 공부 목적이 더 컸다😅... 배포까지 경험해보자가 함께 들어있다.

- 프로젝트 기간

: 팀원 각자의 일정을 고려하는게 중요했다. 누군가는 아직 취직을 준비하고 있었고, 또 누군가는 취뽀 후 첫 출근일을 조정해야하는 상황, 또 누군가는 아직 취직을 생각하지 않고 있었기때문에 팀원 모두가 부담스럽지 않도록 하고 싶었다. 우리의 포부는 1월 말일까지 완성 후 2월 초에 배포! 였지만 ...

  • 2021.01.05 : 프로젝트 기획 회의
    👉🏻 기획서 초안 작성, 디자인 초안 회의
  • 2021.01.10 : 팀원 다 함께 참여한 첫 회의
  • 2021.01.18 : 개발 시작
  • 2021.02.26 : 백엔드 배포 완료
  • 2021.02.28 : 프론트 배포 완료, 도메인 연결 완료

- 기획서 작성

1) 웹 사이트 기획서, 기획서 샘플 등 참고

기획자로 일해본 적은 있지만 웹 사이트 기획은 처음이므로 일단 제일 먼저 구글에서 사이트 기획서를 검색했다. 웹 사이트 기획서 샘플이나 웹 사이트 기획서 작성 방법이라던지.. 다양한 글들을 읽으면서 웹 사이트 기획서에는 어떤 것들을 담아야하는지 체크했다.

문서버전이나 서비스 개요, 사이트 맵의 구조도 등등 내가 생각했던 것보다 신경쓸 것이 더 많았다.

다양한 ppt양식들을 다운받아서 참고할 수 있는 부분들은 참고했다. 웹 사이트 기획서이고, 아무래도 디자인에 관련된 내용은 프론트와 협업해야해서 픽셀이라던가.. 사이즈 하나 하나를 다 명시해주어야하는지에 대한 고민했다. 이전 기업협업때는 디자이너분이 따로 계셨기 때문에 걱정하지 않았었는데 아무래도 디자인을 하다보니 그런 세세한 부분이 계속 신경이 쓰였다. 이 부분은 프론트 팀원들과 상의해서 조정해나가기로 했다. 아무래도 기획을 담당하기는 했지만 백엔드 개발자로서 프로젝트를 완성하는게 더 중요하다고 생각해서 기획서에 힘을 많이 주진 않았다.

2) Google Docs로 문서화

이전에 게임 기획자로 일하며 처음 써본 Google Docs인데 너무 용이했으므로 이번 프로젝트에서 사용했다. 내가 작성한 기획서를 팀원이 바로 확인, 수정이 가능하다. 또한 자동 저장!(매우중요) 기능과 버전 기록을 확인할 수 있어서 기획서가 어떻게 수정되어왔는지도 볼 수 있어서 매우 편리하다.

회의할 때는 아이패드로 필기하고,

Google Docs를 사용해서 문서화했다. 사이트마다 들어갈 수 있는 페이지들을 보여주는 사이트맵인데, 팀원들이 바로 바로 확인할 수 있도록 페이지마다 슬라이드 링크를 달아놓았다.


2. 디자인

- Google Docs로 문서화

기업협업 때 디자이너님이 adobe xd를 사용하는 게 생각나서 나도 사용해보려 했지만 .. 처음 사용해보는 툴이기도 하고, 배우는 데 시간이 제법 소요될 것 같았다. 디자이너로서 프로젝트를 하기로 한 게 아닌 이유도 포함해서 기획서에 디자인 내용까지 함께넣었다. 내가 초안을 만들거나 회의를 통해 팀원들과 페이지들을 구상했다.

이런 식으로 아이패드로 그려서 다 함께 디자인을 고민하고,

Google Docs를 사용해서 더 구체적으로 정리했다.

- Adobe Illustrator 사용

대학교 4년, 직장 생활 1년으로 누적된 ppt 실력을 뽐내보려했지만 ... ppt로 만들 수 있는 이미지는 극히 제한적이었다. 무엇보다 이미지를 축소하거나 확대할 때 이미지 깨짐이 있어서 일러스트를 사용해서 직접 제작하거나 무료 아이콘 이미지들을 검색해서 사용했다.

- 무료 한글 폰트 사용

https://noonnu.cc 에 무료로 사용할 수 있는 한글 폰트들이 모아져있다. 아주 유용하게 사용했다👍🏻
( 이런 프로젝트를 어떻게 만들 생각을 했는지.. 부터 시작해서 어떤 로직을 사용해서 만들었을까에 대해 궁금해지기도 했다 )


3. 백엔드

- 기술 스택

Aquery
Django
AWS RDS(MySQL)
AWS EC2
Gunicorn

- 모델링

기획서를 보며 기능들을 분리했다. A query tool로 모델링을 하고 나니

1) user
2) store
3) board

로 app 구분을 할 수 있었다.


- 구현 기능

1) User

  • 회원가입 API 구현
    : 이메일, 비밀번호 정규식 사용
    : 비밀번호 암호화

  • 로그인 API 구현
    : 로그인시 token 생성

  • 소셜 로그인 API 구현
    : 구글 소셜 로그인 기능

  • 소셜 로그인 이후 기수와 이름 작성 API 구현

2) Store

  • 메인 페이지, 상세 페이지, 테마 페이지 등 각각의 페이지 API 구현

  • 상세 페이지 내 댓글 API 구현
    : 기수와 이름 미입력시 기능 제한
    : 글 5개 이상시 페이지네이션

  • 오늘 뭐먹지 페이지 맛집 랜덤 추천 API 구현

  • 맛집 좋아요 API 구현

3) Board

  • 게시글 조회/작성/수정/삭제 API 구현
    : 글 5개 이상시 페이지네이션
    : 기수와 이름 미입력시 기능 제한

  • 게시글 내 댓글 조회/작성/수정/삭제 API 구현
    : 글 5개 이상시 페이지네이션
    : 기수와 이름 미입력시 기능 제한



4. 프로젝트 끝,

.... 프로젝트를 끝냈다. 초반 기획에는 더 다양한 기능들을 넣고 싶었는데 팀원들 모두 마무리를 짓는 것도 중요하다고 생각해서 회의를 통해 추가 기능 구현 사항으로 빼두고 배포까지 끝냈다. 이전에는 나 말고도 다른 백엔드 팀원이 있었는데 이번 프로젝트는 나 혼자 모두 진행해야 하다보니 걱정이 많이 됐다. 솔직하게 말하면 함께 기업협업을 갔던 채영님에게 프로젝트를 같이하자고 할까 고민도 많이 했었다. 위코드를 다니며 배웠던 걸 다시 제대로 익히고 정리하는 과정이 내게 꼭 필요하다고 느꼈다. 무작정 팀원을 따라가는게 아니라 나 스스로 충분히 고민해보고, 부딪치고, 깨지고, 고통받는 시간들이 꼭 있어야겠다고 느껴져서 채영님께 프로젝트를 함께하자고 제안하지 못했다. 본의아니게 채영님을 섭섭하게 한 것 같아 미안하다고 ... 이 글을 통해 소-올직하게 말해본다😅

팀원들 모두 각자 일정이 있음에도 최선을 다해준 것에 대해 너무 고맙다. 나 혼자라면 시작만 있고, 끝이 없었을 프로젝트일지도 모르는데 .. 함께 했기 때문에 즐겁게 배포까지 잘 완성했다!


좋았던 것들 -

① 로그인 하지 않았을 때 처리하기(login_decorator)

유저가 로그인하면 토큰을 생성해서 프론트에 전달한다. 프론트는 요청할 때 받은 토큰을 헤더에 넣어 백엔드와 계속 통신한다.

def login_decorator(func):
    def wrapper(self, request, *args, **kwargs):

        access_token = request.headers.get('Authorization', None)

        try:
            if access_token != None :
                data = jwt.decode(access_token, SECRET_KEY, ALGORITHM)

                print(data)
                user = User.objects.get(id=data['id']) 
                request.user = user

            else :
                request.user = None
                print(request.user)

        except User.DoesNotExist:
            return JsonResponse({"Error_code": "UNKNOWN USER"}, status=401)

        return func(self, request, *args, **kwargs)

    return wrapper

헤더에 아무것도 담기지 않았을 때 데코레이터에서 request.user = None으로 처리했고, 이후 기능을 제한해야하는 views에서 if문을 사용해서 request.user = None일 경우 기능을 쓰지 못하도록 했다. 프로젝트를 끝난 지금은 간단한 방법인데, 당시에는 정말 고통스러웠던 기억이 난다. 런서버를 할 때마다 데코레이터에서 에러가 걸렸고, 하나하나 print를 찍어보기도 했다. 프론트에서 로컬스토리지에 저장된 토큰이 있을 때만 토큰을 담아서 보내주었어야했는데 토큰이 없어도 계속 헤더에 빈 값'' 으로 보내줘서 에러가 났었다.


  useEffect(() => {
    window.scrollTo(0, 0);
    const ranking = async () => {
      if (localStorage.getItem("token")) {
        await axios
          .get(`${API}/store/list?sort=${like}`, {
            headers: {
              Authorization: localStorage.getItem("token")
            }
          })
          .then((res) => {
            setStoreData(res.data.store_list.like);
          });
      } else {
        await axios.get(`${API}/store/list?sort=${like}`).then((res) => {
          setStoreData(res.data.store_list.like);
        });
      }
    };
    ranking();
  }, []);

프론트에서 토큰이 있을 때만 헤더에 담아 보내는 것으로 로직을 수정했다. 이걸 프론트와 백엔드와 함께 소통해서 알아내기까지... 정말 오랜 시간이 걸렸지만 에러 이유를 찾아내고 수정한 뒤에는 정말 기뻤다!

② 회원정보 입력하지 않았을 때 기능 제한하기

사이트 내에 회원가입 버튼을 눌러서 회원가입을 하면 기수와 이름을 작성해야한다. 소셜 로그인으로 로그인을 했을 경우에는 기수와 이름을 작성하지 않아도 된다. 기수와 이름을 작성하지 않았을 경우 기능을 게시글 작성, 댓글 작성 기능을 제한해야 했다. 유저의 아이디를 찾아서 이름과 기수가 비어있을 때 메세지를 보내려고 했는데 어떻게 프론트와 통신해야할지 감이 잡히지 않았다.

그러던 중 백엔드에서 보내는 토큰을 프론트에서 저장하는 로직을 보고,

axios
        .post(`${API}/user/login`, JSON.stringify(data))
        .then((res) => {
          if (res.data.MESSAGE === "SUCCESS") {
            localStorage.setItem("token", res.data.Authorization);
            localStorage.setItem("user_id_number", res.data.user_id);
            localStorage.isAuthenticated = true;
            window.location.reload();
          } else {
            alert("로그인이 완료되지 않았습니다.");
          }
        })
        .catch((err) => console.log("로그인 통신이 원활하지 않습니다.", err));
    }

이 로직은 어떻게 동작하는건가여? 라고 프론트 팀원에게 물었고 설명을 들었을 때는 ... 머리가 띵했다 😂 ...

프론트에 응답하는 'MESSAGE' : 'LIKE_SUCCESS'가 단순히 좋아요가 잘 되었다, 좋아요를 잘 삭제했다 등의 정말 안부 문자 같은 거라고 여겼는데.. 그것은 크나큰 오산... 내가 보낸 키와 값이 모두 동일할 때 토큰을 저장하는 거였다. 이걸 나는 왜 지금 알았지? 라는 생각과 함께 그럼 유저의 이름과 기수가 없을 때의 메세지와 키값을 정해서 알려주면 프론트가 알 수 있겠구나 싶었다.

class LikeStoreView(View): # 음식점 좋아요/안좋아요 
    @jwt_utils.login_decorator
    def post(self,request,store_id):
        user_id = request.user

        store = StoreLike.objects.filter(store_id=store_id, user_id=user_id.id)

        if user_id.name != None:
            if store.exists() :
                store.delete()

                return JsonResponse({'MESSAGE' :'UNLIKE_SUCCESS'}, status=200)

            StoreLike.objects.create(
                store_id = store_id,
                user_id = user_id.id
            )

            return JsonResponse({'MESSAGE' : 'LIKE_SUCCESS'}, status=201)

        return JsonResponse({'MESSAGE' : 'NEED_USER_NAME'}, status=200)

'MESSAGE' : 'NEED_USER_NAME' 일 경우 원래는 status code를 400대로 썼는데 프론트가 status code가 400대 일경우 내 메세지 키 값에 접근하지 못한다고 해서 200대로 수정한 뒤 테스트를 해보니 잘 돌아가서 기뻤다. 임의로 200으로 두긴 했지만 실무에서도 이런 식으로 쓰는건가? 이게 정답이 맞나? 라는 생각을 많이 했다. 이런 경우에는 status code를 어떻게 설정하는지 궁금해지도 했다.

전체적으로 이번 프로젝트를 하면서 백엔드, 프론트 통신에 대해 좀 더 잘 이해하게 된 것 같아 뿌듯하고 좋았다. 물어보고 또 물어보고 이렇게도 물어보고 저렇게도 물어보고 다시 요청해주세요, 다시 요청해주세요 내 부탁에 귀찮은 기색없이 다 설명해주고, 무한 요청을 보내준 우리 프론트에게 너무 너무 고맙다 😂❤️

③ 기획부터 디자인, 배포까지 경험해 본 것, 그래서 팀원들과 더 다양한 것들을 고민해본 것

클론이 아닌 기획부터 디자인까지 모두 팀원들과 함께 만들었다는 것이 너무 좋았다. 이전에는 개발만 했기 때문에 로직에 대해서만 고민했지만 기획, 디자인까지 모두 함께 고민했고 팀원들의 더 다양한 생각들을 들을 수 있었다. 팀원마다 디자인에 대한 의견들이 각자 달라서 더 좋은 방법을 선택하는게 어려울 때도 있었지만 결과적으로 우리가 사용자에게 보여 줄 수 있는 최선의 기획과 디자인을 만들어낸 것 같아 기쁘다. 또한 개인적으로, 나는 프론트는 아니지만 기획과 디자인을 하면서 사용자 입장에서 보여지는 UI/UX에 대해 고민해볼 수 있는 좋은 경험이 되었다. 사용자가 처음 사이트에 들어왔을 때 무엇을 보일지, 로그인이나 회원가입은 어떤 식으로 할 지, 버튼은 어떤 식으로 보이게 할 지, 게시글이나 댓글은 어떻게 보여주는 것이 잘 읽히고 좋을지까지 많이 고민했고 또 다양한 사이트들을 돌아다니며 참고했다. 앞으로 어떤 사이트를 보더라도 더 유심히 관찰하게 될 것 같다. (지금 velog만 봐도... )

아쉬웠던 것들 -

① API 문서화 작업을 제대로(완벽히)하지 못한 것

백엔드 개발자로서 이정도는 기본이지 라는 글을 본 적이 있다. 위코드를 수료하고 난 후 API 문서화라는 것을 알았고 이미 취직해서 회사를 다니는 동기가 문서화에 대해 이야기를 했을 때 실제로 API a문서화가 중요하구나 알게 되었다. 그래서 이번 프로젝트 때는 꼭!! 꼭!! API 문서화 작업을 하고 싶었고 실제로도 API 문서화하기 좋은 툴이나 방법들에 대해 많이 찾아봤지만 기획서, 디자인.. 프로젝트 기간 안에 해야할 것들이 많다보니 제대로 하지 못했다. 하지 못했다라는 말은 결국 변명일 뿐. 프로젝트를 마무리했으니 문서화 하는 툴 사용 방법을 제대로 익혀서 한번 만들어봐야겠다(다 끝나서 무슨 소용이겠냐만은😂.. 그래도 하고 넘어가는 게 더 낫겠지!)

② 새로운 기술 스택을 사용하지 못한 것

프로젝트 초반 어떤 기술을 사용할 것인지, 무엇을 사용하고 싶은지 기술 스택에 대해 길게 이야기 하는 시간을 가졌다. 팀원이 graph QL을 사용해보면 어떠냐고 내게 물었을 때... 이틀 정도의 시간을 달라고 말한 뒤 graph QL에 대해 잠깐 공부했었는데. 새로운 기술 스택을 익히면 (취직이든, 경험이든, 공부든 어떤식으로도)도움이 될거야!라는 생각이 들었지만 또 과연 나 혼자 이걸 사용할 수 있을만큼의 수준으로 빨리 익힐 수 있을까? 그렇다면 프로젝트 기간 안에 잘 끝낼 수 있을까? 겁부터 들었다. 초반에 정해둔 기간 안에 배포하자는 목표에 맞게 graph QL은 사용하지 않기로 했지만 좋은 공부가 될 수도 있었을텐데 라는 아쉬움은 계속 남는다. 이번 프로젝트 배포에 Docker를 사용해보고 싶었는데 사용하지 못했던 것도 계속 아쉽다. 위코드에서 배우고 사용했던 기술 스택만 사용한 점이 개인적으로는... 많이 아쉽다.

profile
Backend Developer 🌱 벨로그 내용을 티스토리로 이사중~!

1개의 댓글

comment-user-thumbnail
2021년 4월 25일

진짜 그저 빛예진....
예진님 덕분에 우리끼리 완성도 있는 프로젝트를 만들 수 있다는 것도 알게 되고, 기획과 UX/UI를 생각할 수 있는 힘이나 전체적인 프로덕션을 바라보는 힘 등등 배운게 많아요

(언제나 그렇듯이) 행동보다 마음이 많이 앞서는 내가 우리끼리 프로젝트 하나 하고 싶다고 말한 것을 그냥 지나치지 않고 이렇게 실제로 함께할 수 있도록 꼼꼼하게 바탕을 마련해줘서 진심으로 고마워요

현업에서 많이 발전하고 있을게요 또 프로젝트 하나 갑시다!! 사랑해요 ❤️❤️❤️

답글 달기