행동대장 서비스에 QR코드를 도입한 이유
행동대장 서비스는 sns 친구가 아니어도 정산을 할 수 있도록 하는 것이 목적이다. 그러나 기존에는 최초의 목적에 부합하지 않았다. 카톡이 아니더라도 최소 하나의 SNS의 친구가 되어있어야 했다. 따라서, 각 행사의 고유 QR코드를 생성하여 SNS가 없어도 사용할 수 있고 대면에서 바로 행사 페이지에 접속할 수 있도록 했다.
어떻게 QR코드를 생성할까?
QR코드를 만드는 방법은 다양하게 있을 것이다. 직접 구현하거나, 라이브러리를 활용하거나.
-
직접 만들기
가능한 일이지만 시간 제약이 존재하며 리소스가 넘쳐나는 세상에서는 너무 비효율적인 일이라고 생각한다.
QR코드를 생성하기 위한 알고리즘을 직접 구현하는 것은 매우 복잡하고 수학적인 연산이 필요할 것이다. 따라서, 해당 방법은 바로 목록에서 지워버렸다.
-
라이브러리 활용하기
우리는 시간과 인적 자원을 아끼기 위해 손쉽게 QR코드를 생성해주는 라이브러리를 활용할 것이다.
다음 이미지는 NPM에 등록된 QR코드를 생성해주는 라이브러리를 다운로드 순으로 정렬한 것이다.

