- 📖 프로젝트 소개
- 🌟 서비스 소개
- 🚀 배포 링크
- 📅 개발 기간
- 👩💻 개발자 소개 및 역할
- 🔍 둘러보기
- 💻 개발환경
- 🔧 기술스택
- 🗂 System Structure
- 🧩 ERD
- 📂 프로젝트 파일 구조
- 🚦 How to Start
- ✨ 주요기능
요즘 사회에서는 문해력 저하가 큰 이슈로 떠오르고 있습니다.
‘심심한 사과’, ‘모집인원 0명’과 같은 사례들이 대표적이며, 이는 자극적인 숏폼 콘텐츠의 소비 증가와 독서 부족에서 비롯된 문제입니다.
독서의 중요성은 누구나 알지만, 꾸준한 독서 습관을 형성하기란 쉽지 않습니다. 그 이유는 독서가 즉각적인 보상을 제공하지 않아 동기 부여가 부족하기 때문입니다. 성취감과 가치를 바로 체감하기 어려운 독서는 현대인들에게 점점 멀어지고 있습니다.
그러나 이런 문제를 해결할 새로운 트렌드가 떠오르고 있습니다.
바로 텍스트 힙(Text Hip) 입니다.
텍스트 힙은 글자 자체를 즐기고, 책을 마치 유행 아이템처럼 소비하는 새로운 문화입니다. 디지털 이미지와 영상이 주도하는 시대 속에서, 책이나 노트로 글을 읽고 쓰는 경험은 차별화된 멋을 부여하며 힙한 활동으로 자리 잡았습니다.
저희 Rebit는 이러한 텍스트 힙 문화를 기반으로, 독서의 진입 장벽을 낮추고 독서를 장려하여 다음과 같은 목표를 추구합니다:
- 문해력 저하 문제 해결
- 독서 습관 형성 지원
- 독서의 사회적 가치를 재발견
Rebit는 젊은 세대들의 일상 속에 독서를 자연스럽게 녹여내며, 독서가 ‘힙’하고 매력적인 활동으로 자리 잡을 수 있도록 돕습니다.
Rebit를 통해 당신의 독서 여정을 새롭게 시작해보세요.
읽는 즐거움, 공유하는 재미, 그리고 성장의 가치를 경험할 수 있습니다.
Rebit로 힙하게 독서 라이프를 즐겨보세요!
- 📚 피드로 독서의 감각적인 공유 시작!
- 내 인생책을 피드로 올려, 내가 사랑하는 책을 모두와 나눠보세요!
- 스토리를 작성해, 당신만의 독서 일상을 힙하게 공유하세요!
- 메거진으로 좋아하는 연예인의 독서 루틴을 엿보는 재미까지!
- 🏆 챌린지로 독서의 즐거움 두 배로!
- 함께하는 독서 챌린지로 더 힙하고 특별한 독서 경험을 만들어보세요!
- 챌린지 성공 시 주어지는 보상으로 성취감과 즐거움까지 한 번에!
- 📖 나만의 독서 일기로 특별한 추억을 기록!
- 독서 일기를 통해 책과 함께한 나만의 소중한 순간들을 간직하세요!
- 📕 책 정보도 놓치지 말자!
- 궁금한 책의 상세 정보를 한눈에 확인하세요!
- 다른 Rebit 사용자들의 서평과 한줄평을 통해 책에 대한 다양한 시각을 만나보세요!
- 해당 책이 마음에 든다면 온라인 서점으로 이동해 소장 해보세요!
- 🔖 위시리스트로 독서 계획까지 완벽하게!
- 찜한 책들을 한곳에 모아두고 관리하세요!
- 내가 참여 중인 챌린지들을 한눈에 확인하며 독서 목표를 실현해보세요!
2024.09.16 ~ 2024.11.15
Frontend
![]() |
![]() |
|---|---|
| 곽정원 | 이은진 |
| 프론트 배포, 랜딩페이지, 피드, 마이페이지 | 소셜 로그인, 챌린지, 책 검색, 독서 일기 |
Backend
![]() |
![]() |
![]() |
![]() |
|---|---|---|---|
| 강명덕 | 안원모 | 임강범 | 조설빈 |
| 챌린지, CI/CD | 책, 알라딘 API | 피드, S3 | 소셜 로그인, 위시리스트, 독서일기 |
- API 문서: Swagger
- Frontend: React 18.3.1
- Backend: Java 21, JDK 21, Spring Boot 3.3.3
- 버전 및 이슈 관리 : Github, Guthub Issues, Github Project, Github Milestone
- 협업 툴 : Discord, Notion
- 디자인 : Figma (디자인 링크)
- 커밋 컨벤션 : Notion
- git 작업 단위 : Notion
Frontend
Backend
FE 파일 트리
📦
.eslintignore
├─ .eslintrc
├─ .github
│ ├─ ISSUE_TEMPLATE
│ │ ├─ 🐞-bug.md
│ │ └─ 🛠️-feature.md
│ ├─ pull_request_template.md
│ └─ workflows
│ ├─ cd.yml
│ └─ ci.yml
.gitignore
.prettierrc
.storybook
│ ├─ main.ts
preview.ts
├─ README.md
├─ index.html
package-lock.json
package.json
src
│ ├─ App.tsx
│ ├─ api
│ │ └─ instance
│ │ └─ index.ts
│ ├─ assets
│ │ ├─ Github.svg
│ │ ├─ Instagram.svg
│ │ ├─ Main
│ │ │ ├─ Challenge.svg
│ │ │ ├─ ChallengeSample.svg
│ │ │ ├─ Favorite.svg
│ │ │ └─ Story.svg
│ │ ├─ Mypage
│ │ │ └─ point.svg
│ │ ├─ Rebit.svg
│ │ ├─ Rebit_Logo.svg
│ │ ├─ defaultImage.png
│ │ └─ kakao_login.png
│ ├─ components
│ │ ├─ common
│ │ │ ├─ Avatar
│ │ │ │ └─ index.tsx
│ │ │ ├─ Button
│ │ │ │ └─ index.tsx
│ │ │ ├─ Grid
│ │ │ │ ├─ index.stories.tsx
│ │ │ │ └─ index.tsx
│ │ │ ├─ Header
│ │ │ │ └─ index.tsx
│ │ │ ├─ Image
│ │ │ │ ├─ index.stories.tsx
│ │ │ │ └─ index.tsx
│ │ │ ├─ Modal
│ │ │ │ └─ index.tsx
│ │ │ ├─ Sidebar
│ │ │ │ └─ index.tsx
│ │ │ ├─ Spinner
│ │ │ │ └─ index.tsx
│ │ │ ├─ layouts
│ │ │ │ └─ Container
│ │ │ │ └─ index.tsx
│ │ │ └─ overlay
│ │ │ └─ index.tsx
│ │ └─ feature
│ │ ├─ bookDiary
│ │ │ └─ DiaryCalender
│ │ │ └─ index.tsx
│ │ ├─ booksearch
│ │ │ ├─ BookCard
│ │ │ │ └─ index.tsx
│ │ │ ├─ Books
│ │ │ │ └─ index.tsx
│ │ │ └─ SearchBox
│ │ │ └─ index.tsx
│ │ ├─ cards
│ │ │ └─ WishCards
│ │ │ └─ index.tsx
│ │ ├─ challegeDetail
│ │ │ ├─ Intro
│ │ │ │ └─ index.tsx
│ │ │ ├─ Section
│ │ │ │ ├─ DetailCard
│ │ │ │ │ └─ index.tsx
│ │ │ │ ├─ DetailItems
│ │ │ │ │ └─ index.tsx
│ │ │ │ ├─ IntroContents
│ │ │ │ │ └─ index.tsx
│ │ │ │ └─ Navbar
│ │ │ │ └─ index.tsx
│ │ │ └─ Verification
│ │ │ └─ index.tsx
│ │ ├─ challenge
│ │ │ ├─ post
│ │ │ │ └─ Card
│ │ │ │ └─ index.tsx
│ │ │ └─ section
│ │ │ ├─ ChallengeForm
│ │ │ │ └─ index.tsx
│ │ │ ├─ ChallengeItems
│ │ │ │ └─ index.tsx
│ │ │ ├─ NavBar
│ │ │ │ └─ index.tsx
│ │ │ └─ WriteButton
│ │ │ └─ index.tsx
│ │ ├─ feed
│ │ │ ├─ post
│ │ │ │ └─ Card
│ │ │ │ └─ index.tsx
│ │ │ └─ section
│ │ │ ├─ FeedItems
│ │ │ │ └─ index.tsx
│ │ │ ├─ Navbar
│ │ │ │ └─ index.tsx
│ │ │ ├─ WriteButton
│ │ │ │ └─ index.tsx
│ │ │ └─ contentDetail
│ │ │ └─ StoryDetail
│ │ │ └─ index.tsx
│ │ ├─ home
│ │ │ ├─ Card
│ │ │ │ └─ index.tsx
│ │ │ ├─ Challenge
│ │ │ │ └─ index.tsx
│ │ │ ├─ Favorite
│ │ │ │ └─ index.tsx
│ │ │ ├─ Footer
│ │ │ │ └─ index.tsx
│ │ │ ├─ Header
│ │ │ │ └─ index.tsx
│ │ │ ├─ Section
│ │ │ │ └─ Landing-items
│ │ │ │ └─ index.tsx
│ │ │ ├─ Story
│ │ │ │ └─ index.tsx
│ │ │ └─ Welcome
│ │ │ └─ index.tsx
│ │ ├─ images
│ │ │ └─ UploadImage
│ │ │ └─ index.tsx
│ │ ├─ layouts
│ │ │ └─ header.tsx
│ │ ├─ login
│ │ │ └─ LoginButton
│ │ │ └─ index.tsx
│ │ ├─ modals
│ │ │ ├─ bookdiary
│ │ │ │ ├─ ContentDetail
│ │ │ │ │ └─ index.tsx
│ │ │ │ ├─ EditBookDiary
│ │ │ │ │ └─ index.tsx
│ │ │ │ └─ PostDiary
│ │ │ │ └─ index.tsx
│ │ │ ├─ challenges
│ │ │ │ └─ PostChallenge
│ │ │ │ └─ index.tsx
│ │ │ ├─ favbooks
│ │ │ │ ├─ ContentDetail
│ │ │ │ │ └─ index.tsx
│ │ │ │ ├─ EditFavBook
│ │ │ │ │ └─ index.tsx
│ │ │ │ ├─ PostFavBook
│ │ │ │ │ └─ index.tsx
│ │ │ │ └─ UploadBook
│ │ │ │ └─ index.tsx
│ │ │ ├─ magazine
│ │ │ │ └─ ContentDetail
│ │ │ │ └─ index.tsx
│ │ │ ├─ stories
│ │ │ │ ├─ ContentDetail
│ │ │ │ │ └─ index.tsx
│ │ │ │ ├─ EditStory
│ │ │ │ │ └─ index.tsx
│ │ │ │ └─ PostStory
│ │ │ │ └─ index.tsx
│ │ │ ├─ users
│ │ │ │ └─ EditProfile
│ │ │ │ └─ index.tsx
│ │ │ └─ verification
│ │ │ ├─ ContentDetail
│ │ │ │ └─ index.tsx
│ │ │ └─ PostVerification
│ │ │ └─ index.tsx
│ │ └─ mypage
│ │ └─ section
│ │ ├─ ContentSection
│ │ │ └─ index.tsx
│ │ ├─ EditProfileForm
│ │ │ └─ index.tsx
│ │ ├─ Navber
│ │ │ └─ index.tsx
│ │ ├─ PostedChallanges
│ │ │ └─ index.tsx
│ │ ├─ PostedFeeds
│ │ │ └─ index.tsx
│ │ ├─ UserInfo
│ │ │ └─ index.tsx
│ │ └─ UserWishes
│ │ └─ index.tsx
│ ├─ index.css
│ ├─ index.tsx
│ ├─ pages
│ │ ├─ BookDetail
│ │ │ └─ index.tsx
│ │ ├─ BookDiary
│ │ │ └─ index.tsx
│ │ ├─ BookSearch
│ │ │ └─ index.tsx
│ │ ├─ Challenge
│ │ │ └─ index.tsx
│ │ ├─ ChallengeDetail
│ │ │ └─ index.tsx
│ │ ├─ Feed
│ │ │ └─ index.tsx
│ │ ├─ Home
│ │ │ └─ index.tsx
│ │ ├─ Login
│ │ │ └─ index.tsx
│ │ ├─ MyPage
│ │ │ └─ index.tsx
│ │ └─ landings
│ │ └─ BookDetailLanding
│ │ └─ index.tsx
│ ├─ provider
│ │ └─ Auth
│ │ └─ index.tsx
│ ├─ routes
│ │ ├─ PrivateRoute
│ │ │ └─ index.tsx
│ │ ├─ index.tsx
│ │ └─ path.ts
│ ├─ setupTest.ts
│ ├─ store
│ │ ├─ bookSlice.ts
│ │ └─ store.ts
│ ├─ tests
│ │ └─ App.test.tsx
│ ├─ types
│ │ ├─ Custom
│ │ │ └─ svg.d.ts
│ │ ├─ index.d.ts
│ │ └─ index.tsx
│ └─ util
│ └─ hooks
│ ├─ uesLandingPage
│ │ └─ index.tsx
│ ├─ useChallengeFilter
│ │ └─ index.tsx
│ ├─ useFilter
│ │ └─ index.tsx
│ ├─ useLiked
│ │ └─ index.tsx
│ ├─ useStoreImage
│ │ └─ index.tsx
│ ├─ useVerificationFilter
│ │ └─ index.tsx
│ └─ useWishlist
│ └─ index.tsx
├─ tsconfig.json
├─ vercel.json
└─ vite.config.ts
BE 파일 트리
📦
├─ .github
│ ├─ ISSUE_TEMPLATE
│ │ ├─ BUG_REPORT.md
│ │ ├─ ETC_ISSUE.md
│ │ └─ FEATURE_REQUEST.md
│ ├─ PULL_REQUEST_TEMPLATE.md
│ └─ workflows
│ └─ dev-deploy.yml
├─ .gitignore
├─ Dockerfile
├─ README.md
├─ build.gradle
├─ docker-compose.yml
├─ gradle
│ └─ wrapper
│ ├─ gradle-wrapper.jar
│ └─ gradle-wrapper.properties
├─ gradlew
├─ gradlew.bat
├─ settings.gradle
└─ src
├─ main
│ ├─ java
│ │ └─ kakao
│ │ └─ rebit
│ │ ├─ RebitApplication.java
│ │ ├─ auth
│ │ │ ├─ controller
│ │ │ │ └─ KakaoAuthController.java
│ │ │ ├─ dto
│ │ │ │ ├─ KakaoToken.java
│ │ │ │ ├─ KakaoUserInfo.java
│ │ │ │ └─ LoginResponse.java
│ │ │ ├─ event
│ │ │ │ ├─ ProfileImageUploadEventHandler.java
│ │ │ │ └─ RegisteredEvent.java
│ │ │ ├─ exception
│ │ │ │ ├─ AuthErrorCode.java
│ │ │ │ └─ UserInfoNotFoundException.java
│ │ │ ├─ jwt
│ │ │ │ ├─ AuthTokenParam.java
│ │ │ │ ├─ JwtArgumentResolver.java
│ │ │ │ ├─ JwtInterceptor.java
│ │ │ │ ├─ JwtTokenProvider.java
│ │ │ │ ├─ TokenBlacklistRepository.java
│ │ │ │ └─ exception
│ │ │ │ ├─ AccessDeniedException.java
│ │ │ │ ├─ ExpiredTokenException.java
│ │ │ │ ├─ InvalidTokenException.java
│ │ │ │ ├─ JwtErrorCode.java
│ │ │ │ ├─ MissingTokenException.java
│ │ │ │ ├─ SignatureValidationFailedException.java
│ │ │ │ └─ UnsupportedTokenException.java
│ │ │ ├─ service
│ │ │ │ ├─ KakaoApiClient.java
│ │ │ │ └─ KakaoAuthService.java
│ │ │ └─ token
│ │ │ ├─ AuthToken.java
│ │ │ └─ AuthTokenGenerator.java
│ │ ├─ book
│ │ │ ├─ controller
│ │ │ │ └─ BookController.java
│ │ │ ├─ dto
│ │ │ │ ├─ AladinApiResponseListResponse.java
│ │ │ │ ├─ AladinApiResponseResponse.java
│ │ │ │ ├─ BookDetailResponse.java
│ │ │ │ ├─ BookResponse.java
│ │ │ │ └─ BriefReviewResponse.java
│ │ │ ├─ entity
│ │ │ │ └─ Book.java
│ │ │ ├─ exception
│ │ │ │ ├─ api
│ │ │ │ │ ├─ ApiErrorCode.java
│ │ │ │ │ └─ ApiErrorException.java
│ │ │ │ └─ book
│ │ │ │ ├─ BookErrorCode.java
│ │ │ │ ├─ BookNotFoundException.java
│ │ │ │ └─ InvalidIsbnException.java
│ │ │ ├─ mapper
│ │ │ │ └─ BookMapper.java
│ │ │ ├─ repository
│ │ │ │ └─ BookRepository.java
│ │ │ └─ service
│ │ │ ├─ AladinApiService.java
│ │ │ └─ BookService.java
│ │ ├─ challenge
│ │ │ ├─ controller
│ │ │ │ ├─ ChallengeController.java
│ │ │ │ ├─ ChallengeParticipationController.java
│ │ │ │ └─ ChallengeVerificationController.java
│ │ │ ├─ dto
│ │ │ │ ├─ AuthorResponse.java
│ │ │ │ ├─ ChallengeParticipationMemberResponse.java
│ │ │ │ ├─ ChallengeParticipationRequest.java
│ │ │ │ ├─ ChallengeRequest.java
│ │ │ │ ├─ ChallengeResponse.java
│ │ │ │ ├─ ChallengeVerificationRequest.java
│ │ │ │ ├─ ChallengeVerificationResponse.java
│ │ │ │ └─ CreatorResponse.java
│ │ │ ├─ entity
│ │ │ │ ├─ Challenge.java
│ │ │ │ ├─ ChallengeParticipation.java
│ │ │ │ ├─ ChallengeType.java
│ │ │ │ ├─ ChallengeVerification.java
│ │ │ │ ├─ HeadcountLimit.java
│ │ │ │ └─ Period.java
│ │ │ ├─ exception
│ │ │ │ ├─ challenge
│ │ │ │ │ ├─ ChallengeErrorCode.java
│ │ │ │ │ ├─ ChallengeNotFoundException.java
│ │ │ │ │ ├─ DeleteNotAllowedException.java
│ │ │ │ │ ├─ DeleteNotAuthorizedException.java
│ │ │ │ │ ├─ EntryFeeNotEnoughException.java
│ │ │ │ │ ├─ FullException.java
│ │ │ │ │ ├─ InvalidChallengePeriodException.java
│ │ │ │ │ ├─ InvalidChallengeStartDateException.java
│ │ │ │ │ ├─ InvalidHeadcountRangeException.java
│ │ │ │ │ ├─ InvalidRecruitmentPeriodException.java
│ │ │ │ │ └─ NotRecruitingException.java
│ │ │ │ ├─ participation
│ │ │ │ │ ├─ ParticipationAlreadyExistsException.java
│ │ │ │ │ ├─ ParticipationErrorCode.java
│ │ │ │ │ ├─ ParticipationNotFoundException.java
│ │ │ │ │ └─ ParticipationNotParticipantException.java
│ │ │ │ └─ verification
│ │ │ │ ├─ DeleteNotAuthorizedException.java
│ │ │ │ ├─ VerificationErrorCode.java
│ │ │ │ ├─ VerificationNotFoundException.java
│ │ │ │ ├─ VerifyChallengeAlreadyDoneTodayException.java
│ │ │ │ └─ VerifyChallengeNotOngoingException.java
│ │ │ ├─ repository
│ │ │ │ ├─ ChallengeParticipationRepository.java
│ │ │ │ ├─ ChallengeRepository.java
│ │ │ │ └─ ChallengeVerificationRepository.java
│ │ │ ├─ scheduler
│ │ │ │ └─ ChallengeRewardScheduler.java
│ │ │ └─ service
│ │ │ ├─ ChallengeParticipationService.java
│ │ │ ├─ ChallengeRewardService.java
│ │ │ ├─ ChallengeService.java
│ │ │ └─ ChallengeVerificationService.java
│ │ ├─ common
│ │ │ ├─ annotation
│ │ │ │ └─ AllowAnonymous.java
│ │ │ ├─ config
│ │ │ │ ├─ JpaAuditingConfig.java
│ │ │ │ ├─ SwaggerConfig.java
│ │ │ │ └─ WebConfig.java
│ │ │ ├─ domain
│ │ │ │ ├─ ImageKeyAccessor.java
│ │ │ │ └─ ImageKeyModifier.java
│ │ │ ├─ exception
│ │ │ │ ├─ BusinessException.java
│ │ │ │ ├─ CommonErrorCode.java
│ │ │ │ ├─ ErrorCode.java
│ │ │ │ ├─ ErrorResponse.java
│ │ │ │ ├─ GlobalExceptionHandler.java
│ │ │ │ ├─ ImageDownloadErrorException.java
│ │ │ │ ├─ ImageErrorCode.java
│ │ │ │ └─ ValidationError.java
│ │ │ └─ persistence
│ │ │ └─ BaseEntity.java
│ │ ├─ diary
│ │ │ ├─ controller
│ │ │ │ └─ DiaryController.java
│ │ │ ├─ dto
│ │ │ │ ├─ DiaryBookResponse.java
│ │ │ │ ├─ DiaryRequest.java
│ │ │ │ └─ DiaryResponse.java
│ │ │ ├─ entity
│ │ │ │ └─ Diary.java
│ │ │ ├─ exception
│ │ │ │ ├─ DiaryErrorCode.java
│ │ │ │ └─ DiaryNotFoundException.java
│ │ │ ├─ repository
│ │ │ │ └─ DiaryRepository.java
│ │ │ └─ service
│ │ │ └─ DiaryService.java
│ │ ├─ feed
│ │ │ ├─ controller
│ │ │ │ ├─ FavoriteBookController.java
│ │ │ │ ├─ FeedController.java
│ │ │ │ ├─ MagazineController.java
│ │ │ │ └─ StoryController.java
│ │ │ ├─ dto
│ │ │ │ ├─ request
│ │ │ │ │ ├─ create
│ │ │ │ │ │ ├─ CreateFavoriteBookRequest.java
│ │ │ │ │ │ ├─ CreateFeedRequest.java
│ │ │ │ │ │ ├─ CreateMagazineRequest.java
│ │ │ │ │ │ └─ CreateStoryRequest.java
│ │ │ │ │ └─ update
│ │ │ │ │ ├─ UpdateFavoriteBookRequest.java
│ │ │ │ │ ├─ UpdateMagazineRequest.java
│ │ │ │ │ └─ UpdateStoryRequest.java
│ │ │ │ └─ response
│ │ │ │ ├─ FavoriteBookResponse.java
│ │ │ │ ├─ FeedAuthorResponse.java
│ │ │ │ ├─ FeedBookResponse.java
│ │ │ │ ├─ FeedResponse.java
│ │ │ │ ├─ LikesMemberResponse.java
│ │ │ │ ├─ MagazineResponse.java
│ │ │ │ └─ StoryResponse.java
│ │ │ ├─ entity
│ │ │ │ ├─ FavoriteBook.java
│ │ │ │ ├─ Feed.java
│ │ │ │ ├─ Likes.java
│ │ │ │ ├─ Magazine.java
│ │ │ │ └─ Story.java
│ │ │ ├─ exception
│ │ │ │ ├─ feed
│ │ │ │ │ ├─ DeleteNotAuthorizedException.java
│ │ │ │ │ ├─ FavoriteBookRequiredBookException.java
│ │ │ │ │ ├─ FeedErrorCode.java
│ │ │ │ │ ├─ FeedNotFoundException.java
│ │ │ │ │ ├─ InvalidFeedFormatException.java
│ │ │ │ │ └─ UpdateNotAuthorizedException.java
│ │ │ │ └─ likes
│ │ │ │ ├─ FindNotAuthorizedException.java
│ │ │ │ ├─ LikesAlreadyPressedException.java
│ │ │ │ ├─ LikesErrorCode.java
│ │ │ │ └─ LikesNotPressedException.java
│ │ │ ├─ mapper
│ │ │ │ └─ FeedMapper.java
│ │ │ ├─ repository
│ │ │ │ ├─ FavoriteBookRepository.java
│ │ │ │ ├─ FeedRepository.java
│ │ │ │ ├─ LikesRepository.java
│ │ │ │ ├─ MagazineRepository.java
│ │ │ │ └─ StoryRepository.java
│ │ │ └─ service
│ │ │ ├─ FavoriteBookService.java
│ │ │ ├─ FeedService.java
│ │ │ ├─ LikesService.java
│ │ │ ├─ MagazineService.java
│ │ │ └─ StoryService.java
│ │ ├─ member
│ │ │ ├─ annotation
│ │ │ │ ├─ MemberInfo.java
│ │ │ │ └─ MemberInfoIfPresent.java
│ │ │ ├─ controller
│ │ │ │ └─ MemberController.java
│ │ │ ├─ dto
│ │ │ │ ├─ AdminMemberRequest.java
│ │ │ │ ├─ ChargePointRequest.java
│ │ │ │ ├─ MemberActivitySummaryResponse.java
│ │ │ │ ├─ MemberProfileResponse.java
│ │ │ │ ├─ MemberRequest.java
│ │ │ │ └─ MemberResponse.java
│ │ │ ├─ entity
│ │ │ │ ├─ Member.java
│ │ │ │ └─ Role.java
│ │ │ ├─ exception
│ │ │ │ ├─ MemberErrorCode.java
│ │ │ │ ├─ MemberNotFoundException.java
│ │ │ │ └─ NotEnoughPointsException.java
│ │ │ ├─ mapper
│ │ │ │ └─ MemberMapper.java
│ │ │ ├─ repository
│ │ │ │ └─ MemberRepository.java
│ │ │ ├─ resolver
│ │ │ │ ├─ MemberInfoArgumentResolver.java
│ │ │ │ └─ OptionalMemberResolver.java
│ │ │ └─ service
│ │ │ └─ MemberService.java
│ │ ├─ s3
│ │ │ ├─ config
│ │ │ │ └─ S3ClientConfig.java
│ │ │ ├─ controller
│ │ │ │ └─ S3Controller.java
│ │ │ ├─ domain
│ │ │ │ └─ S3Type.java
│ │ │ ├─ dto
│ │ │ │ ├─ DownloadImageInfo.java
│ │ │ │ ├─ S3DownloadUrlResponse.java
│ │ │ │ ├─ S3UploadFileInfo.java
│ │ │ │ ├─ S3UploadKeyRequest.java
│ │ │ │ └─ S3UploadUrlResponse.java
│ │ │ ├─ exception
│ │ │ │ ├─ S3DeleteClientErrorException.java
│ │ │ │ ├─ S3DeleteErrorException.java
│ │ │ │ ├─ S3DeleteSdkErrorException.java
│ │ │ │ ├─ S3DeleteUnknownErrorException.java
│ │ │ │ ├─ S3DownloadClientErrorException.java
│ │ │ │ ├─ S3DownloadErrorException.java
│ │ │ │ ├─ S3DownloadSdkErrorException.java
│ │ │ │ ├─ S3DownloadUnknownErrorException.java
│ │ │ │ ├─ S3ErrorCode.java
│ │ │ │ ├─ S3NotAllowedFileFormatException.java
│ │ │ │ ├─ S3UploadClientErrorException.java
│ │ │ │ ├─ S3UploadErrorException.java
│ │ │ │ ├─ S3UploadSdkErrorException.java
│ │ │ │ └─ S3UploadUnknownErrorException.java
│ │ │ └─ service
│ │ │ └─ S3Service.java
│ │ ├─ utils
│ │ │ ├─ file
│ │ │ │ └─ FileUtil.java
│ │ │ ├─ image
│ │ │ │ └─ ImageDownloader.java
│ │ │ └─ p6spy
│ │ │ ├─ P6SpyConfig.java
│ │ │ ├─ P6SpyEventListener.java
│ │ │ └─ P6SpyFormatter.java
│ │ └─ wishlist
│ │ ├─ controller
│ │ │ └─ WishlistController.java
│ │ ├─ dto
│ │ │ └─ response
│ │ │ ├─ BookWishlistResponse.java
│ │ │ └─ ChallengeWishlistResponse.java
│ │ ├─ entity
│ │ │ ├─ BookWishlist.java
│ │ │ ├─ ChallengeWishlist.java
│ │ │ └─ Wishlist.java
│ │ ├─ exception
│ │ │ ├─ AlreadyInWishlistException.java
│ │ │ ├─ BookWishlistNotFoundException.java
│ │ │ ├─ ChallengeWishlistNotFoundException.java
│ │ │ └─ WishlistErrorCode.java
│ │ ├─ repository
│ │ │ ├─ BookWishlistRepository.java
│ │ │ ├─ ChallengeWishlistRepository.java
│ │ │ └─ WishlistRepository.java
│ │ └─ service
│ │ ├─ BookWishlistService.java
│ │ └─ ChallengeWishlistService.java
│ └─ resources
│ ├─ application.yml
│ └─ templates
│ └─ loginForm.html
├─ test
│ └─ java
│ └─ kakao
│ └─ rebit
│ ├─ RebitApplicationTests.java
│ ├─ auth
│ │ ├─ fixture
│ │ │ ├─ TestKakaoAuthService.java
│ │ │ └─ TestS3Service.java
│ │ ├─ jwt
│ │ │ └─ JwtTokenProviderTest.java
│ │ ├─ service
│ │ │ └─ KakaoAuthServiceTest.java
│ │ └─ util
│ │ ├─ AuthApiTestClient.java
│ │ ├─ ChallengeApiTestClient.java
│ │ ├─ DiaryApiTestClient.java
│ │ ├─ FeedApiTestClient.java
│ │ └─ MemberApiTestClient.java
│ ├─ book
│ │ └─ service
│ │ └─ BookServiceTest.java
│ ├─ challenge
│ │ ├─ e2e
│ │ │ └─ ChallengeE2ETest.java
│ │ ├─ entity
│ │ │ └─ ChallengeParticipationTest.java
│ │ └─ service
│ │ ├─ ChallengeParticipationServiceTest.java
│ │ └─ ChallengeVerificationServiceTest.java
│ ├─ common
│ │ ├─ PageTemplate.java
│ │ └─ annotation
│ │ └─ RepositoryTest.java
│ ├─ config
│ │ └─ TestConfig.java
│ ├─ diary
│ │ ├─ e2e
│ │ │ └─ DiaryE2ETest.java
│ │ ├─ entity
│ │ │ └─ DiaryTest.java
│ │ └─ service
│ │ └─ DiaryServiceTest.java
│ └─ feed
│ ├─ e2e
│ │ ├─ FavoriteBookE2ETest.java
│ │ ├─ FeedE2ETest.java
│ │ ├─ MagazineE2ETest.java
│ │ └─ StoryE2ETest.java
│ ├─ entity
│ │ ├─ CommonFeedTest.java
│ │ ├─ FavoriteBookTest.java
│ │ ├─ MagazineTest.java
│ │ └─ StoryTest.java
│ └─ service
│ ├─ FavoriteBookServiceTest.java
│ ├─ FeedServiceTest.java
│ ├─ MagazineServiceTest.java
│ └─ StoryServiceTest.java
└─ testFixtures
└─ java
└─ kakao
└─ rebit
├─ book
│ └─ fixture
│ ├─ BookFixture.java
│ └─ values
│ └─ BookDefaultValues.java
├─ challenge
│ └─ fixture
│ ├─ ChallengeFixture.java
│ ├─ ChallengeParticipationFixture.java
│ ├─ ChallengeVerificationFixture.java
│ ├─ TestPeriod.java
│ └─ values
│ ├─ ChallengeDefaultValues.java
│ └─ ChallengeVerificationDefaultValues.java
├─ diary
│ └─ fixture
│ ├─ DiaryFixture.java
│ └─ values
│ └─ DiaryDefaultValues.java
├─ feed
│ └─ fixture
│ ├─ FeedFixture.java
│ └─ values
│ ├─ FavoriteBookDefaultValues.java
│ ├─ MagazineDefaultValues.java
│ └─ StoryDefaultValues.java
└─ member
└─ fixture
├─ MemberFixture.java
└─ values
└─ MemberDefaultValues.java
테스트 계정
id : coolkidstest0@gmail.com
pw : coolkids123123
FE
git clone https://github.com/kakao-tech-campus-2nd-step3/Team15_FE.git
cd Team15_FE/
// .env
VITE_KAKAO_JS_KEY='a9751f8a7d38eac0f31ed5122e5adb18'
VITE_KAKAO_REDIRECT='http://localhost:3000/'
VITE_BASE_URL='https://rebit.43.203.210.66.sslip.io'
BE
git clone https://github.com/kakao-tech-campus-2nd-step3/Team15_BE.git
cd Team15_BE/
// .env
PROFILE=dev
SPRING_PORT=8080
# MySQL
MYSQL_HOST=mysql
MYSQL_PORT=3306
MYSQL_DATABASE=rebit
MYSQL_USERNAME=root
MYSQL_PASSWORD=1234
# Redis
REDIS_HOST=redis
REDIS_PORT=6379
# OAuth (Kakao)
OAUTH_KAKAO_CLIENT_ID=test-client-id
OAUTH_KAKAO_AUTH_URL=kakao-auth-url
OAUTH_KAKAO_API_URL=kakao-api-url
OAUTH_KAKAO_REDIRECT_URI=kakao-redirect-url
OAUTH_KAKAO_LOGOUT_URL_TEMPLATE=kakao-logout-url-template
# JWT
JWT_SECRET_KEY=dGVzdC1zZWNyZXQta2V5LXRlc3Qtc2VjcmV0LWtleS10ZXN0LXNlY3JldC1rZXktdGVzdC1zZWNyZXQta2V5
# Aladin API
TTB_KEY=test-ttb-key
# AWS S3
S3_ACCESS_KEY=test-access-key
S3_SECRET_KEY=test-secret-key
S3_BUCKET_NAME=test-bucket
S3_REGION=ap-northeast-2
- 카카오톡 소셜 로그인을 활용한 손쉬운 로그인
- 회원 가입을 하지 않은 유저는 아래의 기능만 사용 가능합니다. (주로 조회만 가능)
- 메인 화면 및 랜딩 페이지 조회 - 작성된 피드 조회 - 챌린지 목록 조회 - 회원 가입을 한 유저는 아래의 기능을 추가로 사용할 수 있습니다.
피드 - 인생책 - 인생책 피드 상세보기 (서평 및 한줄평 조회) - 좋아요 기능 - 책 상세페이지 조회 - 온라인 서점으로 이동 - 위시리스트 추가 - 다른 Rebit 사용자들의 Best 서평 및 한줄평 조회 - 스토리 - 스토리 상세 조회 - 스토리 작성 - 좋아요 기능 - 스토리 수정 및 삭제 - 매거진 - 매거진 상세 조회 - 좋아요 기능 --- 챌린지 - 챌린지 상세 조회 - 챌린지 참여 - 챌린지 위시리스트 추가 - 챌린지 인증 - 챌린지 진행도 조회 --- 다이어리 - 독서 일기 작성 - 작성한 독서 일기 조회 --- 마이 페이지 - 프로필 편집 - 작성한 게시물 조회 - 위시리스트 조회 - 참여한 챌린지 조회 - 활동 수 조회 - 포인트 충전
- 피드 전체 조회 및 좋아요 기능
- 카테고리별 피드 생성 및 조회
- 인생책
- 피드 조회: 사용자가 '인생책'으로 등록한 책에 대한 피드를 조회할 수 있습니다. 다른 사용자들의 추천 책과 피드를 살펴보며 독서 추천을 받을 수 있습니다.
- 피드 생성: 사용자가 자신만의 인생책 피드를 생성할 수 있습니다. 책에 대한 짧은 리뷰나 추천 이유를 작성해 다른 사용자와 공유할 수 있습니다.
- 메거진
- 피드 조회: 메거진 콘텐츠를 통해 트렌디한 독서 관련 이미지와 정보를 제공합니다.
- 스토리
- 피드 조회: 사용자들이 작성한 스토리형 피드를 조회할 수 있습니다. 다양한 주제와 독서 경험을 담은 스토리로 관심사를 공유할 수 있습니다.
- 피드 생성: 사용자가 스토리 피드를 생성하여 자신만의 독서 경험과 이야기를 공유할 수 있습니다.
세부항목 모달 조회 및 게시물에 대한 좋아요 기능 제공
- ISBN, 책 제목 기반 검색
- 책 상세 정보 조회
- TOP 리뷰 보여주기
- 특정 책 한줄평 목록 조회
- 알라딘 구매처 링크로 이동
- ISBN, 책 제목 기반 손쉬운 검색 기능 제공
- 특정 책에 대한 한줄평 및 서평 조회 기능으로 타인과 생각을 공유
- 해당 책을 구매할 수 있는 온라인 서점으로 이동하여 손쉬운 구매
-
챌린지 조회
- 챌린지는 '모집 예정 챌린지', '모집 중인 챌린지', '진행 중인 챌린지'의 세 가지 상태로 구분되어 표시됩니다.
- 사용자는 각 상태에 따라 현재 모집 중인 챌린지와 진행 중인 챌린지를 손쉽게 확인할 수 있으며, 원하는 챌린지에 참여하거나 세부 정보를 조회할 수 있습니다.
-
챌린지 생성
-
챌린지 참여 (보상)
-
인증글 작성
- 챌린지에 참여한 사용자는 인증글을 작성하여 챌린지에 대한 참여를 증명합니다.
- 인증글은 텍스트나 이미지를 포함할 수 있으며, 이를 통해 다른 사용자와의 소통을 활성화할 수 있습니다.
-
인증 현황 확인
- 자신의 인증 현황을 쉽게 확인할 수 있으며, 캘린더 형식으로 인증 일자를 한눈에 볼 수 있습니다.
- 달성 정도를 시각화하여 유저에게 제공합니다.
- 독서 일기 조회
- 사용자가 작성한 독서 일기를 조회할 수 있습니다. 언제, 어떤 책을 읽었는지, 독서 중 느낀 점 등을 일지 형태로 관리하며 기록할 수 있습니다.
- 독서 일기 생성
- 자신의 독서 기록을 남길 수 있는 기능입니다. 읽은 책과 이에 대한 느낀 점을 기록함으로써 독서 습관을 형성하고 회고할 수 있습니다.
- 참여한 활동
- 사용자가 참여한 다양한 활동(챌린지, 피드 등)을 조회할 수 있습니다. 이를 통해 사용자 스스로의 독서 및 활동 내역을 쉽게 확인할 수 있습니다.
- 작성한 피드 조회
- 사용자가 작성한 피드를 모아 볼 수 있습니다. 자신이 공유한 콘텐츠를 쉽게 관리하고 필요한 경우 수정 또는 삭제할 수 있습니다.
- 위시리스트
- 사용자가 관심을 가진 책이나 챌린지를 위시리스트에 추가하고 관리할 수 있는 기능입니다. 이후에 보고 싶은 콘텐츠나 참여하고 싶은 활동을 미리 등록하여 관리할 수 있습니다.
- 포인트
- 서비스 내에서 얻은 포인트를 조회하고 관리할 수 있습니다. 포인트는 챌린지 보상을 통해 획득할 수 있으며, 포인트 추가 기능도 제공합니다.
- 내가 참여한 활동의 목록들을 한눈에 확인
- 위시리스트 목록 조회와 간편한 포인트 충전 기능 제공


















