Skip to content

Commit

Permalink
release 1.0.5
Browse files Browse the repository at this point in the history
  • Loading branch information
KAispread committed Dec 12, 2023
2 parents d24d3af + caeb209 commit 78d17fa
Show file tree
Hide file tree
Showing 152 changed files with 4,641 additions and 2,086 deletions.
90 changes: 88 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,88 @@
# wemeet-backend
We:meet (위밋) 백엔드 API 서버 Repo
<p align="center">
<img alt="image" src="https://github.com/SWM-E2I/wemeet-backend/assets/99247279/52bb1ad9-295b-4867-9222-8c7ba9814424" />
</p>

<p align="center">
<a href="https://apps.apple.com/us/app/%EC%9C%84%EB%B0%8B-%EB%8C%80%ED%95%99%EC%83%9D-%EB%AF%B8%ED%8C%85-%EA%B3%BC%ED%8C%85-%EC%97%AC%EA%B8%B0%EC%84%9C-%EB%A7%8C%EB%82%98/id6466416689">
<img src="https://img.shields.io/badge/appstore-0D96F6?style=for-the-badge&logo=appstore&logoColor=white">
</a>

<a href="https://play.google.com/store/apps/details?id=net.andrewjsy.wemeet">
<img src="https://img.shields.io/badge/googleplay-414141?style=for-the-badge&logo=googleplay&logoColor=white">
</a>

<img src="https://img.shields.io/badge/v1.0.4-1AB394?style=for-the-badge&logo=sessionize&logoColor=white">
</p>

## 💌 소개
### 대학생들을 위한 모든 만남을 제공하는 만남 주선 서비스
- 매일 11시 11분마다 새로운 이성 추천
- 이틀마다 갱신되는 질문 취향 통해 다양한 매력 포인트 제공
- 이성에게 호감을 표현하기 위한 다양한 기능 제공 (좋아요, 미팅 신청, 쪽지)
- 다양한 인증을 통한 신뢰성 확보 (휴대폰 인증, 대학생 인증, 사진 인증)

&nbsp;

## ⭐ SW Maestro 14th - E2I