가장 많이 사용된 3가지는 qrcode.react
, qr.js
, react-qr-code
이다. 이 3가지 라이브러리 중 어떤 것을 사용할지 비교를 통해 선택해보자.
qrcode.react
, react-qr-code
, qr.js
비교하기
qrcode.react
-
성능
React 환경에 최적화되어 있어 QR 코드 생성 속도가 빠르고 효율적이다. 이 라이브러리는 React의 렌더링 방식에 맞게 설계되었기 때문에 대규모 애플리케이션에서도 안정적인 성능을 제공한다. 이는 React의 Virtual DOM을 효과적으로 활용하여 불필요한 재렌더링을 최소화하기 때문이다.
-
커스터마이징
색상, 크기, 배경색 등 기본적인 커스터마이징이 가능하지만, 로고 삽입이나 복잡한 디자인 커스터마이징은 지원하지 않는다.
-
사용성
React 개발자라면 쉽게 사용할 수 있으며, 설치 및 사용법이 직관적이다. 별도의 복잡한 설정 없이도 간단히 QR 코드를 생성할 수 있다.
-
문서화
문서화가 잘 되어 있어 이해하기 쉽고, 예제 코드가 풍부하여 다양한 사용 사례를 참고할 수 있다. 지속적인 업데이트로 최신 기능을 반영한다.
-
안정성
널리 사용되는 라이브러리로 안정적이며, 다양한 프로젝트에서 검증되었다. 활발한 커뮤니티 지원으로 문제 발생 시 빠른 해결이 가능하다.
-
qrcode.react NPM 문서
react-qr-code
-
성능
성능이 뛰어나 React 애플리케이션에서 빠르게 QR 코드를 생성할 수 있다. 특히 동적 데이터와 연동하여 실시간으로 QR 코드를 생성할 때 유리하다. 이는 이 라이브러리가 React의 상태 관리와 연동이 잘 되어 있어, 상태 변화에 따라 QR 코드가 즉시 업데이트되기 때문이다.
-
커스터마이징
기본적인 커스터마이징 옵션을 제공하며, 색상, 크기, 스타일 등을 쉽게 변경할 수 있다. 다만, 고급 커스터마이징 옵션은 제한적이다.
-
사용성
React 개발 환경에서 쉽게 사용할 수 있도록 설계되어 있으며, 직관적인 사용법을 제공한다. 사용법이 간단해 초보자도 쉽게 사용할 수 있다.
-
문서화
잘 정리된 문서화로 쉽게 시작할 수 있으며, 예제 코드와 함께 제공되어 실습하며 배울 수 있다. 지속적인 업데이트를 통해 최신 기능을 지원한다.
-
유연성
다양한 QR 코드 생성 요구사항을 충족시킬 수 있는 유연성을 제공하며, 다양한 크기와 스타일의 QR 코드를 생성할 수 있다.
-
react-qr-code NPM 문서
qr.js
-
성능
경량 라이브러리로 QR 코드 생성 속도가 매우 빠르다. 성능이 중요한 경우에 적합하며, 서버 사이드 렌더링(SSR)에도 유리하다. 이는 이 라이브러리가 독립적인 JavaScript로 동작하여 Node.js 환경에서도 쉽게 통합될 수 있기 때문이다.
-
커스터마이징
기본적인 QR 코드 생성 기능만 제공하며, 고급 커스터마이징 기능은 부족하다. 색상, 크기 등 제한적인 커스터마이징만 가능하다.
-
사용성
경량 라이브러리로 간단한 API를 제공하여 사용이 쉽다. 설치 및 사용법이 매우 직관적이며, 작은 프로젝트에 적합하다.
-
문서화
간단한 문서화가 되어 있어 기본적인 사용법을 이해하기 쉽다. 다만, 업데이트가 자주 이루어지지 않으며, 최신 기능 지원이 제한적이다.
- 크기
라이브러리 크기가 작아 애플리케이션의 전체 크기에 부담을 주지 않으며, 빠른 로딩 속도를 유지할 수 있다.
- qr.js NPM 문서
어떤 라이브러리를 선택?
라이브러리를 선택하기에 앞서, 행동대장 서비스에서 QR코드를 생성할 때 필요한 조건들을 나열해보자.
- QR 코드의 색상 변경이 가능할 것
- QR 코드의 사이즈 변경이 가능할 것
- 하나의 행사. 즉, 하나의 url에 하나의 QR코드가 생성될 것
위 조건 말고는 다른 것은 크게 중요하지 않았다. 하나의 행사에 url이 동적으로 계속 변경되는 것이 아니었기 때문이다. 위 조건에 맞춰 3가지 라이브러리 중 하나를 선택해보자.
일단, qr.js
제외. 업데이트가 12년 전이고.. 아직도 버전이 0.0.0이기 때문이다. 12년전보다 웹 생태계는 많이 바뀌었다고 들었기에 오래된 라이브러리 사용은 좋지 않다고 판단했다.
그리고 남은 두 라이브러리.. react-qr-code
와 qrcode.react
는 모든 측면에서 우수하고 비슷한 스펙을 가지고 있다. 그래서 뭘 선택해야 하나 고민이 많이 들었는데.. 둘 중 하나를 제외하자면 react-qr-code
였다. url의 상태가 지속적으로 변하는 서비스가 아니였기 때문에 동적 데이터에 장점을 둔 해당 라이브러리의 사용은 굳이였다.
따라서, QR코드 생성도 빠르면서 간단한 커스터마이징이 가능하고 지속적으로 배포가 이뤄지고 있는 qrcode.react
를 선택했다. 그리고 무엇보다 qrcode.react
는 가장 많이 사용되고 있기 때문에 자료를 찾기가 수월했다. 문서화도 매우 친절하게 잘 되어있고! ← 이게 가장 크다.
qrcode.react를 사용하여 행동대장 서비스에 QR코드 기능 추가하기
import { QRCodeSVG } from 'qrcode.react';
import getEventPageUrlByEnvironment from '@utils/getEventPageUrlByEnvironment';
import getEventIdByUrl from '@utils/getEventIdByUrl';
// ...
const QRCodePage = () => {
const eventId = getEventIdByUrl();
return (
// ...
<div css={QRCodeStyle()}>
<QRCodeSVG value={getEventPageUrlByEnvironment(eventId, 'home')} size={240} fgColor={`${theme.colors.black}`} />
</div>
// ...
);
};
export default QRCodePage;
- qrcode.react의 QRCodeSVG 컴포넌트를 사용한다.
- QRCodeSVG 컴포넌트의 value로 QR 코드를 생성할 url를 넣어준다. 그러면 QR코드가 생성된다.(초간단!) 해당 QR코드는 동일한 url이라면 변하지 않는다.
데스크탑 QR 코드로 초대하기
현재 데스크탑에서 header의 정산 초대하기 버튼을 클릭하면 내용 및 url 복사만 가능하다. 데스크탑에서도 QR code 기능을 추가하는 것이 좋을 것이라고 판단했다.
따라서, 데스크탑에 정산 초대하기 버튼을 클릭하면 DropDown을 통해 링크 복사하기
와 QR코드로 초대하기
를 선택할 수 있도록 했습니다.
import { useNavigate } from 'react-router-dom';
import { Dropdown, DropdownButton } from '@components/Design';
import getEventIdByUrl from '@utils/getEventIdByUrl';
// ...
const DesktopShareEventButton = ({ onCopy }: DesktopShareEventButtonProps) => {
// ...
const navigate = useNavigate();
const eventId = getEventIdByUrl();
const navigateQRPage = () => {
navigate(`/event/${eventId}/qrcode`);
};
return (
<div style=>
<Dropdown base="button" baseButtonText="정산 초대하기">
<DropdownButton text="링크 복사하기" onClick={copyAndToast} />
<DropdownButton text="QR코드로 초대하기" onClick={navigateQRPage} />
</Dropdown>
</div>
);
};
export default DesktopShareEventButton;
구현 결과
참고자료
9월에 Level4를 시작하여 어느덧 10월 마지막 주. Level4 종료까지 이틀을 앞두고 글을 쓴다.
참.. 언제 끝나나 간절히 바라기만 했던 Level3-4가 드디어 끝난다니.. 좋기도 하면서 한편으로는 아쉽기도 하다. 하지만 나는 여전히 Level4의 마지막 날인 금요일을 기다리고 있긴 하다.ㅎㅎ
Level3-4를 진행하면서 나는.

