Roen의 iOS 개발로그

2022.08.03~04 Today I Learn #팀플회고록

by Steady On

밤샘작업.. 그리고 팀플

전쟁같던 팀플이 끝났다.

우리가 만들기로 했던 와이어프레임에서 많은 기능을 덜어낸 정말 심플한 게시판이었지만, 기본 기능이라도 완벽(?)하게 구현된다는 것에 감사하기로 했다.

3,4일차를 몰아서 적는 이유는 일단, 3일차에 밤샘을 해서 TIL을 적을 시간이 없었고, 3시간 밖에 못잔 터라 4일차에는 뻗어버렸다. 그래서 뒤늦게 TIL을 써본다.

3일차

2일차에 이미 홈화면의 레이아웃은 다 잡아둔 상태였기 때문에, 검색 버튼의 기능 구현과 서버와 DB 연결의 백엔드 작업이 남아있었다. 오전에 가능하면 최대한 해결하고 싶었는데, 검색버튼 구현에서 정말 애를 먹었다.

일단, 프론트에서 받아온 검색어를 서버에서 DB로 먼저 넘겨주면, DB에서 관련 데이터를 뽑아서 가지고 오려는 시도를 했다. find 함수를 사용해서 해당 단어가 들어있으면 가지고 오도록 했는데, 몽고 DB의 특성상 이게 불가능했다. 그 이유는

1. 몽고 DB는 검색기능을 지원하지만, 어디까지나 띄어쓰기의 단위로 끊어서 계산된다.

2. 한국어의 형태소를 반영할 수가 없다.

예를 들자면, DB에 '계란과자'라는 데이터가 들어있으면, '계란'이나 '과자'로는 검색해서 가져올 수가 없다. 완벽한 '계란과자'로 검색을 하거나 DB 저장 자체가 '계란 과자'여야 가능하다. 그리고 형태소 반영은 '떡볶이를 먹었다.'라고 저장되어 있어도 '떡볶이'라는 키워드로는 검색이 불가능하다.

그래서 결국 나는 파이썬으로 DB 전체를 가지고와서 검색어를 반영할 데이터열에서 해당 단어가 들어있으면 리스트에 넣고, 중복되는 데이터는 집합으로 제거 후 다시 리스트로 반환하도록 했다. 이때 집합(set)으로 리턴하면, 계속 에러가 떳는데, 그이유는 제이쿼리와 문법이 겹쳐서 집합을 딕셔너리로 인식했기 때문이었다.

def search_keyword(keyword):
    results = {}
    word = keyword.split(" ")
    all_contents = list(db.posting.find({}, {'_id': False}))

    for i in all_contents:
        for j in word:
            if j in i['post_product']:
                results.update(i)

    return list(results)

그렇게 검색함수를 만들고 나서 중간 회의를 했는데, 여기서 도저히 마감에 맞출 수 없다고 판단해서 우리는 좋아요와 글 상세페이지, 필터링 기능을 빼고 매우매우 심플하게 가장 기본의 기능만 구현하기로 했다.

그런데 이때 또 생각치도 못한 복병이 나타났는데, 그건 바로 깃허브에 venv폴더가 없어서 환경변수가 공유되지 않아, 일부 팀원들은 코드 실행에 계속 에러가 나고 있었던 것...깃을 처음 사용했던 우리는 결국 뚜렷한 해결방법을 찾지 못해서 결국 깃을 새로 만들고, 각자 자신의 작업을 손으로 직접 복붙해서 올리기로 했다.. 그나마 다행이었던 것은 각자 담당하는 페이지가 달랐어서 app.py 이외에는 아직 작업 영역이 겹치지 않았던것... 그래서 세팅을 새로 하고, 팀원 모두에서 깃허브 데스크톱을 깔도록 했고, 안전한 깃 사용을 위해 팀원 모두에서 사용방법(브랜치 만들기, 병합하기, Fetch 받아서 pull 하기)을 알려주었다. 한명씩 돌아가면서 브랜치를 만들고, 자신의 작업을 복붙해서 올리고, 병합하고... 이후 한명을 제외한 팀원 모두가 밤샘작업에 들어갔다. 나는 2시반쯤 담당 작업이 마무리 되어서 다른 팀원들을 도와주러 다녔다.

'글쓰기' 페이지 백엔드 쪽에서는 첨부받은 파일과 함께 글제목과 같은 다른 정보들을 프론트에서 백으로 넘기는 것에서, form data인 사진과 글을 어떻게 백으로 한번에 보낼 것인가에 대해 고민하고 있었다. 같이 찾아보다 보니 '웹개발 플러스' 강의 자료에서 해답을 찾을 수 있었는데, form data에 글정보를 append해서 보내고, 백에서 해당 정보를 인덱싱하여 풀어서 DB로 보내면 되는 간단한 문제였다.

