Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0b6d939
[chore] #115 PLATFROM_ID -> PLATFORM_ID 변수명 변경
2hyunjinn Jun 1, 2025
d0428ca
[refactor] #115 JWT 인증 관련 클래스 구조 개선 및 역할 분리
2hyunjinn Jun 1, 2025
5b0ad6d
[chore] #115 docker-compose.yaml 수정
2hyunjinn Jun 1, 2025
4ddea7e
[feat] #115 JwtAuthFilter에서 userId RequestAttribute로 주입하여 컨트롤러 인증 파라미…
2hyunjinn Jun 1, 2025
bf53420
[chore] #115 jwt 토큰 발급 메서드 jwtTokenProvider 로 변경
2hyunjinn Jun 1, 2025
2da452f
[chore] #115 불필요한 코드 제거
2hyunjinn Jun 1, 2025
0a72230
[chore] #115 .gitignore 일부 수정
2hyunjinn Jun 1, 2025
b3814d5
[chore] #115 BEARER의 길이 기반으로 토큰 파싱
2hyunjinn Jun 1, 2025
cbce273
Merge pull request #142 from Team-Festimate/refactor/#115
2hyunjinn Jun 1, 2025
0e388c5
[refactor] #143 MatchingValidator에 매칭 관련 검증 로직 추가
2hyunjinn Jun 12, 2025
e3cc085
[fix] #143 내가 신청한 매칭만 조회할 수 있도록 검증 로직 추가
2hyunjinn Jun 12, 2025
2b755c8
[test] #143 다른 사람이 신청한 매칭을 조회할 경우 예외 발생하는 테스트 코드 구현
2hyunjinn Jun 12, 2025
2a315f0
[chore] #143 != -> equals 로 변경
2hyunjinn Jun 12, 2025
1022668
Merge pull request #144 from Team-Festimate/fix/#143
2hyunjinn Jun 12, 2025
87352e9
[feat] #145 queryDsl 관련 의존성 추가
2hyunjinn Jun 15, 2025
1b901fd
[feat] #145 queryDsl 관련 의존성 추가
2hyunjinn Jun 16, 2025
f9a2519
[feat] #145 QuerydslConfig 구현
2hyunjinn Jun 16, 2025
496aa6e
[feat] #145 MatchingRepository 에 queryDSL 도입
2hyunjinn Jun 16, 2025
4a1a2ff
[feat] #145 MatchingRepository 에서 MatchingRepositoryCustom 참조할 수 있도록 추가
2hyunjinn Jun 16, 2025
eb8c8cb
[test] #145 매칭 추가하기에서 MatchingRepositoryCustom 참조하도록 변경
2hyunjinn Jun 16, 2025
d50c5f2
[refactor] #145 서브쿼리는 서비스 레벨에서 한번만 조회하고, 이후 메인쿼리만 반복 호출할 수 있도록 변경
2hyunjinn Jun 16, 2025
1918e63
[del] #145 불필요한 코드 제거
2hyunjinn Jun 16, 2025
66a3a39
[refactor] #145 EntityManager 제거
2hyunjinn Jun 16, 2025
e4b0c4d
Merge pull request #146 from Team-Festimate/feat/#145
2hyunjinn Jun 16, 2025
adb0748
[feat] #147 참가자 입장 시 10포인트 자동 충전
2hyunjinn Jul 10, 2025
e86affa
[test] #147 참가자 입장 시 자동 충전 관련 테스트 코드 작성
2hyunjinn Jul 10, 2025
016ee9d
Merge pull request #148 from Team-Festimate/feat/#147
2hyunjinn Jul 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ out/

### VS Code ###
.vscode/
/mysql-data/
22 changes: 20 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
id 'io.spring.dependency-management' version '1.1.7'
}

group = 'org.festiamte'
group = 'org.festimate'
version = '0.0.1-SNAPSHOT'