Level3-4 동안 나는 내가 이루고자 하던 것들을 이뤘을까? 그 당시에 나의 생각을 적어둔 것이 없어서 이뤘는지는 잘 모르겠다. 그래도 뭐 하나 이룬 것이 있었을 거라고 생각한다. 행동대장, 코드 읽기 실력 증가, 디버깅 실력, 협업 경험 등. 지금 생각나는 건 이정도?
그렇다면 나는 Level3-4를 진행하면서 어떤 감정이 가장 기억에 남는가 생각해봤다. 역시 아무래도 고통?인 것 같다. 반복적이면서 변하지 않고 휴식이 부족한 시간들이었다. 그렇기에 주말에 더더욱 쉬려고 혈안이 되어 있었던 것 같다. 나만의 건강한 패턴을 찾았어야 했는데, 그러지 못한 것이 참 아쉽다. 하지만 조금 덜 건강한 패턴이 자리잡은 이유는 “행동대장”이라는 팀에 대한 애정이 넘쳐서 그랬다고 생각한다. 더 좋은 서비스를 만들고 싶고, 더 유저가 편하게 사용할 수 있도록 생각하고 또 생각했었다. 그래서 일도 많고 탈도 있었지만, 모두가 놓지 않고 나아가려고 했기 때문에 지금의 행동대장이 있을 수 있었다.
가장 기억에 남는 감정은 고통이지만 그 사이 사이에 즐겁고 행복한 기억들도 많았다. 행동대장 프론트들이 일정에 치여서 다 같이 노래 흥얼거리며 정신줄 놓고 코딩하던 순간, 데모데이 전날에 항상 밤 새서 개발하던 순간, 코치님들에게 서비스에 대해 칭찬 받았던 날, 맛있는 점심 먹으러 가기, 석촌호수 산책, 최종 데모데이 방탈출 진행, 준의 알맹이 워크숍 수업, 데일리 스크럼 시간에 소알맹을 즐겨준 행동대장 팀원들 등등.. 이런 순간들이 있었기 때문에 힘들었지만 견뎌낼 수 있었다. 물론 막바지에 건강을 조금 잃긴 했지만…
나는 Level3-4를 지내면서 무엇을 얻었을 까? 메인 감정 키워드가 ‘고통’이었던 만큼 얻은 것은 ‘인내’ 라고 생각한다. 이 심란하고도 답답한 순간들을 그저 견디면서 인내할 수 밖에 없었다. 우테코를 그만 둘 수는 없으니까.
그렇다고 가만히 있던 것은 아니다. 이 순간들을 조금이나마 개선하기 위해서 계속해서 걸어나갔다. 멈추지 않았기에 성장할 수 있었다.
요즘 드는 생각들
여전히 나는 걱정이 많다. 주변사람들이 많이 쓰는 토스나 우아한 형제들, DH에 나는 지원하지 않거나 열을 다하지 않았다. 현재의 내가 부족한 것들을 너무나 잘 알기 때문이다. 그래서 지원한다고 좋은 결과가 오지 않을 것이라는 걸 확신했다. 이게 어쩌면 회피일 수 있다. 우형 채용 신청에 대해 고민하면서 나는 지금 이 압박의 순간을 회피하기 위해 이유를 찾아냈던 건 아닐까? 생각을 많이 했다.
누군가는 회피라고 할 수 있다. 그렇다면 난 부정하지 않겠다. 하지만, 나는 지금의 내 선택이 틀렸다고는 생각하지 않는다. 자신감 없는 상태에서 이력서와 포트폴리오를 쓰고 코테 준비를 한다면 좋은 성과가 나지 않을 것을 알기 때문이다. 물론 좋은 성과만을 좇는 건 아니다. 하지만, 내가 가진 이 기회를 잘 적절한 시기에 사용하고 싶다. 사용하지 못 할 수도 있지만 이 기회를 그냥 일반 쓰레기로 처리하지 않고 최소한 분리수거라도 하고 싶다.
앞으로의 취업 준비가 참 막막하다. 다들 뛰어가는 것 같은데, 나 혼자만 걸어가는 느낌이다. 하지만, 언제나 나 자신에게 누누히 하는 말이 있다. 남들과 비교하지 말자. 각자만의 속도가 존재하는 것이다. 무엇이든 비교하기 시작하면 행복해질 수도 있지만 그만큼 불행해질 수도 있다. 그러니 조급해하지 말고 나의 패턴을 찾아서 조금씩.. 조금씩… 나아가자.
Level4의 행복한 순간들
우테코 복지
이걸 참 복지라고 말하기에는 교육기관이라 애매하지만? 우테코 후드집업과 런던 베이글!!을 복지로 받았당.
코치님들(포비, 준)과의 회식

무려 고기를 먹으러 갔다. 여기서 코치님들께 좋은 이야기도 많이 들었고 앞으로의 취업에 도움이 될만한 것들도 많이 들었다. 그리고 포비, 준이랑 같이 사진도 찍었다. 고기가 참 맛있었고.. 행동대장 영상도 찍고.. 유익하고 재밌는 시간이었다.
소알맹 : 소하의 알맹이를 찾아서
준의 알맹이 찾기 워크숍을 들으면서 깨달은 것들이 너무 많았다. 나의 알맹이를 찾아야 지치지 않고 살아갈 수 있다고 받아들였다. 그래서 나는 나의 알맹이를 찾고자 했다. 첫 시도는 행동대장 데일리 스크럼 시간에 한 팀원을 인터뷰한 내용으로 퀴즈를 내는 것이었다. 퀴즈를 만들기 위해 한명씩 따로 인터뷰를 진행하는데 이게 또 미묘하고 재밌다. 사실 아직도 어색한 팀원들이 존재한다. 이는 어쩔 수 없는 것 같다. 그런데 이 인터뷰를 하면서 해당 팀원에게 들었던 궁금증을 해결할 수 있었다. 또한, 이전에는 몰랐던 이 사람의 진면목을 알아갈 수 있었다. 내가 기획했지만 여러모로 나에게 많은 도움을 준 활동이었다.
그리고 팀원들이 퀴즈를 적극적으로 재밌게 참여해줘서 너무 고마웠다. 누구 하나라도 좋아하지 않았더라면 중간에 포기했을 텐데.. 즐겁게 임해줘서 너무 행복했다.
여전한 사람들