'로그인/회원가입' 페이지에서는 로그인이 안되면서

AttributeError: ‘str’ object has no attribute ‘decode’

에러를 띄우고 있었는데, 알고보니 pyjwt가 업데이트 되면서 더이상 decode 메소드를 필요로 하지 않게되어서 생긴 사소한 오류였다.

여기까지 하고 돌아오니 벌써 5시가 넘었었는데, 글쓰기 백엔드 쪽에서 이번에는

werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'post_product_give'

라는 에러를 띄우고 있었다...

두시간 넘게 미친듯이 구글링을 했는데 결국 해답을 못찾아서, 코드를 다시한번 찬찬히 살폈다. 문제는 담당 팀원분이 사진 첨부를 위해 이런저런 코드들을 복붙해서 쓰시다가 이전에 만들었던 파일 입력 form 태그를 제대로 지우지 않아서 생긴 문제였다! 이것까지 해결하고 나니 7시 40분이 되었고, 제대로 기능이 구현되었는지 몇번의 테스트를 더한뒤 기절하듯 잠들었다.

4일차

눈을 뜨니 11시 40분.. 3시간 정도 자고 나니 그래도 좀 살것 같았다. 배고픈거 보다 씻고 싶은게 우선이어서 샤워를 하고 간단하게 식사를 했다. 그리고 1시반에 다시 모여서 진행상황을 확인했다.

1. 로그인/회원가입은 잘 되는데, 로그아웃이 안되는 문제

2. 전체적으로 디자인이 모두 제각각이라 통일성이 없음

1번 이슈를 해결하기 위해 결국 로그인, 회원가입 페이지와 관련된 모든 함수와 API를 제점검했다. 1시간반 동안 코드를 갈아엎은 결과. 로그인되지 않은 상태면 로그인 화면을 우선 띄우기까지는 성공했는데, 여전히 로그아웃이 문제였다.(원래는 로그인 여부에 관계없이 홈화면이 띄워졌음) 그래서 또 코드를 이잡듯 뒤졌다. 로그아웃 자체는 기능이 매우 심플했다. 로그인하면서 저장된 쿠키를 삭제해주는 것. 그런데 이 망할 코드가 계속 .removeCookie가 없는 메소드라며 에러를 띄워댔다. 구글링을 열심히 하면서 자꾸 제이쿼리의 쿠키를 import 해야한다는 코멘트를 봤는데, 당시에 나는 우리가 필요한 모든 라이브러리를 import 했다고 생각했었다. 그런데 우리는 index, login, write 페이지를 모두 다른 사람이 만들었고, 각자 조금씩 다른 라이브러리를 import 했다는것을 간과했다.. 결국 총 두시간반의 삽질 끝에 혹시?하면서 index.html에 해당 라이브러리를 import 했더니 깔끔하게 로그아웃이 되었다...그리고 그사이에 다른 팀원들이 디자인을 마무리해줘서 시간내에 과제를 제출할 수 있었다.

아쉬운 점 그리고...

나도 부족한 점이 많아서 내 담당 코드를 다짜는데도 너무 오랜시간이 걸렸다. 개인적으로 웹개발 플러스의 강의에서 셀레니움 파트는 꼭 듣고 싶었는데, 끝까지 시간이 없어서 못본게 너무 아쉽다.

그리고 강의를 못들었다보니 팀원들이 어려워 할 때 더 쉽고 간단하게, 빠르게 도와줄 수 있었는데, 나도 모르는 코드를 세세하게 보느라 오류해결에 시간이 오래 걸린것 같아서 너무 안타까웠다.

다음에 비슷한 것을 만든다면, 1. 홈화면에서 시작하더라도 로그인을 하면 해당 정보를 불러오고 글을 쓸 수 있게 2. 마이페이지에서 내가 쓴 글과 좋아요 누른 글 모아보기 3. 컨텐츠 좋아요 기능!을 만들어보고 싶다.

좋아요 기능은 겉보기엔 쉬울 것 같은데, 꽤 로직이 복잡할 것 같다. 이런 테스트용 페이지에서는 포스트마다 고유의 데이터로 좋아요 누른 사용자의 리스트를 만들고, 해당하는 사용자라면 버튼 활성화 상태로 표기, 다시한번 누르면 비활성화 되면서 해당 리스트에서 유저가 사라지는 것...생각보다 유기적으로 연결된 곳이 많아서 맵을 잘 짜야겠다는 생각이 든다.

결과물은 너무 허접하고, 나도 모르는 코드의 범벅이라 포트폴리오로 넣고 싶지도 않아서 따로 올리지는 않을 예정이다.

이렇게 전쟁같은 첫번째 팀플의 마무리...

블로그의 정보

Roen의 iOS 개발로그

Steady On

활동하기