[이지로그]편리하고 깔끔한 일정관리 & 메모 앱

5 more properties

배경(Problem)

프로젝트의 방향성에 대하여
‘멋진 기술을 사용하는 것보다는 사용자에게 유용한 서비스를 만들자’에 중점을 뒀습니다. 주어진 시간은 많지 않았기에 최대한 우리의 관심사와 관련이 있고, 도메인이 크고 복잡하지 않아서 빠르게 개발이 가능한 애플리케이션이 뭐가 있을지 고민했고, 자연스럽게 우리가 자주 사용하는 기존 애플리케이션을 개선하자는 쪽으로 생각의 방향이 움직였습니다. 우리에게 불편한 것은 타인에게도 충분히 불편할 수 있기 때문입니다. 그러다 저희는 기존의 메모-일정관리(todo list) 애플리케이션이 주는 불편함에 대해 생각하게 되었고, 이 프로젝트를 기획하게 됩니다.
기존 애플리케이션의 문제점
기존 시장에는 수많은 일정 관리용 애플리케이션과 메모 애플리케이션이 출시되어있습니다. 이것들을 모두 사용해 본 결과 다음 세 가지의 문제를 도출해낼 수 있었습니다.
용도에 따라 흩어져 있는 메이저 애플리케이션
todo도 어떻게 보면 일종의 메모라고 간주할 수 있습니다. 우리는 이러한 메모를 한 군데서 관리해야 할 필요성을 느꼈습니다. 용도에 따라 다양한 애플리케이션을 사용할 수도 있습니다. 예를 들면 메모는 메모 애플리케이션을 사용함으로써. todo 관리는 todo 애플리케이션을 사용함으로써. 일정을 한눈에 보고 싶을 때는 캘린더 애플리케이션을 사용함으로써. 컴퓨터를 쓸 때는 컴퓨터용 애플리케이션으로, 휴대폰을 쓸 때는 휴대폰용 애플리케이션으로. 그러나 이는 우리의 입장에서 비효율적이라 느껴졌습니다.
이는 우리 7명 대부분이 단 한 곳에서 기록을 하지 못하는 원인이기도 할 것 입니다.
무겁고 어렵습니다
노션으로 해결하면 되는 거 아닌가하는 의문이 들 수 있습니다. 그러나 노션은 굉장히 다양한 기능을 포함하고 있으며, 단순한 기록 및 일정 관리 용도로 쓰기엔 무겁고 부담스러운 감이 있습니다. 또한, 러닝커브가 있습니다. 그렇다면 가볍다고 소문난 옵시디언은 어떨까요? 매우 훌륭한 애플리케이션이지만 노션보다 러닝커브가 더 높습니다. 따라서 저희는 수많은 기능을 포함하고 있는 어려운 애플리케이션 말고, 그냥 기억, 생각, 기록, 일정관리를 위한 모든 것을 언제 어디서든 한 곳에서 쉽게 생성할 수 있고 볼 수 있으며 관리할 수 있는 가벼운 애플리케이션이 있었으면 좋겠단 생각을 했습니다.
각 애플리케이션들의 단점
앞에서 언급한 노션이나 옵시디언 말고도, 다른 애플리케이션들에도 여러 단점들이 있었습니다.
타임블록은 매우 가독성 좋은 캘린더 + 일정관리 애플리케이션이나, 아쉽게도 데스크탑에서는 사용하기 힘듭니다.
마이크로소프트 todo는 일정의 분류를 매우 혼란스럽게 하는 시스템을 가지고 있으며, 한 눈에 todo를 살펴보지 못합니다.
google keep은 매우 간편하나, 편의 기능이 부족하고 역시 한눈에 일정을 볼 수 없습니다.
그 외 todoist나 Tick Tick은 사용자가 input에 ‘매 주 과제하기' 를 입력하면 알아서 캘린더에 해당 일정을 추가해준다는 장점이 있으나 ‘오늘부터 이틀 후 까지 ~하기'와 같이 연속적인 일정에는 적절한 반응을 하지 못합니다.

서비스 소개(Solution)