우테코를 다니면서 가장 잘 한 일은 Level1때 10명이 같은 조가 되었던 것이다. 내가 의도해서 만들어진 사람들은 아니지만 이는 다시 없을 행운이었고 기쁨이었다. 앞으로 남은 생일자 11월과 1-2월에 꼭 잊지 않고 모였으면 좋겠다.
최종 데모데이 : 행동대장

위는 내가 만든 행동대장 메인 포스터이다. 사실 메인으로 만든 생각은 아니었다.. 토다리가 만들던 카드뉴스 컨셉에 맞게 방탈출 소품을 위해 만들었는데.. 어쩌다 보니 메인 포스터가 되었다. 그리고 은근 찰떡이다(?) 내가 만들었지만 잘 만들었군. 흠
우리의 귀여운 행댕이 스티커… 우리 팀에 금손 웨디가 있어서 정말 다행이다. 이 스티커는 진짜 너무 귀여워서 행복했다. 그리고 타 팀원들에게도 우리 스티커가 가장 반응이 좋지 않았을까.. 흠흠^^ 귀여워서 이뻤던 행댕이가 이번 스티커를 통해 더 너무너무 좋아졌다!
나름 매우 열심히 준비한 최종 데모데이!
우리 팀은 준비한 이벤트가 무려 “방탈출”이다..! 다 같이 아이디어 회의를 한 후, 내가 방탈출 시나리오를 작성했다. 그리고 방탈출을 위한 소품들도 웨디와 함께 직접 만들었다. 웨디가 그려주면 내가 잘라서 입체적으로 소품을 만들었다.
방탈출을 다들 너무 즐겁게 참여해줘서 행복했다! 또한, 방탈출 난이도도 별 3개중 2.5 정도라 어느정도 밸런스를 잘 잡게 짠 것 같아서 마음에 들었다 ^>^ 역시 다년간 크라임씬과 대탈출, 여고 추리반을 섭렵한 나. 헛으로 본게 아니었다. 후후.

행동대장 Level4까지 종료!
앞으로 Level5부터는 어떻게 될지 확정된 것은 없다. 이번주에 DH와 우형 서류 제출 마감이라 다들 엄청 바쁘다. 그래서 다음주로 미뤄뒀다. 나는 아직 행동대장 서비스를 조금 더 개선해서 우테코 7기들이 유용하게 쓸 수 있도록 하고 싶은 욕심이 있다. 그러나 그 방향은 각자 다르게 생각하고 있을 것이다.
우리 행동대장이 어떻게 되던간에 나에게는 협업이 뭔지, 팀 프로젝트를 하는 이유에 대해 알려준 팀이다. 프로젝트를 진행하며 협업 방식도 정말 많이 변경했고 그 과정에서 FE와 BE간의 의견 차이도 존재했다. 또, FE 끼리도 의견차이가 존재하기도 했다. 이런 것들을 어떻게 해결해 나갈지 알려줬다. 서로가 생각하는 것을 이야기하고 하나씩 수용과 포기를 하며 8가지를 1가지로 만드는 것. 내 욕심을 모두 충족할 수는 없기에 포기하는 법도 배웠고, 나의 주장을 적극적으로 어필하는 방법도 배웠다.
Level4가 끝나간다니.. 참 행복하면서도 믿기지 않는다. 그래도 다음주부터 하루 수면시간 8시간을 보장할 수 있다는 것에서 너무 행복하다.. 이제 지옥같은 출근길과 야간 운전을 하지 않아도 된다.. 밤 늦게 운동하러 가지 않아도 되고.. 내가 하고 싶은 공부들을 할 시간도 생긴다..
한 편으로는 내가 게을러지지 않기 위해 어떻게 해야 할까 고민도 많이 든다. 이건 이번주에 계속 고민해봐야 겠지!
이제 진짜 남은 한달! 우테코 생활 알차게 잘 마무리 해보자! 아쟈쟛!
이것 참.. 회고라고 하기에 좀 뭐하긴 하지만 ^^… level4도 끝나가는 이 시점에 저번에 다 못적은 level3 회고를 마무리해볼까 한다…
기억이 많이 휘발되어 따로 휘갈기는 노트를 참고하여 글을 적는다.
발전한 나의 소프트 스킬
다들 참 많이 지쳐있었을 때였다. 이때 러기와 렛서가 많이 지쳐보였다. 그래서 집 방향이 같은 러기와 짧은 시간이지만 많은 이야기를 했었다. level3에 오면서 개인 시간을 낼 수 없어 약간의 번아웃이 온 듯 했다. 그래서 작은 위로일 지라도 용기를 내어 중문의 카톡을 보냈었다. 나의 카톡을 읽고 힘이 된 듯 해서 뿌듯했다.
우테코에 오기 이전의 나라면 아니, 불과 몇달 전의 나라면 이런 카톡을 보내지 않았을 것이다. 누군가를 위하는 말 일지라도 상대방에게 돌아오는 답변이 무서웠기 때문이다. 꼭 하지 않아도 되는 것에 대한 연락은 상대 답변이 어떻게 올지 참 무섭다. 이건 아직도 여전한 것 같다. 그러나, 우테코에 오면서 조금씩 이런 부분에 대해 용기를 내보고 있다. 이런 부분을 소프트 스킬 수업 시간에 알려주지는 않지만, 우테코라는 환경이 나를 조금씩 나도 모르게 변화시키고 있다.
우테코에서 받은 키트(좌), 공구한 행성이 키링(우)
새로운 경험
우테코에 와서 새로 시작하게 된게 뭐야? 라고 누군가 나에게 묻는다면 나는 단연 “야구!” 를 외칠 수 있다. 최강야구를 보진 않았지만, 집 가는 길에 심심해서 티빙으로 야구를 봤던 것이 나의 야구 인생이 시발점이다. 그래도 야구가 있었기에 집 가는 어두컴컴한 길이 덜 지루했던 것 같다. 또한, 유튜브로 채우던 도파민을 스포츠로 나름 건강하게(?) 채우고 있다. 참 잘 선택한 취미라고 생각한다.
야구 단체 관람?!

그래서 나는 야구에 미쳐버린 나머지 우테코에서 야구 단체 관람까지 진행하게 되었다. 하하! 자세한 이야기는 여기서.. 확인이 가능하다.
사실 나는 뭔가를 기획하거나 운영, 주최하는 것을 좋아한다. 그래서 배드민턴 동아리도 4년씩이나 임원진을 했던 것이다.. 우테코에 와서 FE 걸스나잇 이후에는 또 이런 이벤트를 주최할 일이 없을 줄 알았는데.. 이렇게 야구 단체 관람을 하게 되었다. 핳
인생 첫 커피 챗
지난 번에 용기를 내어 가브리엘에게 커피챗을 신청했다. 가브리엘은 흔쾌히 받아 주셨고 엘버도 함께 커피챗에 응해주셨다. 회사 일로 인해 굉장히 바쁘실텐데도 불구하고 커피챗 신청에 응해주셔서 너무 감사했다.
커피챗의 주된 내용은 아무래도 level3-4 팀 프로젝트와 취업이었다. level3 커피챗 당시에는 취업에 대한 걱정은 있어도 큰 고민은 없었다. 아직은 조금 더 남았다고 생각했기 때문이다. (응.. 근데.. 지금은 현실이야..)
가브리엘과 엘버 덕분에 맛있는 저녁도 먹고 toss에도 와 볼 수 있었다. 확실히 IT 업계 탑이 맞다..
그렇게 유익한 커피챗 시간을 보냈다. 고민도 많이 해결됐고, 새로운 시각을 얻을 수도 있었다.
당시에 나는 팀 프로젝트에 굉장히 지친 상태였다. 1차 스프린트까지는 내 시간이 있어서 아침에 개인 공부도 꾸준히 해왔고 집에 돌아간 후에도 내 일을 할 수 있었기 때문이다. 근데, 2차 스프린트에 들어서면서 그런 것이 싸그리 사라져버렸다. 이게 나에게 너무나도 힘들었다. 그러면서 또 취업 걱정은 들고.. 그래서 당시에 개인 시간을 확보할 수 있도록 하고, 미리 취업 준비도 시작해야 겠다 생각했다. 또한, 왜 이런 코드를 작성했는지 블로그에 꾸준히 기록하자고 생각했다. 정말 생각만 해버렸다. 이거 적으면서 안 했다는 것을 깨달았다..ㅋㅋ ->
그리고 나는 다음날 행동대장 팀원들에게 이 이야기들을 공유해줬다.
음.. 근데 이게 사실 약이 아니라 독을 풀었던 것 같다. 이 프로젝트가 협업을 위한 것도 맞지만 우리의 취업에 가장 큰 포트폴리오 자산이 될 것이다. 그렇기에 포트폴리오에 우리 프로젝트를 넣었을 때 괜찮을 것인지 생각하면서 프로젝트를 진행해야 할 것 같다고 말했다. 이런 뉘앙스의 말로 인해 팀원들에게 혼란을 가중시켰다. 절반의 팀원은 동의했지만 절반의 팀원은 기술적인 것 보다 사용자를 더 중시하기 때문이다.
사실 나도 사용자를 중시하는 측이었지만 취업!! 이라는 큰 고민 때문에 휙-하고 태도를 달리 바꿔버렸던 것 같다. 그리고 후에는 다시 사용자 중심으로 돌아왔다ㅎ
당시에는 여차저차 이쪽 방향으로 팀원들이 따라주려고 했다. 아무래도 다들 지쳤으니까, 더이상 논의하기에는 힘들어서이지 않았을까? 생각한다. 그래서 대충 쓰던 PR 리뷰도 구현 목적과 방법, 결과를 꼼꼼하게 작성하기로 했다. 그리고 꼭 필요한 것이 아니라면 UI/UX에 큰 욕심을 부리지 말자고 했다. 그리고 3차 스프린트에 들어와서 하나의 Task를 페어프로그래밍으로 하고 있던 것을 다시 개인이 task를 가져가는 방식으로 전환했다. 페어 프로그래밍으로 진행하니 진도가 너무 나가지 않는 문제가 발생했기 때문이다.
여튼 참.. 커피챗 하나로 많은 것들이 변화되었던 것 같다. 당시에는 당장 긍정적으로 변화하진 않았을 지라도 점점 우리만의 방식을 찾아가며 협업 방식이 안정적이게 되었다.
이제 level3는 끝이다!
위에서 말했듯이 4차 스프린트는 우리만의 방식을 찾으면서 매우 안정적이게 협업이 진행되었다. 개인이 task를 맡아 진행하는 방식으로 변경했다. 대신 이 task의 규모를 작게 나누었다. 이전에는 하나의 기능을 task로 뒀다면, 이번에는 이 하나의 기능에 대한 a,b,c를 각각의 task로 두는 것이다. 또한, 원활한 merge를 위해 리뷰 제출 시간을 18시로 제한하였다. 그리고 PR 내용을 상세하게 작성해 다른 팀원들이 코드를 리뷰하는데 시간을 덜 들일 수 있도록 했다.
이런 협업의 형태가 우리에게 가장 잘 맞았던 것 같다. 비록 4차 스프린트까지 와서야 찾게 되었지만, level3에서 끝이 아니니까 이제라도 찾은 것이 다행이라고 생각한다. 그리고 이런 방식이 다른 팀원들에게도 시간비용을 절약할 수 있어서 좋았지만, 기능을 구현한 본인 또한 왜 이런 방식으로 구현했는지 생각해보는 기회를 주게 되었다. 즉, 왜 이 기능이 필요했지? 이런 방식으로 구현한 이유는? 이게 최선이었나? 등을 개발하면서 생각할 수 있었다.
level3 런칭페스티벌 전 날에는 프론트는 거진 밤을 샜다. 새벽 4시까지 디스코드로 회의하고 merge하고 디자인 손보고.. 여러가지를 했기 때문이다. 새벽까지 진행해서 지쳤긴 했지만 뿌듯하고 재밌다!라는 감정이 가장 크게 들었다.
그리고 이렇게 노력한 것에 대한 보상은 역시 런칭 페스티벌에 나타났다. 내가 편집한 행동대장의 level3 개발 과정과 토다리가 만들어준 서비스 소개 화면.. 그리고 다양한 피드백 등..
아직은 부족한 부분이 너무 많았어서 부끄럽기도 했지만 열심히 테스트해주는 크루들과 코치님들 덕분에 즐겁게 런칭 페스티벌을 마무리할 수 있었다.
Level3를 마치며
Level4를 마치고 있는 지금 Level3를 마치며를 적는게 조금 웃기지만ㅋㅋ level3는 참 우여곡절이 많았다. 여러번 변경한 협업 방식과 팀의 방향성 변경 번아웃 대처 등등.. 이렇게 제대로 된 프로젝트를 하는 것이 거진 처음이라.. 재밌기도 했고 힘들기도 했고 뿌듯하기도 했다!
npm run deploy 실행시 에러 발생!
우테코 Level4 개인 미션 시작 전, 사전 작업인 api key 발급과 .env
설정, node 버전을 모두 올바르게 맞췄음에도 npm run deploy
를 실행하면 다음과 같은 에러가 발생했다.

