Skip to content

prgrms-web-devcourse-final-project/WEB1_2_Mallangs_BE

Repository files navigation

이미지 설명

💡 서비스 소개

'말랑플레이스' 는 반려동물을 키우는 반려인들을 위한 위치 기반 커뮤니티 서비스입니다. 지도를 기반으로 한 직관적인 인터페이스를 통해 내 주변의 반려동물 관련 정보를 손쉽게 확인하고 공유할 수 있습니다. 특히 사용자들이 자유롭게 생성하는 '글타래' 기능을 통해 실시간으로 지역 정보를 공유하고, 이웃들과 소통할 수 있는 새로운 형태의 반려동물 커뮤니티를 제공합니다.

개발 기간

2024/11/15 ~ 2024/12/10

기능 목록

  • 글타래: 말랑맵에 표기된 마커들을 클릭하면 실종/구조/장소로 분류된 글타래, 사용자가 자유롭게 작성가능합니다.
  • 커뮤니티: 말랑플렝이스의 게시판, 사용자들이 자유롭게 소통하고 커뮤니티를 형성할 수 있습니다.
  • 자유로운 1:1 채팅 기능: 다른 사용자와 자유롭게 실시간으로 대화가능합니다.

기술 스택

Backend

Java 17 Spring Boot Spring Data JPA Spring Security JUnit5 JWT Gradle Socket.io Thymeleaf

DB / Infra

MySQL Redis Docker AWS

성능테스트

Grafana

문서/협업툴

Notion Slack IntelliJ IDEA Swagger Discord

구조

전체 시스템 구조 - 사용자

이미지 설명

전체 시스템 구조 - 관리자

이미지 설명