java {
Expand Down Expand Up @@ -58,8 +58,26 @@ dependencies {
testImplementation 'io.projectreactor:reactor-test' // WebFlux 테스트 지원
testImplementation 'org.springframework.security:spring-security-test' // Security 테스트 지원
testRuntimeOnly 'org.junit.platform:junit-platform-launcher' // JUnit 테스트 실행기

// --- QueryDSL ---
implementation "com.querydsl:querydsl-jpa:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta'

// --- Jakarta Persistence API ---
implementation 'jakarta.persistence:jakarta.persistence-api:3.1.0'
annotationProcessor 'jakarta.persistence:jakarta.persistence-api:3.1.0'
}

sourceSets {
main {
java {
srcDir 'src/main/java'
// Q-타입 생성 위치를 IDE가 인식하도록 추가
srcDir 'build/generated/sources/annotationProcessor/java/main'
}
}
}

tasks.named('test') {
useJUnitPlatform()
}
}
9 changes: 7 additions & 2 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
version: "3"
services:
mysql:
image: 'mysql:latest'
image: mysql:8.0
container_name: festimate-mysql-1
env_file:
- .env
ports:
- '3306:3306'
- "3306:3306"
volumes:
- ./mysql-data:/var/lib/mysql
restart: unless-stopped
27 changes: 8 additions & 19 deletions src/main/java/org/festimate/team/api/admin/AdminController.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import org.festimate.team.api.point.dto.PointHistoryResponse;
import org.festimate.team.global.response.ApiResponse;
import org.festimate.team.global.response.ResponseBuilder;
import org.festimate.team.infra.jwt.JwtService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