|이기우|박채림|장세윤|
|:--:|:--:|:---:|
|<img width="160px" src="https://github.com/SWM-E2I/.github/assets/99247279/9c915d0f-c77d-4d89-aeb5-a72b6e8b5ee9"> | <img width="160px" src="https://github.com/SWM-E2I/.github/assets/99247279/82524158-05e8-49b5-928d-3563fe1003a3" /> | <img width="160px" src="https://github.com/SWM-E2I/.github/assets/99247279/9d998830-3941-433b-83d7-b15aa80adef0"> |
|**Backend**|**Backend**|**Frontend**|
|[@KAispread](https://github.com/KAispread)|[@Chaerim1001](https://github.com/Chaerim1001)|[@Andrewjsy](https://github.com/Andrewjsy)|

&nbsp;

## 📚 Other Pages
- #### 🍎 [AppStore](https://apps.apple.com/us/app/%EC%9C%84%EB%B0%8B-%EB%8C%80%ED%95%99%EC%83%9D-%EB%AF%B8%ED%8C%85-%EA%B3%BC%ED%8C%85-%EC%97%AC%EA%B8%B0%EC%84%9C-%EB%A7%8C%EB%82%98/id6466416689)
- #### 🧩 [PlayStore](https://play.google.com/store/apps/details?id=net.andrewjsy.wemeet)
- #### 🖇 [Instagram](https://www.instagram.com/wemeet__official/)
- #### 🖇 [KakaoTalk Channel](https://pf.kakao.com/_WshlG)
- #### 🖇 [Organization](https://github.com/SWM-E2I)
&nbsp;

## 🛠️ Tech Stack
<p align="center">
<img width="800" alt="image" src="https://github.com/SWM-E2I/wemeet-backend/assets/99247279/ce18758f-8637-4e2e-b858-2ab9c6b2f22b" />
</p>

&nbsp;

## ⚙️ AWS Infrastructure
<p align="center">
<img width="800" alt="image" src="https://github.com/SWM-E2I/wemeet-backend/assets/99247279/c62204e0-44b8-4944-88ca-05881f75e755" />
</p>

&nbsp;

## 🔀 CI/CD Pipeline
<p align="center">
<img width="800" alt="image" src="https://github.com/SWM-E2I/wemeet-backend/assets/99247279/6fd4ec97-613c-4a88-ba27-73ed5c19fbd2" />
</p>

&nbsp;

## 📊 Log & Monitoring
<p align="center">
<img width="800" alt="image" src="https://github.com/SWM-E2I/wemeet-backend/assets/99247279/bc4988a8-87c2-4d73-a4b8-b3ec0f661401" />
</p>

## 📚 API Docs
- Rest Docs의 테스트를 통한 API 문서 생성과 Swagger-UI의 장점을 합쳐 API 문서화
- #### 🖇 [Reference](https://tech.kakaopay.com/post/openapi-documentation/)

<p align="center">
<img width="800" alt="image" src="https://github.com/SWM-E2I/wemeet-backend/assets/99247279/fea1a32f-6b5a-47f5-bb73-da02d93501ee" />
</p>


&nbsp;

## 🌠 Overview

<p align="center">
<img width="200" alt="image" src="https://github.com/SWM-E2I/wemeet-backend/assets/99247279/8ae9ec3f-d5cf-49b5-b21a-7a12a99a2199" />
<img width="200" alt="image" src="https://github.com/SWM-E2I/wemeet-backend/assets/99247279/7be2c79c-a8fd-4058-a2ec-2d500c28fcab" />
<img width="200" alt="image" src="https://github.com/SWM-E2I/wemeet-backend/assets/99247279/b70e5f0d-274f-4004-828a-d9568b723ad0" />
<img width="200" alt="image" src="https://github.com/SWM-E2I/wemeet-backend/assets/99247279/4c88ffcd-7ab2-4980-8e45-997f983d1bc2" />
</p>
26 changes: 23 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,32 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-redis:3.1.0'
implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.4.1'

// Query Details
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0'

// Monitoring
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-registry-prometheus'

implementation 'com.auth0:java-jwt:4.4.0'
implementation 'org.flywaydb:flyway-core'
implementation 'org.flywaydb:flyway-mysql'
testImplementation 'org.projectlombok:lombok:1.18.26'

compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
testCompileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'

implementation platform('software.amazon.awssdk:bom:2.20.26')

implementation 'software.amazon.awssdk:sns:2.20.90'
implementation 'software.amazon.awssdk:ses:2.20.86'
implementation 'software.amazon.awssdk:s3:2.20.82'

// REST - Assured
testImplementation 'io.rest-assured:rest-assured:5.3.2'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
Expand All @@ -76,6 +85,16 @@ dependencies {

// Component that test code convert to Swagger file and include restDocs Api
testImplementation('com.epages:restdocs-api-spec-mockmvc:0.18.2') //2.2


// Json Serializer
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.0'
implementation 'com.fasterxml.jackson.core:jackson-core:2.15.0'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.15.0'

// expo push notification
implementation('io.github.jav:expo-server-sdk:1.1.0')
}

// Querydsl
Expand Down Expand Up @@ -151,13 +170,14 @@ jib {
image = 'eclipse-temurin:17-jdk-alpine'
}
to {
image = '075584359222.dkr.ecr.ap-northeast-2.amazonaws.com/wemeet-dev-ecr'
image = '634460857598.dkr.ecr.ap-northeast-2.amazonaws.com/wemeet-ecr'
tags = [inputTag]
credHelper = 'ecr-login'
}
container {
creationTime = 'USE_CURRENT_TIMESTAMP'
jvmFlags = ['-XX:+UseContainerSupport', '-Dserver.port=8080', '-Dfile.encoding=UTF-8', '-Duser.timezone=Asia/Seoul']
jvmFlags = ['-javaagent:/scouter.agent.jar', '-Dscouter.config=/spring-scouter.conf',
'-XX:+UseContainerSupport', '-Dserver.port=8080', '-Dfile.encoding=UTF-8', '-Duser.timezone=Asia/Seoul']
ports = ['8080']
}
}
10 changes: 10 additions & 0 deletions src/main/java/com/e2i/wemeet/config/common/SchedulerConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.e2i.wemeet.config.common;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;

@Configuration
@EnableScheduling
public class SchedulerConfig {

}
18 changes: 18 additions & 0 deletions src/main/java/com/e2i/wemeet/config/flyway/FlywayConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.e2i.wemeet.config.flyway;

import org.springframework.boot.autoconfigure.flyway.FlywayMigrationStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FlywayConfig {

@Bean
public FlywayMigrationStrategy cleanMigrateStrategy() {
return flyway -> {
flyway.repair();
flyway.migrate();
};
}
}

16 changes: 16 additions & 0 deletions src/main/java/com/e2i/wemeet/config/log/LogExcludeUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.e2i.wemeet.config.log;

import static com.e2i.wemeet.config.log.OperationExcludePattern.EXCLUDE_PATTERN;