개선하고자 했던 것들
본연의 기능에 충실하여 애플리케이션을 최대한 가볍게 만듭니다.
기존 애플리케이션들의 장점은 취하고, 단점은 최소화합니다.
사용자가 애플리케이션을 어디에서도 사용할 수 있도록, 브라우저를 기반으로 하여 모바일 환경과 데스크탑 환경을 통합시킵니다.
이렇게 하여 궁극적으로는 사용자가 단 한 곳에서 간단하고 가볍게 기록 및 일정을 관리할 수 있도록 합니다.
또한, 기존 애플리케이션에는 없는 편의 기능을 통해 편의성을 증대시킵니다. 이것은 이지로그의 차별점이기도 합니다.
1.
카카오톡 채널 연동
2.
chatGPT 기반의 Quick Input
핵심 기능 소개
시연 영상
애플리케이션은 크게 Today, Calendar, Memo 페이지로 구성되어있습니다.

기본 메모

사용자가 원하는 메모를 작성할 수 있도록 합니다. 일반적인 텍스트 뿐 아니라, 헤딩 등 마크다운 요소들을 지원하며, 표 또한 자유롭게 삽입할 수 있습니다.
메모는 파일-디렉토리 구조로 저장할 수 있도록 하여, 메모를 주제마다 분류하기 쉽도록 했습니다.
기본적으로 로그인하지 않아도 사용 가능합니다.
따로 저장 버튼을 누르거나 하지 않아도, 자동으로 저장이 됩니다.

카카오톡 채널 연동 메모

나에게 보내기 기능을 통해 메모를 하는 사람들도 있습니다. 이 기능을 사용할 때처럼, 채널을 통해 메모를 기록하고, 해당 메모를 애플리케이션에 저장하여 메모를 한 곳에서 관리할 수 있도록 합니다.
로그인해야 사용 가능합니다. (유저를 모으기 위한 의도입니다.)

캘린더 - Today

캘린더 페이지에서 일정을 생성, 입력, 삭제 할 수 있습니다. 그리고 ‘오늘’에 해당하는 일정과 기간이 ‘오늘’에 걸쳐진 일정을 Today 페이지에서 볼 수 있습니다.
기본적으로 로그인하지 않아도 사용 가능합니다.

Quick Input

Quick Input에 일정을 입력하면, 해당 내용을 해석하여 자동으로 캘린더에 표시해줍니다. ‘17일 oo하기’ 뿐 아니라, ‘오늘부터 이틀 후 까지 oo하기’와 같이, 좀 더 복잡한 요구사항에도 적절히 반응하도록 합니다.
로그인해야 사용 가능합니다. (유저를 모으기 위한 의도입니다.) 로그인하지 않았을 때 input과 button은 disabled 됩니다.

아키텍처

FE

BE

활용 라이브러리 및 개발 환경

FE