Expand All @@ -16,7 +15,6 @@
@RequestMapping("/v1/admin/festivals")
@RequiredArgsConstructor
public class AdminController {
private final JwtService jwtService;
private final FestivalFacade festivalFacade;
private final FestivalHostFacade festivalHostFacade;
private final ParticipantFacade participantFacade;
Expand All @@ -25,85 +23,76 @@ public class AdminController {

@PostMapping()
public ResponseEntity<ApiResponse<FestivalResponse>> createFestival(
@RequestHeader("Authorization") String accessToken,
@RequestAttribute("userId") Long userId,
@RequestBody FestivalRequest request
) {
Long userId = jwtService.parseTokenAndGetUserId(accessToken);
FestivalResponse response = festivalFacade.createFestival(userId, request);
return ResponseBuilder.created(response);
}

@GetMapping()
public ResponseEntity<ApiResponse<List<AdminFestivalResponse>>> getAllFestivals(
@RequestHeader("Authorization") String accessToken
@RequestAttribute("userId") Long userId
) {
Long userId = jwtService.parseTokenAndGetUserId(accessToken);
List<AdminFestivalResponse> response = festivalFacade.getAllFestivals(userId);
return ResponseBuilder.ok(response);
}

@GetMapping("/{festivalId}")
public ResponseEntity<ApiResponse<AdminFestivalDetailResponse>> getFestivalDetail(
@RequestHeader("Authorization") String accessToken,
@RequestAttribute("userId") Long userId,
@PathVariable Long festivalId
) {
Long userId = jwtService.parseTokenAndGetUserId(accessToken);
AdminFestivalDetailResponse response = festivalFacade.getFestivalDetail(userId, festivalId);
return ResponseBuilder.ok(response);
}

@GetMapping("/{festivalId}/participants/search")
public ResponseEntity<ApiResponse<List<SearchParticipantResponse>>> getParticipantByNickname(
@RequestHeader("Authorization") String accessToken,
@RequestAttribute("userId") Long userId,
@PathVariable("festivalId") Long festivalId,
@RequestParam("nickname") String nickname
) {
Long userId = jwtService.parseTokenAndGetUserId(accessToken);

List<SearchParticipantResponse> response = participantFacade.getParticipantByNickname(userId, festivalId, nickname);
return ResponseBuilder.ok(response);
}

@PostMapping("/{festivalId}/points")
public ResponseEntity<ApiResponse<Void>> rechargePoints(
@RequestHeader("Authorization") String accessToken,
@RequestAttribute("userId") Long userId,
@PathVariable("festivalId") Long festivalId,
@RequestBody RechargePointRequest request
) {
Long userId = jwtService.parseTokenAndGetUserId(accessToken);
pointFacade.rechargePoints(userId, festivalId, request);
return ResponseBuilder.ok(null);
}

@PostMapping("/{festivalId}/hosts")
public ResponseEntity<ApiResponse<Void>> addHost(
@RequestHeader("Authorization") String accessToken,
@RequestAttribute("userId") Long userId,
@PathVariable("festivalId") Long festivalId,
@RequestBody AddHostRequest request
) {
Long userId = jwtService.parseTokenAndGetUserId(accessToken);
festivalHostFacade.addHost(userId, festivalId, request);
return ResponseBuilder.created(null);
}

@GetMapping("/{festivalId}/participants/{participantId}/points")
public ResponseEntity<ApiResponse<PointHistoryResponse>> getParticipantPointHistory(
@RequestHeader("Authorization") String accessToken,
@RequestAttribute("userId") Long userId,
@PathVariable("festivalId") Long festivalId,
@PathVariable("participantId") Long participantId
) {
Long userId = jwtService.parseTokenAndGetUserId(accessToken);
PointHistoryResponse response = pointFacade.getParticipantPointHistory(userId, festivalId, participantId);
return ResponseBuilder.ok(response);
}

@GetMapping("/{festivalId}/participants/{participantId}/matchings")
public ResponseEntity<ApiResponse<AdminMatchingResponse>> getParticipantMatchingHistory(
@RequestHeader("Authorization") String accessToken,
@RequestAttribute("userId") Long userId,
@PathVariable("festivalId") Long festivalId,
@PathVariable("participantId") Long participantId
) {
Long userId = jwtService.parseTokenAndGetUserId(accessToken);
AdminMatchingResponse response = matchingFacade.getMatchingSize(userId, festivalId, participantId);
return ResponseBuilder.ok(response);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class AuthController {
public ResponseEntity<ApiResponse<TokenResponse>> login(
@RequestHeader("Authorization") String kakaoAccessToken
) {
log.info("social login - Code: {}", kakaoAccessToken);
log.info("social login - kakaoAccessToken: {}", kakaoAccessToken);

String platformId = loginFacade.getPlatformId(kakaoAccessToken);

Expand Down
10 changes: 5 additions & 5 deletions src/main/java/org/festimate/team/api/facade/LoginFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import org.festimate.team.domain.auth.service.KakaoLoginService;
import org.festimate.team.domain.user.entity.Platform;
import org.festimate.team.domain.user.service.UserService;
import org.festimate.team.infra.jwt.JwtService;
import org.festimate.team.infra.jwt.JwtTokenProvider;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -15,7 +15,7 @@
@RequiredArgsConstructor
public class LoginFacade {

private final JwtService jwtService;
private final JwtTokenProvider jwtTokenProvider;
private final UserService userService;
private final KakaoLoginService kakaoLoginService;

Expand All @@ -28,18 +28,18 @@ public TokenResponse login(String platformId, Platform platform) {

private TokenResponse loginExistingUser(Long userId) {
log.info("기존 유저 로그인 성공 - userId: {}", userId);
String newRefreshToken = jwtService.createRefreshToken(userId);
String newRefreshToken = jwtTokenProvider.createRefreshToken(userId);

userService.updateRefreshToken(userId, newRefreshToken);
return new TokenResponse(userId, jwtService.createAccessToken(userId), newRefreshToken);
return new TokenResponse(userId, jwtTokenProvider.createAccessToken(userId), newRefreshToken);
}

public String getPlatformId(String authorization) {
return kakaoLoginService.getKakaoPlatformId(authorization);
}

private TokenResponse createTemporaryToken(String platformId) {
return new TokenResponse(null, jwtService.createTempAccessToken(platformId), jwtService.createTempRefreshToken(platformId));
return new TokenResponse(null, jwtTokenProvider.createTempAccessToken(platformId), jwtTokenProvider.createTempRefreshToken(platformId));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public EntryResponse createParticipant(Long userId, Long festivalId, ProfileRequ
throw new FestimateException(ResponseError.PARTICIPANT_ALREADY_EXISTS);
}
Participant participant = participantService.createParticipant(user, festival, request);
pointService.rechargePoint(participant, 10);
matchingService.matchPendingParticipants(participant);

return EntryResponse.of(participant);
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/org/festimate/team/api/facade/SignUpFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
import org.festimate.team.domain.user.validator.NicknameValidator;
import org.festimate.team.global.exception.FestimateException;
import org.festimate.team.global.response.ResponseError;
import org.festimate.team.infra.jwt.JwtService;
import org.festimate.team.infra.jwt.JwtTokenProvider;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@RequiredArgsConstructor
public class SignUpFacade {
private final JwtService jwtService;
private final JwtTokenProvider jwtTokenProvider;
private final UserService userService;
private final NicknameValidator nicknameValidator;

Expand All @@ -36,8 +36,8 @@ public void validateNickname(String nickname) {

private TokenResponse createTokenResponse(User user) {
log.info("signup success - userId : {}, nickname : {}", user.getUserId(), user.getNickname());
String accessToken = jwtService.createAccessToken(user.getUserId());
String refreshToken = jwtService.createRefreshToken(user.getUserId());
String accessToken = jwtTokenProvider.createAccessToken(user.getUserId());
String refreshToken = jwtTokenProvider.createRefreshToken(user.getUserId());
userService.updateRefreshToken(user.getUserId(), refreshToken);
return TokenResponse.of(user.getUserId(), accessToken, refreshToken);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,29 @@
import org.festimate.team.api.festival.dto.FestivalVerifyResponse;
import org.festimate.team.global.response.ApiResponse;
import org.festimate.team.global.response.ResponseBuilder;
import org.festimate.team.infra.jwt.JwtService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/v1/festivals")
@RequiredArgsConstructor
public class FestivalController {
private final JwtService jwtService;
private final FestivalFacade festivalFacade;

@PostMapping("/verify")
public ResponseEntity<ApiResponse<FestivalVerifyResponse>> verifyFestival(
@RequestHeader("Authorization") String accessToken,
@RequestAttribute("userId") Long userId,
@RequestBody FestivalVerifyRequest request
) {
Long userId = jwtService.parseTokenAndGetUserId(accessToken);
FestivalVerifyResponse response = festivalFacade.verifyFestival(userId, request);
return ResponseBuilder.ok(response);
}

@GetMapping("/{festivalId}")
public ResponseEntity<ApiResponse<FestivalInfoResponse>> getFestivalInfo(
@RequestHeader("Authorization") String accessToken,
@RequestAttribute("userId") Long userId,
@PathVariable("festivalId") Long festivalId
) {
Long userId = jwtService.parseTokenAndGetUserId(accessToken);
FestivalInfoResponse response = festivalFacade.getFestivalInfo(userId, festivalId);
return ResponseBuilder.ok(response);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import org.festimate.team.api.matching.dto.MatchingStatusResponse;
import org.festimate.team.global.response.ApiResponse;
import org.festimate.team.global.response.ResponseBuilder;
import org.festimate.team.infra.jwt.JwtService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

Expand All @@ -16,38 +15,31 @@
@RequiredArgsConstructor
public class MatchingController {
private final MatchingFacade matchingFacade;
private final JwtService jwtService;

@PostMapping("/{festivalId}/matchings")
public ResponseEntity<ApiResponse<MatchingStatusResponse>> createMatching(
@RequestHeader("Authorization") String accessToken,
@RequestAttribute("userId") Long userId,
@PathVariable("festivalId") Long festivalId
) {
Long userId = jwtService.parseTokenAndGetUserId(accessToken);

MatchingStatusResponse response = matchingFacade.createMatching(userId, festivalId);
return ResponseBuilder.created(response);
}

@GetMapping("/{festivalId}/matchings")
public ResponseEntity<ApiResponse<MatchingListResponse>> getMatching(
@RequestHeader("Authorization") String accessToken,
@RequestAttribute("userId") Long userId,
@PathVariable("festivalId") Long festivalId
) {
Long userId = jwtService.parseTokenAndGetUserId(accessToken);

MatchingListResponse response = matchingFacade.getMatchingList(userId, festivalId);
return ResponseBuilder.ok(response);
}

@GetMapping("/{festivalId}/matchings/{matchingId}")
public ResponseEntity<ApiResponse<MatchingDetailInfo>> getMatchingDetail(
@RequestHeader("Authorization") String accessToken,
@RequestAttribute("userId") Long userId,
@PathVariable("festivalId") Long festivalId,
@PathVariable("matchingId") Long matchingId
) {
Long userId = jwtService.parseTokenAndGetUserId(accessToken);

MatchingDetailInfo response = matchingFacade.getMatchingDetail(userId, festivalId, matchingId);
return ResponseBuilder.ok(response);
}
Expand Down
Loading