패키지 구조
📦 
├─ .gitattributes
├─ .github
│  ├─ ISSUE_TEMPLATE
│  │  └─ 📋-general-issue.md
│  ├─ PULL_REQUEST_TEMPLATE
│  └─ workflows
│     ├─ CICD.yml
│     └─ CICDdevelop.yml
├─ .gitignore
├─ README.md
├─ build.gradle
├─ gradle
│  └─ wrapper
│     ├─ gradle-wrapper.jar
│     └─ gradle-wrapper.properties
├─ gradlew
├─ gradlew.bat
├─ settings.gradle
├─ src
│  ├─ main
│  │  ├─ java
│  │  │  └─ com
│  │  │     └─ mallangs
│  │  │        ├─ MallangsApplication.java
│  │  │        ├─ domain
│  │  │        │  ├─ article
│  │  │        │  │  ├─ controller
│  │  │        │  │  │  ├─ ArticleController.java
│  │  │        │  │  │  └─ TourApiController.java
│  │  │        │  │  ├─ dto
│  │  │        │  │  │  ├─ request
│  │  │        │  │  │  │  ├─ ArticleCreateRequest.java
│  │  │        │  │  │  │  ├─ LostCreateRequest.java
│  │  │        │  │  │  │  ├─ MapBoundsRequest.java
│  │  │        │  │  │  │  ├─ PlaceCreateRequest.java
│  │  │        │  │  │  │  └─ RescueCreateRequest.java
│  │  │        │  │  │  └─ response
│  │  │        │  │  │     ├─ ArticlePageResponse.java
│  │  │        │  │  │     ├─ ArticleResponse.java
│  │  │        │  │  │     ├─ LostResponse.java
│  │  │        │  │  │     ├─ MapBoundsResponse.java
│  │  │        │  │  │     ├─ PlaceResponse.java
│  │  │        │  │  │     └─ RescueResponse.java
│  │  │        │  │  ├─ entity
│  │  │        │  │  │  ├─ Article.java
│  │  │        │  │  │  ├─ ArticleType.java
│  │  │        │  │  │  ├─ CaseStatus.java
│  │  │        │  │  │  ├─ LostArticle.java
│  │  │        │  │  │  ├─ MapVisibility.java
│  │  │        │  │  │  ├─ PlaceArticle.java
│  │  │        │  │  │  └─ RescueArticle.java
│  │  │        │  │  ├─ factory
│  │  │        │  │  │  ├─ ArticleFactory.java
│  │  │        │  │  │  ├─ ArticleFactoryManager.java
│  │  │        │  │  │  ├─ LostArticleFactory.java
│  │  │        │  │  │  ├─ PlaceArticleFactory.java
│  │  │        │  │  │  └─ RescueArticleFactory.java
│  │  │        │  │  ├─ repository
│  │  │        │  │  │  ├─ ArticleRepository.java
│  │  │        │  │  │  ├─ JdbcLocationRepository.java
│  │  │        │  │  │  ├─ LocationRepository.java
│  │  │        │  │  │  └─ PlaceArticleRepository.java
│  │  │        │  │  ├─ service
│  │  │        │  │  │  ├─ ArticleService.java
│  │  │        │  │  │  ├─ LocationService.java
│  │  │        │  │  │  └─ PlaceArticleCsvService.java
│  │  │        │  │  └─ validation
│  │  │        │  │     └─ ValidationGroups.java
│  │  │        │  ├─ board
│  │  │        │  │  ├─ controller
│  │  │        │  │  │  ├─ BoardController.java
│  │  │        │  │  │  └─ CategoryController.java
│  │  │        │  │  ├─ dto
│  │  │        │  │  │  ├─ request
│  │  │        │  │  │  │  ├─ AdminBoardStatusRequest.java
│  │  │        │  │  │  │  ├─ CategoryCreateRequest.java
│  │  │        │  │  │  │  ├─ CategoryUpdateRequest.java
│  │  │        │  │  │  │  ├─ CommunityCreateRequest.java
│  │  │        │  │  │  │  ├─ CommunityUpdateRequest.java
│  │  │        │  │  │  │  ├─ SightingCreateRequest.java
│  │  │        │  │  │  │  └─ SightingUpdateRequest.java
│  │  │        │  │  │  └─ response
│  │  │        │  │  │     ├─ AdminBoardResponse.java
│  │  │        │  │  │     ├─ AdminBoardsResponse.java
│  │  │        │  │  │     ├─ AdminCategoryResponse.java
│  │  │        │  │  │     ├─ BoardStatusCount.java
│  │  │        │  │  │     ├─ CategoryResponse.java
│  │  │        │  │  │     ├─ CommunityDetailResponse.java
│  │  │        │  │  │     ├─ CommunityListResponse.java
│  │  │        │  │  │     ├─ PageResponse.java
│  │  │        │  │  │     ├─ SightingDetailResponse.java
│  │  │        │  │  │     └─ SightingListResponse.java
│  │  │        │  │  ├─ entity
│  │  │        │  │  │  ├─ Board.java
│  │  │        │  │  │  ├─ BoardStatus.java
│  │  │        │  │  │  ├─ BoardType.java
│  │  │        │  │  │  ├─ Category.java
│  │  │        │  │  │  └─ CategoryStatus.java
│  │  │        │  │  ├─ repository
│  │  │        │  │  │  ├─ BoardRepository.java
│  │  │        │  │  │  └─ CategoryRepository.java
│  │  │        │  │  └─ service
│  │  │        │  │     ├─ BoardService.java
│  │  │        │  │     └─ CategoryService.java
│  │  │        │  ├─ chat
│  │  │        │  │  ├─ controller
│  │  │        │  │  │  ├─ ChatMessageController.java
│  │  │        │  │  │  ├─ ChatRoomController.java
│  │  │        │  │  │  ├─ WebSocketDocumentationController.java
│  │  │        │  │  │  └─ test
│  │  │        │  │  │     ├─ ChatViewControllerTest.java
│  │  │        │  │  │     └─ WebSocketControllerTest.java
│  │  │        │  │  ├─ dto
│  │  │        │  │  │  ├─ request
│  │  │        │  │  │  │  ├─ ChatMessageRequest.java
│  │  │        │  │  │  │  ├─ ChatRoomChangeNameRequest.java
│  │  │        │  │  │  │  └─ UpdateChatMessageRequest.java
│  │  │        │  │  │  └─ response
│  │  │        │  │  │     ├─ ChatMessageDeleteSuccessResponse.java
│  │  │        │  │  │     ├─ ChatMessageListResponse.java
│  │  │        │  │  │     ├─ ChatMessageResponse.java
│  │  │        │  │  │     ├─ ChatMessageSuccessResponse.java
│  │  │        │  │  │     ├─ ChatMessageToDTOResponse.java
│  │  │        │  │  │     ├─ ChatRoomResponse.java
│  │  │        │  │  │     └─ ParticipatedRoomListResponse.java
│  │  │        │  │  ├─ entity
│  │  │        │  │  │  ├─ ChatMessage.java
│  │  │        │  │  │  ├─ ChatRoom.java
│  │  │        │  │  │  ├─ MessageType.java
│  │  │        │  │  │  └─ ParticipatedRoom.java
│  │  │        │  │  ├─ redis
│  │  │        │  │  │  └─ RedisSubscriber.java
│  │  │        │  │  ├─ repository
│  │  │        │  │  │  ├─ ChatMessageRepository.java
│  │  │        │  │  │  ├─ ChatRoomRepository.java
│  │  │        │  │  │  └─ ParticipatedRoomRepository.java
│  │  │        │  │  └─ service
│  │  │        │  │     ├─ ChatMessageService.java
│  │  │        │  │     └─ ChatRoomService.java
│  │  │        │  ├─ comment
│  │  │        │  │  ├─ controller
│  │  │        │  │  │  └─ CommentController.java
│  │  │        │  │  ├─ dto
│  │  │        │  │  │  ├─ request
│  │  │        │  │  │  │  ├─ CommentArticleRequest.java
│  │  │        │  │  │  │  ├─ CommentBoardRequest.java
│  │  │        │  │  │  │  ├─ CommentDeleteRequest.java
│  │  │        │  │  │  │  ├─ CommentPageRequest.java
│  │  │        │  │  │  │  └─ CommentUpdateRequest.java
│  │  │        │  │  │  └─ response
│  │  │        │  │  │     └─ CommentResponse.java
│  │  │        │  │  ├─ entity
│  │  │        │  │  │  └─ Comment.java
│  │  │        │  │  ├─ repository
│  │  │        │  │  │  └─ CommentRepository.java
│  │  │        │  │  └─ service
│  │  │        │  │     └─ CommentService.java
│  │  │        │  ├─ image
│  │  │        │  │  ├─ controller
│  │  │        │  │  │  └─ ImageController.java
│  │  │        │  │  ├─ dto
│  │  │        │  │  │  └─ ImageDto.java
│  │  │        │  │  ├─ entity
│  │  │        │  │  │  └─ Image.java
│  │  │        │  │  ├─ repository
│  │  │        │  │  │  └─ ImageRepository.java
│  │  │        │  │  └─ service
│  │  │        │  │     └─ ImageService.java
│  │  │        │  ├─ member
│  │  │        │  │  ├─ controller
│  │  │        │  │  │  ├─ AddressController.java
│  │  │        │  │  │  ├─ AuthController.java
│  │  │        │  │  │  ├─ MemberAdminController.java
│  │  │        │  │  │  ├─ MemberUserController.java
│  │  │        │  │  │  ├─ Oauth2Controller.java
│  │  │        │  │  │  └─ test
│  │  │        │  │  │     └─ MemberFileTestPageController.java
│  │  │        │  │  ├─ dto
│  │  │        │  │  │  ├─ AddressCreateSuccessResponse.java
│  │  │        │  │  │  ├─ AddressDeleteSuccessResponse.java
│  │  │        │  │  │  ├─ MemberAddressRequest.java
│  │  │        │  │  │  ├─ MemberAddressResponse.java
│  │  │        │  │  │  ├─ MemberBanRequest.java
│  │  │        │  │  │  ├─ MemberCheckPasswordResponse.java
│  │  │        │  │  │  ├─ MemberCreateRequest.java
│  │  │        │  │  │  ├─ MemberFindPasswordRequest.java
│  │  │        │  │  │  ├─ MemberFindUserIdRequest.java
│  │  │        │  │  │  ├─ MemberGetRequestByEmail.java
│  │  │        │  │  │  ├─ MemberGetRequestByNickname.java
│  │  │        │  │  │  ├─ MemberGetRequestByUserId.java
│  │  │        │  │  │  ├─ MemberGetResponse.java
│  │  │        │  │  │  ├─ MemberGetResponseOnlyMember.java
│  │  │        │  │  │  ├─ MemberRegisterRequest.java
│  │  │        │  │  │  ├─ MemberSendMailResponse.java
│  │  │        │  │  │  ├─ MemberUpdateRequest.java
│  │  │        │  │  │  ├─ PageRequestDTO.java
│  │  │        │  │  │  ├─ PasswordDTO.java
│  │  │        │  │  │  ├─ request
│  │  │        │  │  │  │  └─ LoginRequest.java
│  │  │        │  │  │  └─ response
│  │  │        │  │  │     └─ MemberGetByOtherResponse.java
│  │  │        │  │  ├─ entity
│  │  │        │  │  │  ├─ Address.java
│  │  │        │  │  │  ├─ Member.java
│  │  │        │  │  │  ├─ MemberRole.java
│  │  │        │  │  │  └─ embadded
│  │  │        │  │  │     ├─ Email.java
│  │  │        │  │  │     ├─ Nickname.java
│  │  │        │  │  │     ├─ Password.java
│  │  │        │  │  │     └─ UserId.java
│  │  │        │  │  ├─ repository
│  │  │        │  │  │  ├─ AddressRepository.java
│  │  │        │  │  │  └─ MemberRepository.java
│  │  │        │  │  ├─ service
│  │  │        │  │  │  ├─ AddressService.java
│  │  │        │  │  │  ├─ MemberAdminService.java
│  │  │        │  │  │  └─ MemberUserService.java
│  │  │        │  │  └─ util
│  │  │        │  │     ├─ GeometryUtil.java
│  │  │        │  │     └─ PasswordGenerator.java
│  │  │        │  ├─ notification
│  │  │        │  │  ├─ controller
│  │  │        │  │  │  └─ NotificationController.java
│  │  │        │  │  ├─ dto
│  │  │        │  │  │  ├─ NotificationSendDTO.java
│  │  │        │  │  │  ├─ request
│  │  │        │  │  │  │  └─ NotificationRequest.java
│  │  │        │  │  │  └─ response
│  │  │        │  │  │     └─ NotificationResponse.java
│  │  │        │  │  ├─ entity
│  │  │        │  │  │  ├─ Notification.java
│  │  │        │  │  │  └─ NotificationType.java
│  │  │        │  │  ├─ repository
│  │  │        │  │  │  └─ NotificationRepository.java
│  │  │        │  │  └─ service
│  │  │        │  │     └─ NotificationService.java
│  │  │        │  ├─ pet
│  │  │        │  │  ├─ controller
│  │  │        │  │  │  └─ PetController.java
│  │  │        │  │  ├─ dto
│  │  │        │  │  │  ├─ PageRequest.java
│  │  │        │  │  │  ├─ PetCreateRequest.java
│  │  │        │  │  │  ├─ PetLocationRequest.java
│  │  │        │  │  │  ├─ PetMemberProfileResponse.java
│  │  │        │  │  │  ├─ PetNearbyPageResponse.java
│  │  │        │  │  │  ├─ PetNearbyResponse.java
│  │  │        │  │  │  ├─ PetPageResponse.java
│  │  │        │  │  │  ├─ PetResponse.java
│  │  │        │  │  │  └─ PetUpdateRequest.java
│  │  │        │  │  ├─ entity
│  │  │        │  │  │  ├─ Pet.java
│  │  │        │  │  │  ├─ PetGender.java
│  │  │        │  │  │  └─ PetType.java
│  │  │        │  │  ├─ repository
│  │  │        │  │  │  └─ PetRepository.java
│  │  │        │  │  └─ service
│  │  │        │  │     └─ PetService.java
│  │  │        │  └─ review
│  │  │        │     ├─ controller
│  │  │        │     │  └─ ReviewController.java
│  │  │        │     ├─ dto
│  │  │        │     │  ├─ PageRequest.java
│  │  │        │     │  ├─ ReviewCreateRequest.java
│  │  │        │     │  ├─ ReviewInfoResponse.java
│  │  │        │     │  ├─ ReviewPageResponse.java
│  │  │        │     │  └─ ReviewUpdateRequest.java
│  │  │        │     ├─ entity
│  │  │        │     │  ├─ Review.java
│  │  │        │     │  └─ ReviewStatus.java
│  │  │        │     ├─ repository
│  │  │        │     │  └─ ReviewRepository.java
│  │  │        │     └─ service
│  │  │        │        └─ ReviewService.java
│  │  │        ├─ global
│  │  │        │  ├─ advice
│  │  │        │  │  └─ GlobalExceptionHandler.java
│  │  │        │  ├─ common
│  │  │        │  │  └─ BaseTimeEntity.java
│  │  │        │  ├─ config
│  │  │        │  │  ├─ EmbeddedRedisConfig.java
│  │  │        │  │  ├─ GeometryConfig.java
│  │  │        │  │  ├─ MvcConfig.java
│  │  │        │  │  ├─ RedisCacheConfig.java
│  │  │        │  │  ├─ RedisConfig.java
│  │  │        │  │  ├─ RestTemplateConfig.java
│  │  │        │  │  ├─ SecurityBeansConfig.java
│  │  │        │  │  ├─ SecurityConfig.java
│  │  │        │  │  ├─ SwaggerConfig.java
│  │  │        │  │  └─ WebSocketConfig.java
│  │  │        │  ├─ exception
│  │  │        │  │  ├─ ErrorCode.java
│  │  │        │  │  ├─ ErrorResponse.java
│  │  │        │  │  └─ MallangsCustomException.java
│  │  │        │  ├─ handler
│  │  │        │  │  ├─ SseEmitters.java
│  │  │        │  │  ├─ StompFileHandler.java
│  │  │        │  │  └─ StompHandler.java
│  │  │        │  ├─ jwt
│  │  │        │  │  ├─ controller
│  │  │        │  │  │  └─ TokenController.java
│  │  │        │  │  ├─ dto
│  │  │        │  │  │  ├─ TokensRequest.java
│  │  │        │  │  │  └─ TokensResponse.java
│  │  │        │  │  ├─ entity
│  │  │        │  │  │  ├─ CustomMemberDetails.java
│  │  │        │  │  │  └─ TokenCategory.java
│  │  │        │  │  ├─ filter
│  │  │        │  │  │  ├─ JWTFilter.java
│  │  │        │  │  │  ├─ LoginFilter.java
│  │  │        │  │  │  └─ LogoutFilter.java
│  │  │        │  │  ├─ handler
│  │  │        │  │  │  └─ CustomAuthenticationFailureHandler.java
│  │  │        │  │  ├─ service
│  │  │        │  │  │  ├─ AccessTokenBlackList.java
│  │  │        │  │  │  ├─ CustomerMemberDetailService.java
│  │  │        │  │  │  └─ RefreshTokenService.java
│  │  │        │  │  └─ util
│  │  │        │  │     └─ JWTUtil.java
│  │  │        │  ├─ oauth2
│  │  │        │  │  ├─ dto
│  │  │        │  │  │  ├─ CustomOAuth2Member.java
│  │  │        │  │  │  └─ MemberOAuth2DTO.java
│  │  │        │  │  ├─ handler
│  │  │        │  │  │  ├─ CustomFailureHandler.java
│  │  │        │  │  │  └─ CustomSuccessHandler.java
│  │  │        │  │  ├─ response
│  │  │        │  │  │  ├─ GoogleResponse.java
│  │  │        │  │  │  ├─ NaverResponse.java
│  │  │        │  │  │  └─ OAuth2Response.java
│  │  │        │  │  └─ service
│  │  │        │  │     └─ CustomOAuth2MemberService.java
│  │  │        │  ├─ s3
│  │  │        │  │  ├─ S3Config.java
│  │  │        │  │  ├─ S3Controller.java
│  │  │        │  │  └─ S3Service.java
│  │  │        │  └─ schedule
│  │  │        │     └─ CustomTaskScheduler.java
│  │  │        └─ web
│  │  │           └─ HomeController.java
│  │  └─ resources
│  │     ├─ application-dev.properties
│  │     ├─ messages.properties
│  │     └─ templates
│  │        └─ websocket_test.html
│  └─ test
│     └─ java
│        └─ com
│           └─ mallangs
│              ├─ MallangsApplicationTests.java
│              └─ domain
│                 ├─ article
│                 │  ├─ repository
│                 │  │  └─ ArticleRepositoryTest.java
│                 │  └─ service
│                 │     └─ ArticleServiceTest.java
│                 ├─ board
│                 │  └─ repository
│                 │     ├─ BoardRepositoryTest.java
│                 │     └─ CategoryRepositoryTest.java
│                 ├─ chat
│                 │  ├─ repository
│                 │  │  ├─ ChatRoomRepositoryTest.java
│                 │  │  ├─ ChatRoomRepositoryTests.java
│                 │  │  └─ ParticipatedRoomRepositoryTest.java
│                 │  └─ service
│                 │     ├─ ChatMessageServiceTests.java
│                 │     └─ ChatRoomServiceTests.java
│                 ├─ member
│                 │  ├─ repository
│                 │  │  ├─ AddressRepositoryTests.java
│                 │  │  └─ MemberRepositoryTests.java
│                 │  └─ service
│                 │     ├─ AddressServiceTests.java
│                 │     └─ MemberServiceTests.java
│                 ├─ pet
│                 │  ├─ repository
│                 │  │  └─ PetRepositoryTest.java
│                 │  └─ service
│                 │     └─ PetServiceTest.java
│                 └─ review
│                    ├─ repository
│                    │  └─ ReviewRepositoryTest.java
│                    └─ service
│                       └─ ReviewServiceTest.java
└─ upload
   ├─ baa22335-a605-4d1e-8735-ea775a4bd056_스크린샷 2024-08-07 165513.png
   └─ s_baa22335-a605-4d1e-8735-ea775a4bd056_스크린샷 2024-08-07 165513.png