React
프론트엔드 팀원 모두가 잘 알고 있는 라이브러리이기도 하고, 좀 더 선언적인 프로그래밍, 코드 재사용과 원활한 협업을 위해 사용했습니다.
Typescript
타입 명시를 통해 예상치 못한 에러를 방지하고, 일종의 문서화 효과를 누리기 위해 사용했습니다.
React Router Dom
SPA를 쉽고 빠르게 구현하고자 도입했습니다.
Axios
기존의 fetch 함수보다 편의성이 높고, 특히 4xx 응답에 더 옳은 반응을 해주기 때문에 채택했습니다.
React Query
네트워크 통신을 통해 받아오는 데이터가 갱신되었을 때, 데이터를 다시 가져오고 리렌더링하는 과정을 코드 몇 줄로 압축할 수 있기 때문에 도입했습니다.
캐싱 기능의 이점을 얻고자 도입했습니다.
Vite
개발 환경에서 Vite의 핫 모듈 리로딩은 기존의 번들러와는 달리, 수정된 파일 만을 리로드해서 띄우기 때문에 매우 빠릅니다. 프로덕션 환경에서도 빌드 퍼포먼스를 최적화합니다. 따라서 CRA를 사용하지 않고 Vite를 도입했습니다.
MUI
일관된 디자인을 시스템을 가진 UI 컴포넌트를 직접 구현하지 않고 빠르게 개발할 수 있도록 하기 위해 도입했습니다.
Tailwind CSS
스타일에 대한 세세한 요구사항의 변화에 대응하기 위해 도입했습니다.
lodash.debounce
사용자가 메모를 입력할 때 마다 매번 저장하는 요청을 보내게 되면 서버에 부담이 가기때문에 lodash의 debounce를 도입했습니다.
Dexie.js
브라우저의 indexedDB 기능을 쉽게 사용할 수 있도록 해주는 기술입니다.
다른 기술도 있었지만, 커뮤니티가 활발하고 공식문서가 체계적으로 잘 꾸려져 있어서 선택하게 되었습니다.
사용자가 로그인하지 않고 메모를 저장할 수 있도록 하려면, 브라우저의 어딘가에 저장해야 하는데 로컬 스토리지를 사용하기에는 무리가 있다고 판단했습니다. 왜냐하면 메모의 자료구조는 파일-디렉토리 구조인데 로컬스토리지로 이것의 CRUD를 구현하는 것은 힘들 것 같다는 생각이 들었기 때문입니다. 대신에, 이와 같이 복잡한 구조를 더 잘 나타낼 수 있는 IndexedDB를 사용하기로 했고, indexedDB 자체는 러닝커브가 있기 때문에 개발 시간을 줄이고자 Dexie를 선택하게 되었습니다.
TinyMCE
사용자가 메모를 할 때, Word를 사용할 때 처럼 heading, paragraph 등의 마크다운 요소를 사전 지식 없이 자유롭게 사용하게 하려면 rich text editor가 필요합니다. 그러나 이것을 직접 구현하기에는 시간이 없었습니다. 따라서 라이브러리를 사용하기로 했습니다.
저희에게 필요한 rich text editor는 리액트를 제공하고, 타입을 제공하며, 성능면에서도 우수하고, 무엇보다 모바일 환경에서도 최적화되어있는 text editor인데 TinyMCE가 이 모든 조건을 충족하여 선택하게 되었습니다.
Vercel
배포 과정을 간소화하기 위해 사용했습니다.
react-big-calendar, react-arborist
MUI가 제공하지 않는 복잡한 기능들을 제공하는 UI 라이브러리들입니다.
각각 캘린더 기능, 디렉토리-파일 CRUD 기능을 쉽게 구현하기 위해 사용했습니다.
다른 라이브러리들도 있었지만 역시나 커뮤니티가 활발하고 공식문서가 체계적으로 구성되어있어 사용하기로 결정했습니다.

BE

Java 17
SpringBoot 3 이상의 버전을 사용하기 위해서 Java 17을 사용했습니다.
record를 사용해서 DTO를 편리하게 작성하기 위해서 사용했습니다.
SpringBoot 3.1.5 & Spring Security
최신 버전의 Security 를 사용해서 더 높은 보안수준을 구축하기 위해 사용했습니다.
Spring Data JPA
MongoDB 와 Mysql 을 같은 프로젝트에서 편리하게 사용하기 위해서 도입했습니다.
MongoDB
메모 기능의 경우, 파일시스템의 Directory 구조처럼 Hierarchy 를 가지고 있는데 이는 RDB보단 MongoDB로 표현하기 더 수월하기 때문에 도입했습니다.
고유키인 ID로 바로 조회가 가능하기 때문에 탐색 성능면에서도 효율적이라고 판단하여 사용했습니다.
Spring WebFlux
ChatGpt 를 활용한 QuickInput 기능 구현을 위해 도입했습니다.
JWT
카카오 로그인, 토큰 인증 방식의 회원 관리를 위해서 도입했습니다.
Swagger
API 문서 자동화를 위해서 도입했습니다.
MySQL
안정적인 DB 구조를 위해서 도입했습니다.
AWS
안정적이고 편리하게 클라우드 환경을 구축하기 위해서 도입했습니다.

트러블 슈팅

FE

