“지친 일상 속, 에너지를 다시 움직일(reboot) 최적의 모임을 만나다”
관심사에 맞는 모임을 탐색하고, 참여·개설·관리할 수 있으며,
리뷰와 자유게시판 기능까지 제공하는 커뮤니티형 모임 플랫폼
기존 모임 서비스는 정보가 흩어져 있거나 탐색 과정이 복잡해, 사용자가 자신에게 맞는 모임을 찾고 참여 이후의 소통까지 이어가기 어렵다는 불편이 있었습니다.
RE:BOOT(리부트)는 이러한 문제를 줄이기 위해 지역, 날짜, 타입 기반의 탐색과 찜하기, 모임 참여하기 등으로 최적의 모임을 찾아 참여하고, 모임 개설 및 수정·삭제로 모임을 관리하며, 리뷰와 커넥트(자유 게시판)를 통해 사용자들 사이에서 소통하고, 알림과 마이페이지를 통해 개인 활동을 관리할 수 있는 구조로 설계했습니다.
- 모임 탐색: 지역 · 날짜 · 카테고리 기반으로 원하는 모임 탐색
- 모임 참여/관리: 모임 참여, 찜하기, 모임 개설 및 관리 기능 제공
- 리뷰 기능: 참여 후 리뷰 작성 및 조회 지원
- 커뮤니티 기능: 커넥트(자유게시판)에서 게시글 · 댓글 기반 소통 지원
- 개인화 기능: 알림과 마이페이지를 통한 개인 활동 관리
마이페이지 GNB & 알림내역 |
랜딩페이지, 찜한모임 모든리뷰, 404페이지 |
모임 상세페이지 |
로그인, 회원가입 유저페이지 |
모임찾기 모임 만들기 모달 |
커넥트(자유게시판) CRUD 전 부분 프로필 모달 |
Frontend
협업 및 프로젝트 관리
기술 선택 이유 및 용도
| 구분 | 기술 | 선택 이유 |
|---|---|---|
| Frontend | Next.js | App Router 기반 라우팅과 (auth) / (main) route group 분리를 통해 페이지 흐름을 구조적으로 관리하기 위해 사용 |
| Frontend | TypeScript | API 요청/응답 타입, props, 서버 데이터, 상태 구조를 안정적으로 다루기 위해 사용 |
| Frontend | Tailwind CSS | 반복 UI를 빠르게 구현하고 반응형 스타일을 한 파일 안에서 일관되게 관리하기 위해 사용 |
| 상태 관리 / 데이터 패칭 | TanStack Query | 서버 상태, 캐시, 무한 스크롤, mutation 이후 동기화를 한 흐름으로 관리하기 위해 사용 |
| 상태 관리 / 데이터 패칭 | Zustand | 가볍고 직관적인 전역 클라이언트 상태 관리를 위해 사용 |
| 상태 관리 / 데이터 패칭 | React Hook Form | 폼 상태와 유효성 검사를 효율적으로 처리하기 위해 사용 |
| 상태 관리 / 데이터 패칭 | Zod | 스키마 기반 유효성 검사로 타입 안전성을 확보하기 위해 사용 |
| 개발 환경 / 품질 | MSW | 백엔드 미완성 상황에서도 API 응답을 가정한 Mock 환경에서 프론트엔드 기능을 독립적으로 개발하고 테스트하기 위해 |
| 개발 환경 / 품질 | Storybook | 컴포넌트 단위 UI 개발 시 문서화와 테스트 |
| 개발 환경 / 품질 | ESLint / Prettier | 코드 스타일 일관성과 정적 분석 기반 품질 관리 가능 |
| 개발 환경 / 품질 | pnpm | 빠른 패키지 설치와 효율적인 디스크 공간 관리로 개발 환경을 가볍고 일관되게 유지 |
모든 페이지는 반응형(모바일, 태블릿, 데스크톱)으로 구현되었습니다.
- CTA 중심 랜딩 구조
- 페이지 전반에서 모임 탐색으로 이어지는 행동 유도를 중심에 두고 섹션을 배치
- 스크롤 기반 Sticky 섹션 구현
- 스크롤 진행에 따라 단계별 콘텐츠가 전환되도록 구현하고, 반응형 환경에서도 한 화면 내에서 섹션 전체가 안정적으로 보이도록 레이아웃과 여백 최적화
- 서비스 흐름을 단계적으로 설명하는 구조
- 모임 발견 → 참여 → 사람 연결 → 다음 모임으로 이어지는 경험을 순서대로 보여주도록 구성
- 이메일/비밀번호 기반 로그인 및 회원가입
- Google(팝업) / Kakao(리다이렉트) 소셜 로그인 지원
- 모달과 전용 페이지 두 가지 진입 방식 지원
- 실시간 유효성 검사 및 비밀번호 표시/숨김 토글
- 인증 보안
- accessToken / refreshToken을 httpOnly 쿠키에 저장해 XSS/CSRF 방어
- accessToken 만료 시 자동 재발급 후 원래 요청 재시도
- 회원가입 후 자동 로그인, 실패 시 로그인 페이지로 안내
- 인증 상태 변경 시 React Query 캐시 즉시 동기화
- 무한스크롤
- gcTime 5분, staleTime 0
- 찜하기나 모임 참여 관련 낙관적 업데이트, 목록 데이터는 바로 stale 처리하나 즉시 갱신하지 않음
- 업데이트가 빈번하게 일어나는 데이터이기 때문에 prefetch는 사용하지 않음
- 필터링, 검색 기능
- 브라우저 쿼리스트링 사용으로 주소창 직접 입력 시 필터링된 데이터 표시 가능
- 필터링된 데이터가 화면에 반영되지 않는 이슈 발생
- Suspense+useSuspenseInfiniteQuery 사용 시 AnimatePresence 렌더링 이슈가 있어 useInfiniteQuery 로 변경
- 페이지 스크롤 시 필터 목록 포지셔닝
- 비회원 유저는 진입 불가
- 두 가지 진입 방식
- 직접 URL 입력 또는 새로고침을 통해 진입
- 모임 찾기에서 버튼을 통해 진입(모달;Parallel,Intercepting Routes)
- 직접 접속하는 경우 모달 폼과는 다른 레이아웃으로, 좌측에 애니메이션 이미지 표시됨
- 배포 환경에서, 모임 생성 완료 후에도 같은 수준의 페이지(/meetup/…)에 모달이 뜨는 이슈 발생
- Nextjs 이슈를 확인하여 현재 주소를 확인하는 조건 추가
- 단계별 폼 작성
- 한 개의 form 사용, 현재 단계가 아닌 fieldset을 css 로 숨김
- 현재 단계의 필드가 유효하지 않으면 다음 단계로 넘어갈 수 없음
- 실시간 검사를 위해 controlled input 사용
- provider로 모든 필드 데이터를 공유, 제출 시점에 요청 데이터 형식으로 일괄 변환
- 다음 버튼 활성화 시 엔터키를 사용해 다음 단계로 넘어갈 수 있음
- 모든 필드에서 엔터 사용 감지: onKeyDown 이벤트 사용
- 단 기본 Enter 동작은 허용/입력 중이 아닐 때만 동작(textarea 등)
- 폼 외부이면서 모달 내부를 클릭하는 경우 동작하지 않는 이슈 발생
- onBlurCapture (blur 이벤트 + capture true 옵션) 를 추가하여 특정 조건에는 포커스를 폼으로 옮기도록 제어
- 모든 필드에서 엔터 사용 감지: onKeyDown 이벤트 사용
- 임시 저장 기능
- 실시간 sessionStorage에 저장
- 새로고침하더라도 데이터 유지
- 카카오 주소 검색
- 디바운싱 처리 및 문자가 합성 완료되었을 때 검색
-
모임 상세 정보
- 모임 일정에 따른 deadline(마감 기한) 표시/미표시 & 참여 버튼 비활성화
- 찜하기 가능
- 주최자/참여자에 따른 UX/UI 구분
- 주최자:
- 공유하기
- 모임 수정 & 삭제
- 사용자:
- 참여하기 / 참여 취소하기
- 주최자:
-
참여 인원 목록
- 기본 인원 목록 표시 4명
- 5명 초과 시, +N 활성화
- 해당 +N 버튼 클릭 시, 전체 참가 인원 목록 조회, 10개씩 렌더링
- 아래로 스크롤할 때마다 10개씩 무한 스크롤
-
카카오 맵
- 응답받은 주소 값에 따라, 카카오 맵 UI 표시
- 주소 수정 시, 즉시 해당 주소 값으로 리렌더링
-
리뷰 조회
- 5개 이상 리뷰 등록 시, 페이지네이션 적용 (Default: 4개)
- 리뷰 작성자일 시, 리뷰 수정/삭제 가능
-
관련 모임
- 같은 지역(region) & 같은 카테고리(type) 기준으로 관련 모임 조회
- 찜하기 가능
-
각 섹션 별 스켈레톤 정의
- 하나의 섹션에서 오류 발생 시, 다른 섹션은 정상 동작 & 해당 섹션만 재시도
- 서버 프리패치 + 하이드레이션 기반 초기 렌더링
- 첫 진입부터 필터 조건이 반영된 데이터를 바로 출력
- 무한 스크롤 기반 목록 조회
- 페이지 이동 없이 목록을 연속 탐색할 수 있도록 구현
- 목록 필터
- URL 쿼리스트링 기반으로 필터 상태 관리
- 새로고침, 공유, 재진입 시에도 동일한 조건 유지
- 모임 타입 탭, 모임 날짜, 지역, 정렬 기준으로 필터링
- 반응형 필터바 UX
- 데스크톱·태블릿에서는 sticky 고정
- 모바일에서는 스크롤 다운 시 숨김, 스크롤 업 시 재노출
- 필터 변경 시 목록 최상단 지점으로 스크롤 위치 보정
- URL 쿼리스트링 기반으로 필터 상태 관리
- 액션 이후 연관 쿼리 invalidate 처리
- 목록, 상세, 헤더 카운트, 마이페이지 등 연관 데이터 동기화
- 상태별 UI 분리
- 초기 로딩은 스켈레톤, 추가 로딩은 로더, 빈 결과는 Empty UI, 에러 발생은 재시도 UI 제공
- 비회원 유저 진입 불가
- 찜한 모임 목록 조회
- 목록 정렬 지원
- 찜한순, 모임 생성순, 모임 날짜순, 마감 임박순, 참여 인원순
- 찜하기 해제
- 해제 즉시 찜한 목록에서 제거
- 참여하기 / 참여 취소
- 카드에서 모달로 진입해 모임 정보를 확인한 뒤 참여 여부 변경 가능
- 액션 이후 관련 데이터 동기화
- 전체 리뷰 목록 조회 및 평점 요약 통계 제공
- 모임 타입별 통계 조회 지원
- 목록 정렬 지원
- 작성일순, 점수순, 참여 인원순
- 회원은 본인 리뷰만 수정 및 삭제 가능
- 작성자 프로필 클릭 시 프로필 모달 제공
- 긴 리뷰 내용 접기 / 더보기
- 2줄을 초과하는 경우 더보기·접기 버튼 노출
게시판 메인 페이지
- 게시글 목록
- 전체 게시글 목록 조회 (서버 사이드 prefetch 적용)
- 키워드 기반 게시글 검색
- 정렬 필터 — 최신순 · 좋아요순 · 조회수순 · 댓글 많은순
- 페이지네이션 기반 목록 탐색
- 이번 주 HOT 게시물 섹션 별도 표시 (좋아요·조회수·댓글 기준 인기글)
- 목록 카드에 좋아요 수 · 댓글 수 · 작성자 표시
- 게시글 상세
- 게시글 내용 · 조회수 · 좋아요 수 · 댓글 수 표시
- 좋아요 토글 (추가 / 취소)
- 작성자 본인에게만 수정 · 삭제 버튼 노출
- Intercepting Routes 적용 — 목록에서 클릭 시 URL 유지하면서 모달로 상세 표시, 새로고침 시 전체 페이지로 자연스럽게 전환
- 게시글 작성 / 수정 / 삭제
- 제목 · 내용 · 이미지 입력
- 유효성 검증 적용
- 작성 · 수정 완료 후 목록 자동 이동
- 삭제 완료 시 토스트 알림 표시
댓글
- 댓글 작성 · 수정 · 삭제
- 댓글 목록 무한스크롤 (IntersectionObserver 기반, 3개씩 추가 로드)
- 최신순 정렬
- 본인 댓글에만 수정 · 삭제 버튼 노출
- 비로그인 상태에서 댓글 작성 시 토스트 알림
공통 :
- 로그인한 사용자의 활동을 관리할 수 있는 페이지
- 프로필 수정, 리뷰 작성, 리뷰 수정의 input의 경우 검증 규칙은 zod 스키마로 분리하고, 폼 상태는 RHF를 통해 관리함으로써 UI 로직과 검증 로직을 분리 dirty 상태를 활용해 모달을 실수로 닫아도 사용자 입력이 없어지지 않도록 UX 개선
- 각 컴포넌트 별 ErrorBoundary + Suspense 설정으로 다른 탭에서 오류가 발생해도 해당 탭만 재시도하고 다른 탭은 정상 동작 가능, 이때 유저가 직접 재시도를 할 수 있도록 재시도 버튼 제공
프로필 설정 :
- 닉네임 : 닉네임 최대 8자 제한
- 프로필 이미지 수정
- 1MB 초과 시 이미지 업로드 제한
- 이미지 포멧을 JPEG, PNG, WebP, GIF 로 제한
탐색 탭 :
-
모임관리
- 참여 모임 : 내가 참여한 모임과 개설한 모임을 한꺼번에 관리할 수 있는 탭으로 모임 일시 기준 내림차순으로 제공
- 모임 상태에 따라 사용자 행동 버튼을 다르게 제공 참여 취소 / 개설 확정 / 개설 취소 / 모임 삭제 / 찜 관리
- 모임 진행 상태를 한눈에 확인할 수 있도록 배지 UI 제공 이용 예정 / 개설 대기 / 개설 확정 / 개설 취소 / 이용 완료 / 리뷰 작성완료
- 개설 모임 : 내가 개설한 모임을 관리할 수 있는 탭으로 개설 일시 기준 내림차순으로 제공된다
- 참여 모임과 달리 참여한 모임 관리를 할 수 없으므로 참여취소 버튼을 제외한 모든 action / badge 제공
- 참여 모임 : 내가 참여한 모임과 개설한 모임을 한꺼번에 관리할 수 있는 탭으로 모임 일시 기준 내림차순으로 제공
-
리뷰 관리
- 리뷰 작성 : 완료된 모임 중 작성하지 않은 리뷰 목록을 볼 수 있으며 모임 일시 기준 내림차순으로 제공된다.
- 리뷰 작성이 가능하다
- 리뷰 목록 : 완료된 모임 중 작성한 리뷰 목록을 볼 수 있으며 작성일 기준 내림차순으로 제공된다.
- 리뷰 더보기 / 접기 기능으로 일관된 리뷰 layout 제공
- 리뷰 수정 / 삭제를 할 수 있는 버튼 제공
- 리뷰 작성 : 완료된 모임 중 작성하지 않은 리뷰 목록을 볼 수 있으며 모임 일시 기준 내림차순으로 제공된다.
-
탐색 탭 내부 컨텐츠 이미지 및 모임 명 클릭시 상세 이동
-
상태 별 UI 제공
- 최초 진입: Skeleton UI
- 최초 진입 이후 로딩 상태: Loader
- 데이터가 없는 경우: Empty
- 에러가 발생한 경우: QueryErrorBoundary
-
탐색 탭은 모두 무한 스크롤 기반 탐색 제공
-
무한스크롤 UX 개선을 위해 mediaQuery 별 스크롤 주체 분리 및 scrollTop 버튼 제공
- 탭 이동시 해당 탭의 첫번째 항목을 볼 수 있도록 스크롤 위치 보정
-
1280px 이상의 경우 넓은 화면을 활용하여 탐색 중에도 프로필 수정 및 탐색을 자유롭게 하기 위해 탭 컨텐츠 내부를 기준으로 스크롤 가능
-
1279px 이하의 경우 탭 컨텐츠 내부를 기준으로 스크롤 하면 탐색 가능영역이 좁아져 window로 변경하되 탭을 sticky 형태로 제공
├── 📁 app/
│ ├── 📁 (auth)/ # 로그인, 회원가입 경로
│ │ ├── login/
│ │ └── signup/
│ ├── 📁 (main)/
│ │ └── 📁 <케밥 케이스>/ # 모임 찾기, 찜한 모임, 모든 리뷰, 자유 게시판 등등...
│ │ ├── page.tsx
│ │ └── layout.tsx
│ ├── layout.tsx
│ └── page.tsx
│
├── 📁 components/ # 전역 재사용 컴포넌트
│ ├── 📁 ui/ # 기본 UI 컴포넌트 (Button, Input 등)
│ │ └── Button/
│ │ ├── index.tsx
│ │ └── index.stories.tsx
│ ├── 📁 commons/ # 범용이되 도메인 강결합이 아니며 필수 사용이 아닌 컴포넌트
│ └── 📁 layout/ # 레이아웃 컴포넌트 (Header, Footer)
│
├── 📁 features/ # 기능 단위 구조
│ ├── 📁 shared/
│ │ └── 📁 components/ # 도메인 결합이 강하지만 여러 feature에서 함께 사용하는 컴포넌트
│ └── 📁 <카멜 케이스>/
│ ├── 📁 components/ # 해당 feature 내부에서만 사용하는 컴포넌트
│ ├── apis.ts # api 호출
│ ├── mutations.ts # useMutation
│ ├── queries.ts # useQuery
│ ├── types.ts # 해당 feature에서 사용하는 타입
│ ├── hooks.ts # 해당 feature에서만 사용하는 hooks (폴더 가능)
│ └── utils.ts # 해당 feature에서만 사용하는 utils (폴더 가능)
│
├── 📁 libs/ # 공통 라이브러리 설정 및 인프라 모듈
├── 📁 utils/ # 공통 유틸 함수
└── 📁 hooks/ # 공통 커스텀 훅
구조 설계 원칙
- 인증 관련 페이지
(auth)/ 일반 페이지(main)로 route group 분리 app/하위 폴더명: 케밥 케이스 /features/하위 폴더명: 카멜 케이스- 큰 단위의 컴포넌트 내에 작은 단위 컴포넌트 파일을 중첩 생성 (파일명: 파스칼 케이스)
2026.03.08 – 2026.04.17 (약 6주)
main ──────────────────────────────────────────▶ (프로덕션 배포)
└── develop ────────────────────────────────▶ (통합 개발 브랜치)
├── feature/브랜치 ──▶ merge ──▶ develop
└── hotfix/브랜치 ──▶ merge ──▶ develop & main
| 브랜치 | 용도 |
|---|---|
main |
실제 서비스에 배포되는 프로덕션 코드 |
develop |
개발 중인 최신 기능이 통합되는 브랜치 |
feature |
새로운 기능 개발 (develop에서 파생, 완료 후 develop으로 PR) |
hotfix |
운영 중인 긴급 버그 수정 (main에서 파생, 수정 후 main & develop에 병합) |
release브랜치는 현 단계에서는 미사용
# format
#{이슈번호}-{기능종류}-{작업설명}
# example
#1-feat-login
#23-feat-ui
#25-chore-dependency| 접두사 | 의미 |
|---|---|
feat/ |
새로운 기능 추가 |
fix/ |
버그 수정 |
refactor/ |
코드 리팩토링 |
chore/ |
빌드 관련 수정, 패키지 매니저 설정 등 |
test/ |
테스트 코드 추가/수정 |
docs/ |
문서 수정 |
improvement/ |
기존 기능 개선 |
config/ |
환경 설정 |
<타입>(<범위>): <제목> ← 40자 이내
<본문> ← 선택 사항, 72자 이내 줄 바꿈
Resolves: #<이슈번호>
See also: None
| 타입 | 의미 |
|---|---|
feat |
새로운 기능 추가 |
fix |
버그 수정 |
docs |
문서 수정 |
style |
코드 포맷팅, 코드 변경 없는 경우 |
refactor |
코드 리팩토링 |
test |
테스트 코드 추가/수정 |
chore |
빌드 관련, 패키지 매니저 설정 등 |
- Refresh Token Rotation(RTR) 환경의 Race Condition
- 선언적 아키텍처 도입 과정에서 발생한 SSR 충돌과 렌더링 블로킹 해결
- 쿼리스트링 갱신 성능 개선 과정에서 발생한 렌더링 누락과 Request 불일치 해결
- Sentry Webhook Payload 구조 한계로 인한 Issue 집계 데이터 누락 해결
- 주요 사용자 흐름을 안정적으로 검증할 수 있도록 테스트 코드 범위 확대 예정
- 키보드 탐색, 스크린리더 대응 등 접근성 보완 예정
# 1. 저장소 클론
git clone https://github.com/Re-bootWorks/Reboot.git
# 2. 패키지 설치
pnpm install
# 3. 개발 서버 실행
pnpm dev
# 4. 브라우저 접속
http://localhost:3000환경 변수 관련 문의: rolarola0315@gmail.com









