나는 이렇게 논다/Suulgo_# 술취향 매칭

#6_코드말고 술잔 부딪치시는 건 어떠세요 ?

daco2020 2022. 1. 22. 18:56
반응형

술 GO?

전 글에서 술 취향 매칭 알고리즘을 통해 가장 매칭 점수가 높은 사람들을 리스트로 받는다고 말했었다. 그리고 마음에 드는 유저를 선택하면 해당 유저의 술 취향을 볼 수 있는 상세페이지로 들어갈 수 있다.

 

상세페이지 화면을 보면 우측 상단에 ‘술고!’ 버튼이 보인다. 이제는 매칭을 넘어 상대방과 술 약속을 잡을 차례다. 버튼을 누르면 날짜 선택 모달 창이 뜨고, 원하는 날짜를 선택하여 실제 요청을 보낼 수 있다. 보낸 요청은 DB 테이블에 기록되는데, 이후 상대방이 확인을 할 수 있는 코드 또한 작성해두었다.(사이트에서는 아직 구현하지 못해 추후 실시간 알림이 뜰 수 있도록 리펙토링 예정)

 

 

문어발 요청은 NO!

약속 요청을 만들면서 한 가지 우려스러운 상황이 떠올랐다. 술고(술약속) 요청을 보낼 때는 날짜 단위로 요청을 보낼 수 있는데 만약 한 명이 다른 회원들 모두에게 약속 요청을 보낸다면 어떻게 될까? 한 명이 같은 날 여러 사람과 약속을 잡게 되고 결국 노쇼 문제가 발생할 여지가 높아진다. 만약 이를 악용하는 사람이 있다면 이는 결국 우리 서비스 만족도를 낮추게 될 터였다.

 

우리는 이러한 문제를 해결하기 위해 같은 날, 이중으로 다른 사람에게 약속 요청을 보낼 수 없도록 하였다. 술 취향 매칭 서비스라고 해서 뭔가 가벼워보일지 모르겠지만 엄연히 사람과 사람을 이어주는 서비스이므로 고객에게 실망을 안겨주고 싶지 않았다. 때문에 우리는 다음과 같이 두 가지 상황을 더 추가하여 분기를 처리하였다.

 

첫 번째는 정상적인 약속 요청이 성공한 경우이고, 두 번째는 같은 날 다른 사람과 약속을 잡을 수 없도록 막았다. 그리고 마지막으로는 이미 지난 날짜를 선택한 경우 약속 요청을 할 수 없도록 코드를 짰다.

# POST매서드 body에 담겨서 오는 값

{
    "respondent_id" : 4, # 요청 받는 상대 유저 아이디
    "time" : "2021-12-28" # 추후 시간 추가예정
}

우선 위와 같이 ‘respondent_id’, ‘time’ 의 키에 유저 아이디와 날짜 정보를 받는다.

class AppointmentView(View):
    @authorization
    def post(self, request):
        try:
            data         = json.loads(request.body)
            requester    = request.user
            respondent   = User.objects.get(id=data['respondent_id'])
            string_date  = data['time']

            date_format  = '%Y-%m-%d'
            promise_date = datetime.strptime(string_date,date_format).date()

            if datetime.now().date() >= promise_date:
                return JsonResponse({'message':'DATE_ERROR'}, status=400)

            if Meeting.objects.filter(requester=requester, time=promise_date).exists():
                return JsonResponse({'message':'ALREADY_EXISTS'}, status=400)

            Meeting.objects.create(requester=requester, respondent=respondent, time=promise_date)
            return JsonResponse({'message':'SUCCESS'}, status=200)

        except KeyError:
            return JsonResponse({'message':'KEY_ERROR'}, status=400)

        except User.DoesNotExist:
            return JsonResponse({'message':'DoesNotExist'}, status=400)

서버에서는 strptime을 통해 들어온 문자열을 날짜 타입으로 바꿔주고 오늘 날짜와 비교를 한다. 그리고 만약 오늘 날짜보다 이전이라면 ‘DATE_ERROR’를 반환한다.

 

만약 ‘요청한 사람’과 ‘요청한 날짜’가 이미 DB에 존재한다면 ‘ALREADY_EXISTS’를 반환한다. 이렇게 하면 한 사람이 같은 날 여러 명에게 요청을 보내지 못하도록 막을 수 있다.

 

이 외의 경우라면 정상적으로 성공했다는 메시지를 반환한다. 

 

 

 

 

해결해야 할 과제

하지만 스프린트 막바지 테스트를 해보면서 예상치 못했던 문제가 발견되었다. 현재 코드로는 자신이 자신에게도 요청을 보낼 수 있었던 것이다... 이런 기본적인 것을 놓쳤다는 게 스스로 아쉬웠다. 추후 리펙토링 시에는 본인이 본인에게 약속을 요청할 수 없도록 코드를 개선할 예정이다.

 

추가로, 상대로부터 요청받은 정보를 받을 수 있는 알림기능이 아직 프론트에서 구현되지 않았는데, 이 부분 또한 실제 서비스에서는 필수적인 부분이기 때문에 가장 우선적으로 구현되어야 한다. 그리고 이 과정에서 어떻게 하면 실시간으로 상대방에게 알림을 줄 수 있는지 백엔드단에서도 고민을 해봐야 한다. 멘토님께 들은 키워드로는 ‘소켓통신’이 있는데 이는 클라이언트가 요청하지 않아도 서버 쪽에서 응답을 줄 수 있는 기능이라고 간략하게 전해 들었다.

 

문득 내가 구현하고 싶은, 혹은 서비스의 필요에 의해 무언가를 배우는 과정이 즐겁다는 생각이 들었다. 그래서인지 아직 모자란 실력이지만 두려움보다는 기대감이 더 큰 것 같다.

 

 

 

 

 

반응형