MUI의 SwapableDrawer가 Swapable 하지 않아요!
여기서 말하는 SwapableDrawer란?
반응형 레이아웃을 위해(모바일) 메모 페이지에서 파일-디렉토리 구조를 보여주는 UI를 Drawer 안에 넣고, 사용자가 옆에서부터 밀어서 여는 제스쳐를 취할 때 해당 UI를 보여주는 요소입니다.
원인 휴대폰 기종마다, 특정 제스쳐를 취하면 해당 기종 고유의 행동을 취하는 경우가 있는데, 그것이 브라우저에서의 이벤트 감지도 방해하는 듯 했어요.
그리고 Text Editor의 이벤트 흐름과 꼬이게 되어 이벤트가 제대로 인식이 되지 않는듯 했어요.
해결 관련 props를 줘서 조정해봐도 해결되지 않자, 궁극적으로 선택한 방법은 버튼을 만드는 것이었어요. 제일 확실한 방법이기도 하고, 애초에 이지로그는 브라우저에서만 동작하는 어플리케이션이라서, 제스쳐만으로 열고 닫는 UI 요소가 있으면 그것은 기기 고유 동작과 꼬이게되어 사용자에게 혼동을 줄 것 같다는 생각이 들었어요. 따라서 최종적으로 버튼을 도입하기로 했습니다.
<좌:버튼 우:SwapableDrawer>
Vercel이 React Router Dom에 설정한 route를 인식하지 못해요!
원인 React Router Dom을 사용해서, 저희는 사용자가 사이트에 접속할 때 path를 “/”로 설정해서 접속하면, 무조건 “/today”로 가게끔 처리했어요. 이게 로컬 환경에서는 잘 동작이 되는데 Vercel에 배포하고보니 배포된 앱은 이것을 전혀 인식하지 못했어요. 이유는 간단했어요. 번들링된 파일은 내부적으로 “/” 경로의 요청에 대한 응답은 가지고 있지만 “/today” 경로의 요청에 대한 응답은 가지고 있지 않기 때문이었어요. 왜냐하면 이것은 React Router Dom을 사용하여 프로그래밍적으로 설정한 것이기 때문이에요.
해결 루트 디렉토리에 vercel.json 파일을 만들어 다음과 같이 작성했어요.
{ "rewrites": [{ "source": "/(.*)", "destination": "/" }] }
JSON
복사
위 파일의 의미는 다음과 같아요. 슬래쉬(/)로 시작하는 모든 요청은 “/”를 요청하는 것과 같다.
이렇게 해주니 배포된 앱이 ‘아, /today를 요청하는 건 /를 요청하는 것과 같구나. 그럼 그냥 ‘/’에 해당하는 응답을 가져오면 되겠구나’하고 인식할 수 있었어요.
위와 같이 rewrite는 서버가 클라이언트에게 보이는 URL을 변경하지 않고, 내부적으로 요청을 다른 대상으로 전달할 때 사용돼요.
사용자가 입력한 날짜를 받아서 react-big-calendar에 넣어줬는데 날짜가 달력에 표시되지 않아요!
원인 사용자가 로그인하지 않은 상태에서도 일정을 입력할 수 있도록, 로컬 스토리지를 사용했어요. 로컬 스토리지에 데이터를 저장할 때는 “문자열화”를 시키는데, 이것이 버그의 원인이 되었어요. react-big-calendar가 받는 데이터의 날짜 property는 Date 타입이어야하거든요. 그런데 우리는 문자열이 된 날짜를 react-big-calendar에게 주고 있었어요.
해결 원인을 밝히는 것이 힘들었지 해결하는 것 자체는 어렵지 않았어요. 그저 데이터를 파싱하는 과정에서 다시 날짜 property를 Date 객체로 변환시켜주면 되는 거였으니까요. 하지만 타입의 중요성, 공식문서 제대로 읽기의 중요성을 다시금 일깨워준 버그였답니다.

BE

크램폴린에서 AWS로의 이동
원인 크램폴린 환경에서는, 아무래도 카카오 내부 자원을 사용하다보니 조심스럽게 사용해야하는 것들이 많았어요. 따라서 외부 API를 호출하는 것도 까다로웠고 정상적으로 호출할 수 있도록 하기 위해 여러 방법을 모색했어요. 그러다 시간이 많이 흘렀고, 결단을 내려야할 때가 왔어요. 해결 방법이 어딘가에 있을테지만 그것을 찾아낼 만큼 쿠버네티스와 그 외 설정들에 관해 공부하기에는 남은 시간이 얼마 없었어요.
해결 익숙한 AWS 로의 전환을 통해, 빠르게 외부 API를 호출할 수 있는 환경을 마련할 수 있었어요. 이 경험을 통해 현 시점에서는 불가능할지도 모르는 한 가지 방법에만 몰두하는 것보단, 더 넓은 시야를 가지고 다른 방법을 모색하는 것이 나을 수도 있다는 것을 배웠어요.
KoGPT에서 ChatGPT로
원인 원래는 사용자가 퀵 인풋에 입력한 내용을 해석하고, 알맞은 자료구조로 파싱하는데 KoGPT를 사용할 계획이었어요. 그러나 요구사항은 KoGPT가 내놓는 결과물보다 조금 더 섬세한 것을 원했어요.
해결 ChatGPT로의 전환을 통해 요구사항을 충족할 수 있었어요. 사용하고자 했던 기술이 요구사항을 충족하지 못할 수도 있으므로, 여러가지 가능성을 열어두고 기술을 고려하고 선택해야한다는 것을 배웠어요.

기타

동기화 정책
기본적으로 이지로그는 사용자가 로그인하지 않아도 사용할 수 있는 애플리케이션입니다. 따라서 사용자가 로그인했을 때, 로그인하지 않은 상태에서 작성한 메모 및 일정을 어떻게 동기화할 것인지 고민했습니다. 의견을 나누다가 결정한 로직의 흐름은 다음과 같습니다.
로그인하지 않은 상태로 애플리케이션을 이용할 시, 사용자의 정보를 받을 수 없으므로 사용자가 입력하는 모는 내용은 로컬 스토리지, 그리고 indexedDB에 저장한다. 사용자가 로그인하면, 로그인하는 즉시 그 내용들을 서버로 보내 데이터베이스에 저장한다.
그런데 한 가지 문제가 있었습니다. 일정의 경우, 데이터 구조가 복잡하지 않아서 데이터베이스에 저장하기 그리 까다롭지 않은데, 메모의 경우, 파일-디렉토리 구조의 depth가 깊어질수록 데이터베이스에 저장하는 연산의 시간복잡도가 크게 증가하며, 이는 성능에 안좋은 영향을 끼치게 된다는 것입니다.
따라서, 프론트에서는 사용자가 로그인하지 않은 상태라면 폴더의 depth를 1을 넘지 못하도록 제한했습니다. 이렇게 하니 백엔드에서도 훨씬 수월하게, 성능에 무리가 가지 않는 선에서 동기화 로직을 작성할 수 있었습니다.
미래지향적으로 생각해본다면, 만약 이 플리케이션을 시장에 내놓을 경우 이 결정은 사용자의 로그인을 유도하는 효과까지 가져올 수 있으리라 생각합니다.
프론트엔드와 백엔드 간의 호흡의 중요성을 느껴볼 수 있었던 시간이었습니다.

팀 소개

팀 소개말

자유로운 아이디어로 프로젝트를 하며, 협업 스킬과 각자가 원하는 기술적 역량을 성장시키는 것이 목표인 팀, Project6S입니다.
지정된 과제인 WebIDE, 파이널 프로젝트인 이지로그 뿐 아니라, 자율적인 프로젝트인 여행 계획 플랫폼 K-tour Planner, Velog를 모방한 공부 기록용 블로그 StudyLog를 통해 실용적인 배움을 추구하고, 커뮤니케이션 비용을 줄일 방법을 고안해나가며 성장을 도모했습니다.
<K-tour Planner>
<StudyLog>
저희 팀의 강점은 긴밀한 소통입니다. 매일 진행한 화상회의를 통해, 각자의 진행 상황, 애로 사항들을 공유하여 모두가 목표에 관해 모호함이 아닌 분명함을 가지도록 했습니다.

팀원 소개

박소미 | Frontend / 조장 | youyoy689@gmail.com
강신규 | Backend | rkdtlseb@naver.com
권순한 | Backend | soonable@gmail.com
김서아 | Frontend | seoa521@gmail.com
양지원 | Frontend | puding0712@naver.com
유지완 | Backend | rjw10004@gmail.com
김재민 | Backend | kjaemin0122@naver.com