동아리/학회 출석 확인 웹 서비스 만들기
방학은 정말 짧은 것 같다. 분명 2달전에 이번 방학은 계획적으로 살아야겠다는 마음을 먹고 계획을 짜려고 마음을 먹었는데, 어느새 수강신청 날이 다가와 있었다.
여름방학이 3일 남짓 남은 시점에 내가 이전 기수로 활동했었던 동아리의 운영진으로 활동하는 친구를 만났는데, 돌연 출석 체크 시스템의 어려움을 토로했다. 그 동아리에서는 알럼나이 제도를 운영하고 있었고, 출석 체크를 통해 일정 이상 결석 시 알럼나이 활동을 못하는 등 불이익이 주어졌기에 운영진들이 출석, 지각, 공결 등의 기록을 Notion을 이용해 수기로 하고 있었고, 총 결석 수 등을 종합할 때에는 동아리 부원의 이름을 각각 검색 후 육안으로 찾아야 해서 매우 귀찮은 일이라고 했다. 그래서 출석 관리를 전산화 하는 방안을 가볍게 모색중이었고, 나도 그 사실을 전해 듣게 된 것이다.
나도 해당 동아리에서 활동하며 공결 / 병결 처리를 위해 운영진에게 개인적으로 메신저를 보내는 것이 부담스러운 면이 있었고, 좀 더 효율적인 방법이 있었으면 좋겠다고 생각했던 찰나에 출석 시스템을 전산화하고자 하는 의지가 있던 운영진들이 Figma로 개략적인 서비스 outline도 가져오니 개발하고자 하는 욕구가 생겨났다. 특히 최근에 Discord에서 앱으로 QR Scanner를 이용해 컴퓨터에서 편리하게 로그인 할수 있는 시스템을 보고 정말 좋았다는 생각을 했기에, QR로 편리하게 동아리 출석을 관리할 수 있도록 하는 웹 서비스를 만들고, 추가적으로 공결, 병결 요청과 증빙자료 제출을 할 수 있는 창구로써의 기능을 제공하면 나름 잘 이용될 수 있을 것이라는 확신이 들었다.
다만 매 학기마다 하고 싶은 사이드 프로젝트 개발을 하느라 학교 공부에 집중하지 못하는 것 같아 돌아오는 학기에서는 학부 수업 외에는 절대 개발을 하지 않고자 마음먹었기에, 2일 이내에 개발하는 것으로 목표를 잡고 개발을 시작하였다.
관련 링크
서비스 구조
가장 처음 생각한 부분은 QR 코드를 운영진(이하 어드민이라 하겠다)이 생성 후, 이를 동아리 부원(이하 멤버라 하겠다)이 스캔하여 출석을 인증받는 방식으로 할지, 아니면 동아리 멤버가 자신의 QR 코드를 생성하여 운영진의 기기로 스캔하여 출석을 인증받는 방식으로 할지이다. 비교적 빠른 결정을 내렸는데, 학교에서는 후자를 시행하고 있었고, 휴대전화는 주로 손바닥과 뒷면이 맞닿게 들고 다니기에 화면의 QR 코드를 스캐너의 인식 영역에 갖다 대는 것이 은근히 번거로운 과정임을 인지하고 있었다. 또한 동아리 세션을 생각해 보았을 때 운영진이 QR 코드를 발급받아 프로젝터, 외부 모니터 등 접근성 높은 시각 매체로 QR 코드를 멤버들에게 보여줄 수 있다면 모두에게 조금 더 편리할 것 같아 전자의 방식을 채택하였다. 물론 보안, 부정 출석에 대한 고민은 더 해봐야겠지만 일단은 세션 하나 당 시크릿 키를 하나씩 발급하여 DB에 저장하고, 이를 인코딩한 QR을 object storage에 업로드 후, 업로드한 링크를 어드민 api로 전달하는 과정을 통해 최종적으로 멤버에게 QR코드를 전달하는 과정을 고안하였다. QR Code를 만드는데 이용한 키를 클라이언트에 전달해서 이를 클라이언트에서 QR로 재구성하여 렌더링하는 것이 훨씬 쉽지만, 웹 애플리케이션 특성상 종단간 보안이 취약하므로 시크릿 키를 직접 전달하고 싶지는 않았고, 어차피 이미지, 파일 업로드 로직을 구현하려면 object storage가 있으면 좋았기에 해당 방식을 이용하였다.
빠른 개발을 위해 코드를 빠르게 작성할 수 있도록 Node진영의 Nest.js와 postgreSQL을 채택하였다. 유저 Authentication 방식은 standalone, email-password 방식을 이용하였고, session token을 쿠키에 저장하여 endpoint를 보호하는 방식을 이용하였다. 또한 병결/공결 처리 시 필요한 증빙자료 업로드, 프로필, 동아리 대표 사진 업로드, QR Code Image 업로드를 위해 Minio Object Store를 이용하였다. Minio는 open-source s3-compatible object store인데, 내 홈서버가 있는데 s3 storage를 굳이 결제해서 이용하고 싶지 않아 애용하고 있다.
마지막으로 고민한 부분은 프론트엔드 부분이다. 가장 익숙한 Next.js를 이용할 것은 분명했는데, 어드민 웹은 구현한다 쳐도 유저에게 모바일 웹 환경에서의 QR scanning 과정은 번거로울 것이 뻔했다. 그렇다고 2일 내에 cross-platform 모바일 개발까지 하는 것은 역량이 달릴 것이 분명했기에, 조금은 미숙한 대안으로 PWA(Progressive Web App)으로 클라이언트를 제작하기로 결정하였다.
디자이너 친구에게는 미안하지만 시간이 시간인지라 디자인 시안은 참고만 하고 내 마음대로 css를 개발 친화적으로 만들었다. 확실히 개발자는 디자인에 구애받지 않을 때 행복한 것 같다. 물론 디자이너에게 양해를 구하지는 않았지만 말이다.
스크린샷
로고도 물론 피그마로 내가 제작하였다. 디자이너에게 보여줬을 때 반응은 물론 “다시 만들어주겠다” 였다.
PWA 기능을 이용해 모바일 환경에서 다운로드한 모습이다. PWA가 없었다면 Flutter로 앱을 개발했을텐데, 생각만 해도 끔찍한 일이다.
멤버 유저가 가장 처음 보게되는 화면이다. QR scanner를 즉시 열 수 있으며, 그룹 찾기, 생성하기 등의 기능을 floating button으로 이용할 수 있다.
자신이 속한 그룹의 세션 목록을 달력 뷰를 이용해 볼 수 있다.
QR Scanner이다. 한 세션에 두 번 출석하거나, 자신이 속한 그룹이 아닌 QR 스캔 등 비정상적 행위 시 사진처럼 오류 toast가 뜬다.
어드민이 볼 수 있는 화면이다. 오늘 세션이 있다면 QR을 생성하여 아래와 같이 fullscreen으로 띄울 수 있다.
어드민의 경우 위와 같이 속한 멤버 상태 관리, 그룹 참여 요청을 관리할 수 있다.
또한 차례로 달력에서 날짜를 선택, 세션을 선택하여 멤버의 출석 관리 및 공결 신청 관리를 한 눈에 할 수 있다.
세션 생성의 경우 하나씩 만들거나, 주기적인 세션의 경우 한번에 생성할 수 있는 기능을 제공하였다.
돌아보며
확실히 Copilot이 있으니 반복되는 코드를 어쩔 수 없이 작성해야 할 때, jsx component 코드를 작성할 때 등 편리한 부분이 많았지만, 뭔가 특색있는 기능, 코드를 넣고자 할 때에는 한계가 아직 보였다. 그래도 이 친구가 목표했던 개발 기한을 지킬 수 있음에 상당 부분 기여한 것은 부정할 수 없는 사실이다.
또한 누군가의 실제적인 불편함, 니즈를 해결하기 위해 specific한 해결책으로 서비스를 개발해본 경험은 매우 인상적이었는데, 지금까지는 주로 내가 필요한 서비스, 내가 제작하고 싶은 서비스를 만들어왔기 때문에 유저를 모으기가 힘들었으며, 피드백도 받기 어려웠다. 하지만 이번 경우 확실히 사용할 유저가 있으며 피드백도 나올 수 있기에 개발자로서의 부가적인 역량 향상에 도움이 되리라 믿는다.
이번 학기에는 공부만 하려했지만 프로젝트가 최소 3개 있다는 것이 개강 첫 주에 확정되었다. 심지어 모두 다른 언어, 프레임워크로 해야할 듯 한데 아무래도 VS code와 거리두기는 어려울 듯 싶다.
Enjoy Reading This Article?
Here are some more articles you might like to read next: