2025-04-11
3월부터 시작된 마지막 부트캠프 팀 프로젝트를 최근에 마무리했습니다. 이번 프로젝트는 약 6개월간 이어진 부트캠프의 마지막 과제로, 그동안 배운 기술과 경험을 모두 녹여낼 수 있는 기회였습니다. 단순히 결과물을 만드는 것에 그치지 않고, 팀원들과 함께 기획 단계부터 서비스의 구조, 사용성, 확장 가능성까지 깊이 있게 고민하며 프로젝트를 완성해 나갔습니다.
무엇보다 마지막 프로젝트라는 부담감보다는 책임감으로 임하며, 그동안 부족했던 부분을 채우고자 스스로에게 더 높은 기준을 요구했던 시간이었습니다. 기술적으로는 단순한 구현이 아니라 왜 이렇게 구현해야 하는지, 더 나은 방법은 무엇인지 끊임없이 질문하고 고민하는 습관을 기를 수 있었습니다. 또한 다양한 이슈를 직접 해결해 나가며 특정 기술에 대해 더 깊이 이해하고 실무적으로 활용할 수 있는 자신감도 얻게 되었습니다.
이번 프로젝트는 결과물 이상의 의미가 있었습니다. 단기간에 성장할 수 있었던 이유는 팀원들과의 긴밀한 협업뿐만 아니라, 스스로 기술에 대해 진지하게 고민하고 배우려는 자세를 놓지 않았기 때문이라고 생각합니다.
지금부터는 저희 팀이 진행한 프로젝트에 대해 설명드리겠습니다. 전체적인 흐름보다는 구현 중심으로 간결하게 정리해 보여드릴 예정이며, 주요 기능과 기술적 고민이 담긴 부분들을 위주로 소개드리겠습니다.
[github repo] : https://github.com/kss761036/Epigram
[service url] : https://epigram-gilv.vercel.app/
[storybook url] : https://epigram-storybook.vercel.app/
[presentation pdf] : https://www.slideshare.net/slideshow/12-4-ppt-12-4-ppt-12-4-ppt/277795857
에피그램은 명언을 공유하고, 감정을 기록할 수 있는 커뮤니티 중심의 웹 서비스입니다. 사용자는 명언을 매개로 다른 사람들과 소통할 수 있으며, 자신의 감정을 기록하고 시각화하여 감정의 흐름을 돌아볼 수 있는 기능을 제공합니다.
다른 좋은 주제들도 많았지만 에피그램을 선택하게 된 이유는, 감정 표현과 소통의 공간이 부족한 현실을 바탕으로, 감정 관리와 사용자 간 상호작용이 공존하는 플랫폼의 필요성을 느꼈고, 이를 실제 서비스 수준으로 구현해 볼 수 있는 주제라 판단하여 선택하게 되었습니다.
프로젝트 진행에 앞서, 팀원들과 함께 유지 보수성과 협업 효율성을 높이기 위한 폴더 구조에 대해 충분히 논의하였습니다. 그 결과, 기능과 목적에 따라 역할별로 명확히 구분된 구조를 설계하였고, 각자의 작업 범위가 명확해짐에 따라 개발 과정에서도 보다 원활한 협업이 가능했습니다.
PR이 제출되거나 main 브랜치에 머지될 때마다, 자동으로 Storybook 프리뷰 링크가 생성되도록 GitHub Actions를 설정하였습니다. 이를 통해 각 컴포넌트의 구현 결과를 쉽게 확인하고, 빠르게 리뷰할 수 있는 개발 흐름을 만들 수 있었습니다.
Tailwind CSS를 사용하는 프로젝트였기 때문에, 일관된 UI 구현과 유지 보수를 위해 색상, 타이포그래피 등의 디자인 토큰을 설정하였습니다. 특히 Tailwind CSS가 v4로 업데이트되면서 설정 방식에 변화가 있었고, 새로운 방식에 맞춰 @theme 지시문을 활용해 토큰을 적용했습니다. 덕분에 전체적인 스타일 관리를 보다 체계적으로 할 수 있었고, 컴포넌트 간의 스타일 일관성도 자연스럽게 유지되었습니다.
사용자 인증이 필요한 페이지에서는 Next.js의 미들웨어 기능을 활용하여, NextAuth의 세션이 존재하지 않을 경우 자동으로 로그인 페이지로 리다이렉트되도록 처리하였습니다. 이를 통해 불필요한 페이지 접근을 사전에 차단하고, 보다 안전한 사용자 흐름을 구현할 수 있었습니다.
백엔드 API 호출 시에는 Next.js의 catch-all segment를 활용하여, 프론트엔드에서 발생하는 API 요청이 먼저 Next.js 서버를 거치도록 구성하였습니다. 이 과정에서 axios의 request interceptor를 사용해 토큰을 자동으로 헤더에 포함시킨 후 백엔드 서버로 요청을 전달하도록 처리하였습니다.
프로젝트의 전체 인증 흐름은 NextAuth를 기반으로 구성하였습니다. 사용자의 로그인 상태를 전역적으로 관리하고, 세션 기반으로 접근 제어가 필요한 페이지를 보호하는 데 활용했습니다.
다양한 상황에서 재사용할 수 있도록 size와 color를 동적으로 받을 수 있는 유연한 구조로 구현하였습니다.
이미지가 없는 경우에도 사용자 정보를 직관적으로 표현할 수 있도록 유저네임의 첫 글자를 활용한 폴백 처리까지 함께 설계하였습니다. 이를 통해 예외 상황에서도 사용자 경험을 해치지 않도록 고려하였고, 안정적인 UI 구성에 기여할 수 있었습니다.
공용 드롭다운 컴포넌트는 확장성과 접근성을 고려하여 설계하였습니다. 기본이 되는 베이스 드롭다운 컴포넌트를 먼저 제작한 뒤, 다양한 상황에 맞는 드롭다운 UI들이 해당 베이스 컴포넌트를 상속하거나 조합하여 파생될 수 있도록 구성하였습니다.
또한, 컴파운드 패턴과 Context API를 활용하여 드롭다운 내부의 상태 및 동작을 유연하게 관리할 수 있도록 하였고, W3C의 WAI-ARIA 패턴 가이드를 참고하여 키보드 내비게이션, 포커스 등 접근성 관련 기능도 함께 개선하였습니다.
<Dropdown>
<DropdownTrigger>버튼</DropdownTrigger>
<DropdownMenu direction='horizontal'>
<DropdownItem>아이템1</DropdownItem>
<DropdownItem>아이템2</DropdownItem>
<DropdownItem>아이템3</DropdownItem>
</DropdownMenu>
</Dropdown>
감정 차트 컴포넌트는 Chart.js를 커스터마이징하여 도넛 형태의 차트로 구현하였습니다. 단순히 데이터를 내부에서 처리하는 방식이 아닌, 외부에서 데이터를 주입받아 렌더링하는 구조로 설계함으로써 컴포넌트의 재사용성과 테스트 용이성을 높였습니다.
또한, 데이터 전달에 혼선이 생기지 않도록 명확한 데이터 인터페이스를 정의하였고, 다른 팀원들도 쉽게 사용할 수 있도록 타입 구조를 구체화하였습니다.
프로젝트 기간이 비교적 길었던 만큼, 단순한 기능 구현에 그치기보다는 기술적인 흐름을 더 깊이 이해하고, 문제를 직접 해결해보는 경험을 쌓는 데 집중하고자 했습니다.
문제가 발생했을 때는 단순히 검색에 의존하기보다는 공식 문서와 레퍼런스를 꼼꼼히 읽고, 지금 구현하고 있는 기능의 동작 원리와 구조에 대해 스스로 질문하며 풀어보려는 태도를 유지했습니다. 이러한 과정 속에서 단순한 구현 이상의 통찰과, 문제를 마주했을 때 어떻게 접근하고 해결할지를 고민하는 습관을 기를 수 있었습니다.