npm run deploy
?
npm run deploy
는 npm run build:prod && npx gh-pages -d dist
를 실행한다. build는 정상적으로 작동하지만 npx gh-pages -d dist
명령어를 실행하면 에러가 발생했다.
npx gh-pages -d dist
명령어는 gh-pages
패키지를 사용하여 GitHub Pages에 프로젝트를 배포한다. 이때, -d dist
옵션은 배포할 디렉토리를 dist로 지정하는 것이다.
gh-pages
패키지?
gh-pages
는 GitHub Pages에 웹사이트를 배포하는 데 도움을 주는 도구이다.
GitHub Pages?
GitHub에서 호스팅되는 웹사이트를 쉽게 배포할 수 있는 서비스이다.
에러 원인 발견 및 해결!
즉, gh-pages 브랜치를 push 할 때 문제가 발생하는 것이다.
난생 처음 보는 문제로… gpt에게 물어봐도 이상한 소리만 답으로 줬다..ㅎ
그래서 나는 구글링을 했다.
이 글 에서 도움을 얻었다.
자, 에러를 잘 뜯어보자 RPC 뭐시기 뭔지는 모르겠지만 send-pack에서 뭔 sideband packet 뭐시기가 뜬다. 이것도 뭔 소리인지 모르겠다. 그렇다면 그 밑을 보자.
fatal: the remote end hung up unexpectedly
는 “원격 끝에서 예기치 않게 연결이 종료되었습니다”라는 말이다.
해당 에러가 발생하는 이유는 post buffer의 사이즈 문제라고 한다.
git에서 기본적으로 1개의 파일의 최대 용량이 1MB로 설정되어 있다. 그런데 이 사이즈를 초과한 파일을 push하려고 할 때 발생하는 에러였다. 때문에 git의 post buffer (즉, push === post) 사이즈를 늘려줬다. 그러니 해결됐다!!
문제 해결 명령어
git config http.postBuffer 1048576000
아, 참고로 기본 값은 1048576이다.
무사히 deploy가 실행된 터미널!

