컬러 라벨, 테마 백엔드 설계하기

안녕하세요, LINER에서 Web Frontend를 담당하고 있는 제니🍑입니다. 벌써 라이너라는 배에 탑승한지 3개월이 되어 가네요! 저는 눈에 보이고, 사용자의 접점에 있는 개발이 좋아서 Client 개발자가 되어야겠다는 결심을 했었는데요, 그럼에도 Full stack에 대한 선망은 항상 마음 속 깊이 존재했던 것 같아요.

그런데 이번 알파 스프린트에서는 운이 좋게도 (?) 기존에 하던 프론트엔드 개발과 더불어 백엔드 개발의 기회를 얻게 되었습니다!!!! 이번 포스트에서는 그래서 개인적으로는 기대가 많이 되는 컬러 라벨, 컬러 테마 기능 추가에 대한 백엔드 설계 과정에 대해서 작성해 볼까 합니다.

What? (문제 상황)


Color Theme 의 다양화

간혹 가다 들어오는 CS 사항 중에서, 하이라이트 색상의 종류를 다양화하면 좋을 것 같다는 요청이 많이 들어왔다고 합니다. 저의 학창시절을 생각해 봤을 때도, 필통 내용물이 자존심의 원천인 시절이 있었는데요, 색상 별로 비싼 펜을 모으고, 하이라이터 색상도 최대한 다양하게 구비해서 갖고 다녔던 것을 생각해보면 충분히 납득 가능한 것 같습니다.

현재는 라이너에서는 Basic Theme만 제공되고 있고, 최대 5가지의 색상으로만 하이라이팅이 가능한 상황입니다.

출시가 대기 중인 <컬러 테마 바꾸기 기능>에서는, 2 가지의 새로운 Theme이 제공되고, Theme 마다 서로 다른 색상들을 제공할 예정이었습니다. 뿐만 아니라, 추후에는 사용자도 Custom Theme을 생성하고 Theme과 하이라이트 색상들의 더 자유로운 변주가 가능할 수 있는 상황을 염두해 두고, 백엔드 설계를 해야 했습니다

Color Label 기능 추가

하이라이트 관련, 두 번째 출시 대기 중인 기능은, 컬러 라벨 기능인데요, 이 기능은 컬러마다 사용자가 이 컬러는 내가 Important 한 것들을 밑줄 치는 색깔, 이 컬러는 Interesting한 것들을 밑줄 치는 색깔이다! 이렇게 정할 수 있는 기능입니다. 평소에 하이라이팅을 자주하는 저의 경우에도 색상을 용도마다 분류해서 쓰게 되는 경향이 있는데, 이런 수요를 만족 시킬 수 있는 기능이라고 생각합니다.

Color Order 변경 기능 추가

마지막으로 고려해야 했던 추가 기능은 하이라이트 색상의 순서를 변경하는 기능이었는데요, User가 순서를 변경하고 저장을 하면, 그 저장된 순서대로 Browser extension에서 하이라이트 팔레트에 띄워 주어야 하고, Color Filter Dropdown이나 기타 하이라이트 색상이 띄워지는 모든 부분에 변경한 순서대로 색상들을 정렬해서 띄워줘야 합니다. 뿐만 아니라, 새로 추가 되는 테마들 사이에서도 순서의 변경사항이 동기화 되어야 한다는 점이 중요합니다.

컬러 테마 사이에서 라벨이나 순서의 동기화라는 핵심 기능 때문에 백엔드 설계를 하면서 상당히 고민을 많이 해야 했습니다.

How? (문제 해결)


1. 기존 DB 구조 파악하기

컬러 라벨, 테마 기능이 새로운 모델 설계를 요하는 가장 큰 이유는 현재 하이라이트의 색상 관리가 특정한 color id 로 구분되고 있는 것이 아니라 바로 색상 Hex로 mapping이 되고 있었기 때문입니다 .

예를 들어,

“라이너는 정말 좋은 회사다.”

라는 문장에 하이라이트를 사용자가 하였다면,