public abstract class LogExcludeUtil {

private LogExcludeUtil() {
throw new AssertionError();
}

public static boolean isMatchedExcludeUrls(final String requestUrl) {
return EXCLUDE_PATTERN.getExcludePattern().stream()
.anyMatch(pattern -> pattern.matcher(requestUrl).matches());
}

}
2 changes: 1 addition & 1 deletion src/main/java/com/e2i/wemeet/config/log/LogFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public LogFilter(final StopWatch apiWatch, final QueryCounter queryCounter) {
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// 요청이 Logging 제외 목록에 포함 되어있을 경우, 로그를 남기지 않고 요청 전송
if (LogExceptionPattern.isMatchedExceptionUrls(request.getRequestURI())) {
if (LogExcludeUtil.isMatchedExcludeUrls(request.getRequestURI())) {
filterChain.doFilter(request, response);
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.e2i.wemeet.config.log;

import java.util.List;
import java.util.regex.Pattern;

public enum OperationExcludePattern {
EXCLUDE_PATTERN(List.of(
java.util.regex.Pattern.compile("^/static/dist.*"),
java.util.regex.Pattern.compile("^/static/swagger-ui.*"),
java.util.regex.Pattern.compile("^/api-docs.*"),
java.util.regex.Pattern.compile("^/h2-console.*"),
java.util.regex.Pattern.compile("^/actuator.*")
));

private final List<Pattern> excludePattern;

OperationExcludePattern(List<Pattern> excludePattern) {
this.excludePattern = excludePattern;
}

public List<Pattern> getExcludePattern() {
return excludePattern;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.e2i.wemeet.config.notification;

import io.github.jav.exposerversdk.PushClient;
import io.github.jav.exposerversdk.PushClientException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class NotificationConfig {

@Bean
public PushClient pushClient() throws PushClientException {
return new PushClient();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public ResponseEntity<ErrorResponse> handleNotEqualRoleException(
// SQL 관련 예외 핸들링 + sql & sql 예외 원인 Logging
@ExceptionHandler({DataAccessException.class, UndeclaredThrowableException.class})
public ResponseEntity<ErrorResponse> handleDatabaseAccessException(
final DataAccessException e) {
final RuntimeException e) {
final int code = DATA_ACCESS.getCode();

String message = messageSourceAccessor.getMessage(DATA_ACCESS.getMessageKey());
Expand Down
21 changes: 19 additions & 2 deletions src/main/java/com/e2i/wemeet/controller/TokenController.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,42 @@
package com.e2i.wemeet.controller;

import com.e2i.wemeet.config.resolver.member.MemberId;
import com.e2i.wemeet.dto.request.token.PushTokenRequestDto;
import com.e2i.wemeet.dto.response.ResponseDto;
import com.e2i.wemeet.dto.response.ResponseStatus;
import com.e2i.wemeet.dto.response.persist.PersistResponseDto;
import com.e2i.wemeet.security.token.handler.AccessTokenHandler;
import com.e2i.wemeet.service.token.TokenService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RequestMapping("/v1/auth")
@RequestMapping("/v1")
@RestController
public class TokenController {

private final TokenService tokenService;
private final AccessTokenHandler accessTokenHandler;

@GetMapping("/persist")

@GetMapping("/auth/persist")
public ResponseDto<PersistResponseDto> persist(@MemberId Long memberId) {
PersistResponseDto result = tokenService.persistLogin(memberId);
return new ResponseDto<>(ResponseStatus.SUCCESS, "Persist Login Success", result);
}

@PostMapping("/push")
public ResponseDto<Void> savePushToken(@RequestBody PushTokenRequestDto requestDto,
@RequestHeader(name = "AccessToken", defaultValue = "") String accessToken) {
Long memberId = accessTokenHandler.extractMemberId(accessToken).orElseGet(() -> null);
tokenService.savePushToken(requestDto.pushToken(), memberId);

return ResponseDto.success("Push Token Save Success");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.e2i.wemeet.controller.member;

import com.e2i.wemeet.config.resolver.member.MemberId;
import com.e2i.wemeet.dto.response.ResponseDto;
import com.e2i.wemeet.service.member.BlockService;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RequestMapping("/v1/member/block")
@RestController
public class BlockController {

private final BlockService blockService;

@PostMapping("/{blockMemberId}")
public ResponseDto<Long> blockMember(@MemberId Long memberId, @PathVariable Long blockMemberId) {
final Long blockedMemberId = blockService.block(memberId, blockMemberId);
return ResponseDto.success("Block Member Success", blockedMemberId);
}

@GetMapping
public ResponseDto<List<Long>> readBlockMembers(@MemberId Long memberId) {
final List<Long> blockList = blockService.readBlockList(memberId);
return ResponseDto.success("Read Block Member Success", blockList);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.e2i.wemeet.controller.member;

import com.e2i.wemeet.config.resolver.member.MemberId;
import com.e2i.wemeet.dto.request.member.RecommenderRequestDto;
import com.e2i.wemeet.dto.response.ResponseDto;
import com.e2i.wemeet.service.member.RecommendService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RequestMapping("/v1/recommend")
@RestController
public class RecommendController {

private final RecommendService recommendService;

@PostMapping
public ResponseDto<Long> recommend(@MemberId Long memberId,
@RequestBody @Valid RecommenderRequestDto requestDto) {
recommendService.recommend(memberId, requestDto.phoneNumber());
return ResponseDto.success("Recommend Success", null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ public class SuggestionController {
@GetMapping
public ResponseDto<List<SuggestionResponseDto>> readSuggestion(@MemberId Long memberId) {
LocalDateTime requestTime = LocalDateTime.now();
// List<SuggestionResponseDto> response = suggestionService.readSuggestion(memberId, requestTime);
// 사전 예약 카드 노출
List<SuggestionResponseDto> response = suggestionService.tempSuggestion(memberId,
List<SuggestionResponseDto> response = suggestionService.readSuggestion(memberId,
requestTime);

return ResponseDto.success("Get Suggestion Success", response);
Expand Down
Loading

0 comments on commit 78d17fa

Please sign in to comment.