2021.01 ~ 2021.04
## 회고
프로그래머스는 평가, 채용, 교육 서비스를 운영하고 있었는데 그 중 교육 서비스는 따로 개발을 전담하는 팀이 없는 상태였다. 그래서 기능 개발은 하나도 진척이 안 되고 버그 수정도 지지부진했다. 그런데 K-digital training이라는 사업을 시작하면서 LMS의 대규모 개편이 필요해졌다. 그에 따라 LMS를 리뉴얼하는 TF를 신설했고 원래 평가팀 개발자였던 나도 TF로 이동하게 되었다.
TF 초기 멤버는 기획자 1명, 디자이너 1명, 개발자는 나를 포함해서 4명이었다. 백엔드는 내가 주로 맡고 대표님이 도와주시기로 했다. 프론트엔드는 경력이 많으신 프리랜서 프론트엔드 개발자와 js를 해본 적 있는 백엔드 개발자가 맡게되었다. 나중에는 프론트엔드 개발자 한 분과 Vue.js 경험 있는 백엔드 개발자가 입사하셔서 프론트엔드 파트에 합류했다. 그리고 프론트엔드에서 할 일이 점점 많아져서 대표님도 프론트엔드 파트로 이동했고, 결국 최종적으로는 1:5가 되어 나 혼자 백엔드를 개발했다.
그런데 TF 목표가 LMS 리뉴얼인 것을 제외하고는 거의 정해진 게 없었다. 그래서 여러 차례 회의를 하면서 개발 범위, 로드맵, 기획, 디자인 등등을 정하거나 검토했다. 기획 논의까지는 재밌게 참여했는데 솔직히 디자인 검토는 잘 모르겠어서 나는 잘 참여하지 못하고 주로 프론트엔드 개발자 분과 디자이너 분이 논의하시는 걸 듣기만 했다. 그래도 모바일 대응, 스크롤 스타일 등 재밌는 주제가 많이 나와서 나름 유익했던 것 같다.
개발적으로는 Rails erb에서 Rails API + Vue.js로 스택을 바꾸는 것이 목표였다. 그래서 프론트엔드 개발은 완전히 새로 퍼블리싱부터 개발까지 해야해서 기존 코드를 재사용하는 것이 불가능했던 반면, 백엔드는 모델은 거의 수정하지 않고 API만 추가하면 되었다. 그래서 다른 개발자 분들이 퍼블리싱 작업을 하시는 동안 나는 API를 만들었다. 프론트엔드 개발자와 논의하면서 API를 설계했으면 좋았겠지만 그렇게 하진 못하고 일단 내가 만들고 나중에 API 연동할 때 검토를 진행하는 방식으로 진행했다.
그런데 기획이 더 고도화되면서 기존에 없던 기능들이 생겼다. 중첩 요소의 순서 변경 기능, 특정 이벤트 발생 시 알림 보내기 기능, 엑셀로 학생 등록 기능 등등을 새로 개발해야 했는데 그 동안 기존 기능에 대한 API만 만들다가 새로운 기능을 만드니까 재밌었던 것 같다. 문제는 이 때 쯤에 프론트엔드 개발자들도 퍼블리싱을 마치고 API 연동을 시작해서 API 관련 이슈 리포트가 많이 들어왔다. 새로운 기능 개발과 이슈 처리 간의 컨텍스트 스위칭 비용이 많이 들었는데 git worktree를 사용하면서 조금 나아졌다.
LMS는 하위 요소의 개수를 표시해야할 일이 많았는데 `COUNT(*)` 쿼리 사용을 최소화하기 위해 COUNT 쿼리의 결과를 컬럼에 저장하고 있었다. 그런데 기획이 추가되면서 조건 별로 COUNT 컬럼을 여러 개 만들게 되었고, 요소를 생성하거나 삭제하거나 또는 조건이 수정될 때 재계산을 하는 로직이 너무 복잡해졌다. 사실 개인적으로는 Materialized View로 바꿔버리고 싶었는데 아직 사내에서 MView를 쓰는 곳이 없었고 나도 며칠 후에 훈련소 입소가 예정되어 있어서 시간 관계 상 포기했다. 대신 COUNT 컬럼에 관련된 메서드를 concern으로 분리하고 한꺼번에 재계산을 할 수 있도록 코드를 수정했다. 내가 훈련소에 가도 누군가 읽을 수 있는 코드를 만들기 위해 새벽까지 머리 싸매가며 개선했다.
그렇게 기능 개발을 끝내고 QA 후 버그 수정을 하던 중 훈련소에 입소하게 되었다. 원래는 훈련소 입소하기 전에 모두 끝날 예정이었는데 일정이 많이 늦어져서 생긴 일이었다. 그래서 아쉽게 배포를 직접 보진 못하고 훈련소 안에서 인터넷 편지로 배포했다는 소식을 들었다. 훈련소에서 돌아왔더니 TF가 정식 팀으로 바뀌었고 나도 다시 원래 팀인 평가팀으로 돌아갔다. 그래서 죄송하게도 운영하면서 생기는 이슈들을 내가 처리하지 못했다.
## 새로 사용해 본 기술
### apipie
프로그래머스는 대부분 Rails erb 기반으로 구성되어있고 API로 개발한 부분이 거의 없었다. 그래서 다른 개발자 분이 apipie로 POC를 한 정도를 제외하면 API 문서가 전혀 없는 상태였다. LMS 리뉴얼은 프로그래머스 처음으로 API를 대규모로 적용하는 프로젝트였고, 그래서 개발에 앞서 API 문서화 도구를 결정할 필요가 있었다. Rails의 여러 API 문서화 툴을 비교해보았는데, apipie는 ruby 코드로 작성하는데 OpenAPI 변환 기능도 있고 API validator 기능도 있어서 apipie를 그대로 사용하기로 결정했다.
apipie의 validator 기능을 사용하려면 파라미터를 snake_case로 정의해야하는데 프론트엔드 개발자 분들은 API 문서가 camelCase로 나오길 원하셨다. 그래서 apipie의 OpenAPI로 변환하는 부분에서 snake_case를 camelCase로 바꾸는 기능을 추가해서 멍키패치를 했다. ruby의 `class_eval` 메서드를 사용해서 쉽게 멍키패치를 할 수 있었다.
처음에는 controller 메서드 윗 부분에 문서를 같이 정의했는데 요청/응답 페이로드가 큰 경우에는 controller 코드보다 문서 코드가 더 길어지는 문제가 종종 생겼다. 그래서 문서 부분을 concern으로 분리하여 controller에서 문서 내용을 제거했다.
### git worktree
마지막 쯤에는 프론트엔드 개발에만 5명이 투입되었고 백엔드는 여전히 나 혼자 개발했다. 그래서 API 개발하는 도중에 버그 수정 등 프론트엔드 쪽 요청이 오면 git stash를 하고 다른 작업을 하는 경우가 많았다. stash, pop을 반복하다보니 컨텍스트 스위칭 비용이 컸고 stash list가 여러 개 쌓이면 관리가 힘들어지는 문제가 있었다.
그래서 프론트엔드에서 작업 요청이 오면 기존에 작업을 진행하던 브랜치는 그대로 두고, 프론트엔드 요청 처리 용 git worktree를 만들고 IDE 창을 새로 띄워서 진행했다. 그랬더니 단순히 IDE 창을 바꾸는 것만으로 컨텍스트 스위칭이 되었고 추가 요청이 들어왔을 때도 간단히 해당 worktree를 열기만 하면 끝났다.