글타래
커뮤니티
게시판
댓글
리뷰
알림
채팅
서버 아키텍쳐

image

시스템 설계 및 다이어그램

ERD

스크린샷 2024-12-09 143601

와이어 프레임
유저 스토리

image

흐름도

Untitled diagram-2024-12-11-014121

프로젝트 협업 규칙

Convention

깃 전략

Feature-Branch 전략(GitHub Flow)

image

Branch 관리

Main Branch

  • 배포 브랜치, 운영 서버
  • 직접적인 PUSH 금지
  • developmain Pull Request만 허용

Develop Branch

  • 개발 통합 브랜치: 다음 배포 버전을 위한 개발 코드 통합
  • 기능 개발이 완료된 feature 브랜치들의 병합 지점
  • QA/테스트 진행 시 기본 브랜치

Feature Branch (branch명: feature/기능명)

  • 기능 개발 작업용 브랜치
  • Issue 생성 → Branch 생성 → 개발 → PR 요청 → 코드 리뷰 → Merge

Merge 방식

  • 마지막 승인자(Merge Approver)가 머지 수행
  • feature 브랜치: 1명 이상 승인 시
  • develop 브랜치: 모든 팀원 승인 시

Git Convention

💡 프로세스:

  • Issue 생성 → 브랜치 생성 → 해당 브랜치 이동 → develop Pull → 커밋 → PR 생성