하이라이트의 고유 id – 하이라이트의 내용 (“라이너는 정말 좋은 회사다”) – 하이라이트 색상 (파랑 #fd231)

이런 식으로 DB가 설계가 되어 있었습니다. 저렇게 색상으로 mapping 되어있는 기존 Highlight들을 최대한 migration을 피하면서 새로운 기능을 추가할 수 있도록 모델 구조를 생각해 보려 했습니다.

2. 머릿 속에서 표류하는 구조를 시각화 하기

저는 이전에 간단한 백엔드 개발 밖에 해보지 않아서, 모델 설계를 이렇게 해 본 경험은 처음이었습니다. 그래서 생각보다 고려해야 하는 여러 가지 기획 상의 제약 조건들, 그리고 또 제가 놓칠 수 있는 부분들이 많을 것 같아서 우선 ERM (Entity Relationship Model) 을 시각화 하는 것부터 시작했습니다.

구조를 시각화 하니, 그렉과 중간 중간 회의를 하면서 제가 놓치는 시나리오들을 현재 모델 구조가 커버할 수 있을까? 를 반복적으로 확인할 수 있었습니다. 특히 구조가 눈에 보이니까 조금 더 효율적으로, 디비 마이그레이션을 최소화하는 구조, 최대한 join을 덜하고 시간 복잡도를 줄일 수 있는 자료구조를 생각하는 것에 있어서 도움이 많이 되었습니다. (+Thanks to Greg)

또, 가까운 미래에 추가될 수 있는 하이라이트 관련 기능들을 최대한 수용할 수 있는 아주 유연한 구조를 설계하기 위해서 ERM 그림에 고려해야하는 상황들, 그리고 그에 대응하는 방안들에 대해서 설명도 중간 중간 추가해 두었습니다. 아키텍쳐 회의를 진행하면서 느꼈던 사항은, “기록해두지 않으면 무조건 까먹는다” 라는 것이었습니다. 그렉과 “아 이렇게 하면 되지~” 라고 회의 때 논의하고 기록하지 않고 넘어갔 사항들이 자리에 돌아온 순간에 머릿속에서 삭제되고 “왜 이렇게 하기로 했더라..?”라고 되돌아오게 되는 경험을 반복해보면서 역시 모든 생각의 흐름, 이거는 왜 이렇게 짰는가에 대해서는 모두 적어두는 것이 중요하다는 교훈을 줬습니다.

차근차근 Color Label, Theme, 그리고 순서 변경의 Synchronization까지 어떻게 설계하려고 했는지 살펴보겠습니다.

Multiple Highlight Theme에 대응하는 새로운 Flow

이제 새로운 두 가지의 Theme이 추가가 되면, 이 Theme 의 종류와 특성을 관리하는 Highlight Theme Table 하나, 그리고 그 Theme에 있는 색상들을 관리하는 Highlight Color Table이 추가적으로 필요합니다.

Highlight Theme에는 위와 같은 속성들이 있고, 언급하고 싶었던 것은 Theme Type입니다. Theme type에는 provided, extended, custom 세 가지의 type을 enum으로 설정했습니다.

Provided은 라이너에서 제공하는 테마들이고, Extended는 그런 테마들에서 사용자가 색상을 추가, 삭제해서 사용할 때, Custom은 완전히 새로운 색상 팔레트를 사용자가 생성할 때의 테마를 뜻합니다.

앞서 말씀 드린 추가 테마들은 모두 Provided이고 사실 Extended, Custom에 대한 기획은 아직 정해진게 없었지만 사용자에게 자유도가 최대로 주어진 상황에도 현재 db를 사용할 수 있도록 이 type을 추가했습니다.

이렇게 하이라이트 Theme의 아이디로 그 테마에 해당되는 색상들을 찾아야합니다. 즉, 여기서의 theme_id가 index가 되어서 Highlight Color DB에서 해당하는 테마의 색을 찾는 과정입니다

Highlight Order, Label Syncrhonization에 대응하기

앞서 언급했듯이, Highlight의 Theme마다 하이라이트의 색상 종류가 6개 이상일수도, 6개 이하일수도 있고, 하나의 유저는 여러 가지의 theme을 갖고, customize, extend을 할 수도 있으며, 그 순서를 변경하거나 각 하이라이트 색상에 라벨을 바꿔도 그것이 모든 theme마다 동기화가 되어야하는 상황입니다.

처음에 이렇게 자유도가 큰 서로 다른 하이라이트 색상 수와 순서를 가지는 테마에서 순서, 라벨을 동기화하려면 테마 마다 동일한 어떤 기준이 필요하다고 생각했습니다. 그래서 Slot이라는 개념을 도입했다.

하이라이트 테마, 색상의 대원칙은 위에 내용입니다.

Slot- Color – Label은 항상 테마 상관없이 함께 간다는 것입니다.

그렇기 때문에, Slot Order Table 과 Label Table은 Slot의 id로만 접근해서 하이라이트 색상을 정렬, 라벨을 매핑할 수 있게 되는 것입니다. 그리고, 사용자는 결국 자기 user id에 해당하는 order row를 slot의 개수마다 갖고 있고, 테마에 상관없이 slot만 갖고 있으면 되는 것입니다. 참고로 Slot Order 테이블은 Linked list의 구조를 써서 prev, next를 저장하고 있어서 순서 정렬을 용이하게 할 수 있습니다. 만약 어떤 테마에서는 없는 slot_id가 있다면 그냥 무시하고 next에 접근하면 되기 때문에 깔끔한 모델 구조를 갖고 있을 수 있습니다.

기타 모든 상황들에 대응하기

위 구조까지 오게 되기까지 정말 많은 상황들을 고려해야했습니다. 예를 몇 가지만 들자면,

  1. 유료 유저가 무료 유저가 되어서 사용되는 색상이 제한 되는 경우,
  2. 하이라이트 색상을 유저가 추가했다가 삭제를 하는 경우의 slot 관리
  3. Custom Theme에서의 하이라이트 추가 삭제
  4. Extended Theme에서 하이라이트 추가후 삭제했을 때 테마 관리

등등 이었습니다. 개발을 하면서 추가적인 고려사항들과 제약사항들이 닥칠 수 있지만, 우선적으로는 생각해낼 수 있는 상황들에는 대응 가능한 모델 구조를 짜려고자 하였습니다.

So What?

부끄럽게도 제가 Express 개발 경험이나 모델 설계에 대해 숙련도가 많이 낮아서 이번 알파 스프린트에는 아키텍쳐 설계까지만 하고 끝나버렸습니다. 이렇게 아키텍쳐 설계를 직접해보니까 이 기능에 대한 애정이 무럭무럭 생겨버려서 꼭 구현을 직접 해보고 싶다는 생각이 들었습니다.

백엔드 부분의 설계와 Express, Sequelize 공부를 해보니 프론트 엔드의 api Call 등에 대한 이해도가 훨씬 커졌고 백엔드 경험을 통해서 좀 더 단단한 개발자가 되고 싶다는 욕심이 생기더라고요!!!(지금은 좀 많이 물렁..한 것 같습니다) 다음 알파 때는 필히 이 기능이 직접 구현이 될 수 있도록 또 열심히 공부할 생각입니다. BURNING.

다음 스프린트 글에서 실제로 구현을 성공했고, 어떻게 구현했는지 썰을 풀 수 있는 포스트로 돌아오는게 목표입니다. I will be back.