참고 자료
git fatal 오류 해결: the remote end hung up unexpectedly Everything up-to-date
Git, fatal: The remote end hung up unexpectedly
git fatal: the remote end hung up unexpectedly 오류 조치
2차 스프린트. 그러니까 2차 데모데이가 종료되었는데 까먹고 작성하는 것을 놓쳐버렸다.. 그래서 지금이라도 작성해본다.
2차 스프린트 시작과 함께 우테코 해커톤

2차 스프린트가 시작되는 7월 15일 월요일. 우테코에서 처음으로 개최한 해커톤이 진행되었다.
해당 해커톤 기간은 우테코에서 유일하게 밤을 샐 수 있는 기회라고 하셨다. 그래서 이런 기회를 그냥 놓칠 수 없는 나는 월-화 캠퍼스에서 자기로 결정했다.
아침 데일리 스크럼 시간에 우리 프로젝트의 핵심 기능은 어떤 것일지 꽤 긴 논의를 거쳤다. 그러면서 필요없는 기능도 쳐냈고 가장 우선순위를 두어야 할 것이 무엇인지 알 수 있었다. 또한, 각자 같은 기능에 대해서 다르게 생각하는 것들이 존재했기에 컨텍스트를 맞출 수 있었다.
생각보다 같은 기능을 다르게 생각하는 것이 많다는 것을 이 일을 계기로 처음 알게 되었다. 팀원들과 컨텍스트를 맞추는 것이 중요하구나를 페어 미션 이후에 또 느끼게 되었다.

우리 팀의 핵심 기능 단위는 “행사 정산 기능”으로 정했다. 지난번에 설문을 통해 사람들에게 행사를 진행/참여하면서 가장 필요하다고 느끼는 것이 어떤 것인지 물어봤었다. 그 중 가장 많은 비율을 차지한 것이 정산과 관련된 것이었다. 물론 정량평가이긴 했지만, 이 문항들도 팀원들이 직접 공통적으로 느꼈던 부분들을 추린 것이기 때문에 나름 신빙성이 존재하는 결과라고 생각한다. 따라서 위에 말한 “행사 정산 기능”을 우리의 핵심 기능 단위로 정했다.
이렇게 우리 팀의 핵심 기능 단위를 정했고 백엔드와 프론트엔드 각자 해커톤 기간동안 할 일을 정했다. 프론트엔드는 최소 기능을 담는 페이지 퍼블리싱을 완료하고자 했다. 이 Task를 각각 2명씩 나눴다. 디자인 시스템 담당 2명과 퍼블리싱 담당 2명으로. 퍼블리싱을 담당하는 팀이 디자인 뼈대만 잡아두고 기능을 구현하면 추후에 디자인시스템 팀에서 만든 컴포넌트를 붙이는 형식으로 진행하고자 했다.
이렇게 디자인시스템까지 들고 가게된 이유는 해커톤을 위해 코드를 얼렁뚱땅 작성하지 말자고 이야기를 나눴다. 시간에 쫒기고 싶지 않아서 내린 결론이었다.
하지만 돌이켜보면 우리가 했던 것은 그저 밤새 개발이었지 해커톤은 아니었던것 같다는 생각이 든다. 돌아가는 쓰레기를 만들어두고 나중에 리팩토링을 작업하는 것이 더 좋았을 수도 있겠다라는 생각이 드는데.. 그 당시에는 리팩토링을 하는 것에 겁을 먹었던 것 같다.
그래서 일단 결과적으로 2명씩 나눠서 Task를 맡았던 것은 사실 그닥 결과는 좋지 않았다. 디자인시스템을 배포하는 과정에서 문제가 발생하여 결국 퍼블리싱 페이지에 디자인시스템을 붙히지 못했다. 그래서 우리는 뼈대만 존재하는 페이지로 시연을 진행해야 했다.. 하하
우테코에서 제공한 해커톤 저녁 및 간식
일 작업 방식을 바꿔보자
해커톤 기간 동안에 페어로 개발을 진행하면서 효율적이지 않은 것 같다는 생각이 들었다. 사실 1박 2일이라는 짧은 기간이기 때문에 코드 컨텍스트를 맞추고자 페어로 진행한 것도 있다.
그래서 이번에는 각자 Task를 나눠 개발을 진행하기로 했다. 각자 구현해야 할 기능들을 나눴고 정한 due date까지 기능 구현을 완료해 와야 했다. 이 방식으로 바꾼 후에 나는 굉장한 스트레스에 휩싸였다..
일단 내가 스트레스에 받게 된 이유를 정의하자면 다음과 같다.
- 정해진 기간동안 내가 할 수 없는 분량이었다.
- 정해진 기간 안에 완료할 수 없다는 생각이 강하게 드니까 압박감이 들었다.
- 스트레스를 너무 받다 보니 일 효율이 더 떨어진다.
- 기간은 부족한데 일 효율도 안 나니까 더 스트레스를 받는다.
위 1~4번의 무한 반복이었다.
이런 문제점을 깨닫고 due date에 다 못했음을 말했고 기간은 넘겨서까지 일을 진행하게 되었다. 이 일주일도 조금 안되는 기간동안 엄청난 스트레스를 받다 보니 어떻게 이 문제를 해결해야 할지 감이 잡히지 않았다. 그런 순간 포비랑 준과 팀 단위 티타임을 가지게 되었다.
가장 작은 단위로
이 티타임 동안 정말 많은 깨달음과 해결책을 얻었다.
나의 이런 스트레스를 받고 있는 상황을 준에게 이야기하게 되었다. 준은 당연히 현업 개발자도 며칠 뒤의 기간동안의 계획을 세우기는 어렵다고 했다. 그렇기에 하루 단위로 Task를 할당하라고 했다.
Level2 수업에서도 준이 매번 말했던 것은 “가장 작은 단위로” 였다. 그렇다. 일 분배 또한 가장 작은 단위로 나눠서 진행하는 것이 좋은 해답이었다. 그날 할 일을 정하고 그 일을 오늘 안에 끝낼 수 있는지 %를 매겨본다. 50%가 넘는다면 해결 할 수 있는 Task라는 것이다. 80 이하라면 더 작게 나눠서 다시 Task를 만든다. 그렇게 가장 작은 단위 하나를 오늘의 할 일로 할당하는 것이다. 이렇게 일을 분배한다면 Task를 끝냈다는 성취감이 올 것이다.
일을 진행하면서 가장 중요한 것은 성취감인 것 같다. 내가 힘들었던 이유도 아무리 해도 일이 끝나지를 않으니 성취감이 존재하질 않았다. 그러니 더더욱 쳐지게 되는 것이고, 내가 뭘 얼마나 더 해야 할지 감이 잡히질 않았을 것이다. 앞으로는 이런 방법으로 일을 나눠봐야 겠다고 생각했다.
각개전투가 아닌 협업
모두가 공통적으로 생각하는 부분은 협업을 하고 있지 않다고 느껴진다였다. 프론트는 프론트끼리 일을 나눠 작업을 하니 협업하는 느낌이 들지 않았다. 그리고 백엔드와는 일단 통신을 진행하는 부분이 없다 보니 백엔드와 협업한다는 느낌이 들지 않았다.
그렇기에 우리는 다음과 같이 작업을 바꿔보자고 결론을 내렸다.
프론트엔드 2명씩 짝 지어서 기능을 개발해보자. 그리고 백엔드 2명과도 한 팀이 되어 기능을 구현해보자.
아직 이 방법을 실천하는 것은 2차 데모데이가 종료되고 스프린트3 기간에 진행하자고 논의를 마쳤다. 해당 방식을 사용한 부분에 대해서는 3차 스프린트 회고에 적도록 하겠다.
2차 데모데이
하기 전에 일단 회식

