Rails는 지난 20년간 웹 개발의 효율성을 높여왔으며, 37signals는 소규모 팀이 풀스택 애플리케이션을 빠르게 배포하는 데 중점을 둡니다. 이는 Hotwire(Turbo, Stimulus)를 활용한 점진적 개선 전략 덕분입니다. 본 문서는 Basecamp에 프로젝트를 시각적으로 그룹화하는 '프로젝트 스택' 기능을 Hotwire로 어떻게 구현했는지 설명합니다.
프로젝트 스택은 드래그앤드롭을 통해 스택 생성, 프로젝트 추가/정렬, 스택 비우기/삭제, 프로젝트 해제 등 복잡한 UI 상호작용을 제공합니다.
모델링은 기존 구조를 최대한 활용했습니다. Stack
은 Project
와 동일하게 Delegated Types
의 Bucketable
로 정의되어 Bucket::Pin
의 기존 정렬 기능을 재활용했습니다. 핵심은 Bucket::Pin
에 parent_id
를 추가하여 사용자별 중첩 구조를 지원하고, Positioned
concern을 확장하여 중첩된 요소들의 위치를 효율적으로 관리한 것입니다. 이는 최소한의 스키마 변경으로 이루어졌습니다.
백엔드에서는 기존 드래그앤드롭 시스템을 활용하여 position
과 parent_id
를 서버로 전송했습니다. Buckets::Pins::PositionsController
는 이 정보를 바탕으로 Bucket::Pin
의 reposition_to
메서드를 호출하여 위치를 업데이트하고, 프로젝트를 다른 프로젝트 위로 드래그하면 Stack.amalgamate
를 통해 새 스택을 생성하도록 처리했습니다.
UI 업데이트는 Hotwire의 Turbo Streams를 통해 실시간으로 이루어졌습니다. 스택 생성 시 드롭된 프로젝트를 새 스택으로 교체하고, 스택 내 프로젝트 카운터를 업데이트하며, 스택 해제 시 프로젝트를 루트 목록에 추가하는 등 모든 변경 사항을 즉각적으로 반영했습니다. 특히, 스택 해제와 같은 새로운 드래그앤드롭 상호작용은 Stimulus 컨트롤러로 구현하여 최소한의 JavaScript로 풍부한 사용자 경험을 제공했습니다. 스택 삭제 및 열기/편집 기능은 Turbo Streams와 Turbo Frames를 활용하여 효율적으로 구현되었습니다.
이 프로젝트는 Hotwire(Turbo 및 Stimulus)가 단일 프로그래머가 전체 기술 스택을 효율적으로 관리하며 풍부하고 반응적인 UX를 구축할 수 있음을 입증합니다. 단 37줄의 JavaScript와 소량의 Turbo Stream Ruby 코드만으로 기존 시스템에 복잡성을 추가하지 않으면서도 강력한 기능을 구현했습니다.