Journey 엔티티를 만들었다가 폐기했다
흩어진 항목을 묶을 새 엔티티 Journey를 80%까지 만들고 폐기한 이야기. 엔티티의 경계는 격리해서는 안 보이고, 다른 것과 연결할 때 비로소 드러난다는 깨달음.
Journey 엔티티를 만들었다가 폐기했다
시작은 “통합 레이어가 필요하다”는 직관
흩어진 기능들 — 템플릿, 루틴, 회고 — 이 사용자 머릿속에서만 묶여 있다는 게 평소 신경 쓰였다. 시스템 차원에서 그 묶음을 인식하면, 길게 이루는 것에 더 도움이 될 거라 생각했다. 그래서 “여러 항목을 한 목표 단위로 묶는 새 엔티티”를 만들기로 했다.
이름은 처음에 Goal이었는데, “Goal”은 결과 압박/제약감이 강해서 거부됐고, Journey(여정)로 정했다.
1단계, 2단계까지 깔끔하게 구현
서버에 Journey 모델 + CRUD 엔드포인트를 만들고, 모바일에는 Achiever 탭 진입점 + 목록/생성/편집/메뉴 모달까지 만들었다. 기존 Project 패턴을 그대로 따라가서 코드 스타일도 일관됐고, 실제로 동작도 잘 했다.
여기까지 두 번 커밋했다. 이때까지는 잘 가고 있다고 믿었다.
3단계 설계에서 균열이 보이기 시작했다
3단계는 “Task / Project / Reservation을 Journey에 연결”이었다. 단순하게 각 모델에 journey_id 외래키를 추가하면 될 것 같았다.
여기서 첫 균열이 왔다.
Journey는 개인적인 거고 Project랑 Task는 공용이야. 그래서 journey_id를 연결하는 건 안 맞다고 봐.
맞는 말이었다. 공용 엔티티에 개인 컨텍스트 필드를 박는 건 데이터 모델을 더럽힌다. 같은 Project를 A는 자기 “다이어트” 여정에, B는 “건강 관리” 여정에 묶고 싶을 수 있는데, 그게 동일한 컬럼에 들어가면 깨진다.
그래서 junction collection으로 방향을 틀었다 — journey_links라는 별도 테이블에서 (journey_id, linked_id, linked_type, created_by) 형식으로 다대다 관리. 링크 자체가 개인 소유라 공용 엔티티를 더럽히지 않는다. 깔끔한 설계로 보였다.
그러다 더 깊은 균열이 짚어졌다.
만들수록 Journey랑 Project 구분이 모호해지는데.
순간 정직해질 수밖에 없었다. 맞다 — 지금 만들고 있는 “항목 묶는 컨테이너 Journey”는 멤버 0명짜리 Project와 거의 같다.
두 엔티티의 차이가 무엇이었나
- Project = 단체 협업 목표, 멤버 공유
- Journey = 개인 목표, 본인만
차이는 “공유 여부” 하나뿐이었다. 기능적으로는:
- 둘 다 title, description, deadline을 가짐
- 둘 다 task를 묶는 컨테이너 역할
- 둘 다 “안에 뭐가 있는지”를 화면으로 보여줌
진짜 차별화는 위계가 아니라 의미여야 했는데 — 어디에서 다르게 행동하는가 — 그걸 코드로 풀어내지 못한 채, 외형만 비슷하게 만들고 있었다.
만들기 전엔 안 보였다
웃긴 건, 연결을 설계하기 전까지는 이 겹침이 안 보였다는 것이다.
엔티티 자체만 보면 Journey와 Project는 다르게 느껴진다. 이름도 다르고, 의도한 의미도 다르다. 하지만 “다른 항목과 어떻게 연결할까”를 설계하기 시작하니까, 두 엔티티가 같은 모양의 그릇이라는 게 드러났다.
엔티티의 경계는 그 자체로는 안 보이고, 다른 것과 연결할 때 비로소 드러난다. 격리해서 정의한 엔티티는 깔끔해 보이지만, 시스템 안에서 다른 엔티티와 닿는 면을 만들기 시작하면 그제야 진짜 모양이 나온다.
그래서 80%를 짓고 폐기했다
서버 + 모바일 UI + i18n + atom + 화면 4개 + 컴포넌트 2개 = 두 번의 커밋. 다 만들고 동작 확인까지 했는데 폐기했다.
비효율 같지만, 이전 글 (실패한 시도들의 가치)에서 썼듯이 — 폐기된 시도가 남기는 건 “싫음”의 기록이다. 이 시도가 남긴 건 한 문장이다.
새 엔티티를 만들기 전에, 기존 엔티티와의 경계가 어디서 어떻게 다른지 먼저 풀어내야 한다. 경계는 격리해서는 안 보이고 연결할 때 드러나니까, 가능하면 연결 시나리오를 먼저 그려봐야 한다.
이 문장은 다음 결정에서 더 빠르게 작동할 거다.
다음
방향을 바꿨다. “Journey를 만들지 말자”가 아니라 “Project를 더 잘 만들어 보자”로. 멤버 0명일 때도 자연스럽게, 개인 루틴까지 포함할 수 있게, 진행률/회고/마일스톤을 가질 수 있게. 이전에 Journey에 부여하려던 의미가 사실 Project에 더 잘 맞았던 게 아닐까.
오늘은 코드 한 줄 안 늘었지만, 한 가지 명확해졌다. 그것만으로도 하루가 의미 있었다.