2차 데모데이 전날인 목요일.. 우리는 우리가 개발한 기능을 데모데이에 보여주기 위해서 전날 회식하고 직접 사용해보자고 하였다. 그래서 우리는 배포한 서버가 백호 말고 아무도 접속할 수 없는 상황임에도.. 냅다 회식을 했다. 그래도 우리 팀이 화목한 것 같아서 좋았다.
“초기 기획 및 구현은 이렇게 하는걸 의도한 것이다.”
우리 팀이 듣게 된 최고의 칭찬이다. 앞으로도 이 칭찬을 뛰어 넘을 것은 사실 없을 것 같다.

데모데이는 2시라서 그 전까지 목요일에 해결하지 못한 서버 접속 에러를 해결하고 자잘한 디자인 및 기능을 수정했다. 다행이도 데모데이 전에 무사히 해결하여 코치님들 앞에서 시연을 할 수 있었다.
시연을 진행하면서 참석해주신 코치님(포비, 준, 브라운, 레아)들에게 극찬을 받았다. 가장 작은 단위의 핵심 기능을 잘 구현해온 팀이라고 해주셨다. 그리고 이미 완성도가 높다고 해주셨다. 이런 칭찬을 받으니 그간 기획에 대해 오랫동안 회의한 보람을 느낄 수 있었다. 기능 개발을 한 기간은 그리 길지 않음에도 만족시킬 수 있다니.. 모두가 오래 회의를 진행한 보람이 있었다.
그리고 내가 프로젝트를 진행하면서 걱정한 부분이 있었다. 바로 우리 프로젝트는 행사를 위한 프로젝트인데 너무 정산에 초점이 맞춰진 것 아닌가? 처음 기획 의도에서 좀 벗어나게 된 것 같다는 생각이 들었다.
이런 생각에 대해 여쭤보니 오히려 좋은 방향이라고 말씀해주셨다. 그렇게 좀 다른 방향으로 프로젝트가 흘러가게 되어도 좋게 서비스가 발전해나가고 있다는 것이니까 괜찮다고 본다!
2차 스프린트를 마치며
사실 2차 스프린트 2주의 기간동안 지옥과 천국을 맛 보았다.
개인적으로 스트레스를 너무 많이 받아서 너무 힘들었기도 했지만 티타임을 기점으로 멘탈을 회복하면서 데모데이에 칭찬을 받으며 천국을 맛 보았다.
또한, 1차 스프린트와는 다르게 프로젝트 진행 방식을 개별 기능 구현으로 변경했는데 이것 또한 문제점이 많이 보여서.. (시간이 부족하니 제대로 리뷰하지 않고 그냥 무작정 approve하기, due date에 치이기 등 ) 다음 스프린트에는 또 다시 페어로 돌아가게 될 것 같다. 이렇게 진행 방식을 바꿔가며 우리 팀에게 맞는 방향을 찾아가는 것이겠지 뭐 ~