🚨 주의사항:

  • 커밋 메시지 템플릿을 반드시 지킬 것
  • 충돌 발생 주의
  • main 브랜치에 직접 PR 금지 (develop으로만 PR 가능)

[type] 커밋 메시지 형식

  • feat: 새로운 기능 구현
  • mod: 코드 및 파일 수정
  • add: 라이브러리 추가 및 코드 추가
  • del: 불필요한 코드/파일 삭제
  • fix: 버그 및 오류 해결
  • ui: UI 관련 작업
  • chore: 작은 작업 (버전 관리 등)
  • hotfix: 긴급 배포 수정
  • rename: 파일 및 폴더명 수정
  • docs: 문서 작업
  • refactor: 코드 리팩토링
  • merge: 브랜치 병합
  • comment: 주석 추가 및 변경

Code Convention

//도메인 지정
private Long memberId;

private Long userId; 

//엔티티 수정 메서드 : chanegeMethod
public void changeName(String name){
    this.name = name;
}

//엔티티 수정 메서드 : chanegeMethod
public void changeWeight(Integer weight){
    this.weight = weight;
}

domainId로 통일

팀원 소개

강수민 오익수 김동현 한재재 김동우
글타래
커뮤니티, 이미지
명세서 관리
채팅, 회원
댓글, 알림
펫, 리뷰
공공데이터 DB 적재

About

위치기반 반려동물 소셜 서비스 '말랑 플레이스'

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages