Skip to content

Commit d4cc833

Browse files
Merge pull request #182 from prgrms-web-devcourse-final-project/develop
chore: develop → main 브랜치 머지
2 parents bdf8788 + 103fd77 commit d4cc833

37 files changed

+727
-196
lines changed

build.gradle

Lines changed: 63 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,113 @@
11
plugins {
2-
id 'java'
3-
id 'org.springframework.boot' version '3.5.3'
4-
id 'io.spring.dependency-management' version '1.1.7'
2+
id 'java'
3+
id 'org.springframework.boot' version '3.5.3'
4+
id 'io.spring.dependency-management' version '1.1.7'
55
}
66

77
group = 'grep'
88
version = '0.0.1-SNAPSHOT'
99

1010
java {
11-
toolchain {
12-
languageVersion = JavaLanguageVersion.of(21)
13-
}
11+
toolchain {
12+
languageVersion = JavaLanguageVersion.of(21)
13+
}
1414
}
1515

1616
// 공통 버전 정의
1717
ext {
18-
set('springCloudGcpVersion', "6.2.2")
19-
set('springCloudVersion', "2024.0.1")
18+
set('springCloudGcpVersion', "6.2.2")
19+
set('springCloudVersion', "2024.0.1")
2020
}
2121

2222
repositories {
23-
mavenCentral()
24-
google()
23+
mavenCentral()
24+
google()
2525
}
2626

2727
dependencies {
28-
// 데이터 베이스 의존성
29-
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
30-
runtimeOnly 'com.mysql:mysql-connector-j:8.4.0'
28+
// 데이터 베이스 의존성
29+
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
30+
runtimeOnly 'com.mysql:mysql-connector-j:8.4.0'
3131

32-
// Sql 쿼리 파라미터 보는 라이브러리
32+
// Sql 쿼리 파라미터 보는 라이브러리
3333
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0'
3434

3535
// 테스트 데이터베이스 의존성
36-
testImplementation 'com.h2database:h2:1.4.200'
36+
testImplementation 'com.h2database:h2:1.4.200'
3737

38-
// Querydsl 추가
39-
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
40-
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
41-
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
42-
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
38+
// Querydsl 추가
39+
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
40+
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
41+
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
42+
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
4343

44-
testImplementation 'org.springframework.boot:spring-boot-starter-test'
45-
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
44+
testImplementation 'org.springframework.boot:spring-boot-starter-test'
45+
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
4646

47-
// 테스트 의존성
48-
testImplementation 'org.springframework.boot:spring-boot-starter-test'
49-
testImplementation 'org.springframework.security:spring-security-test'
50-
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
47+
// 테스트 의존성
48+
testImplementation 'org.springframework.boot:spring-boot-starter-test'
49+
testImplementation 'org.springframework.security:spring-security-test'
50+
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
5151

52-
// 롬복
53-
compileOnly 'org.projectlombok:lombok:1.18.30'
54-
annotationProcessor 'org.projectlombok:lombok'
52+
// 롬복
53+
compileOnly 'org.projectlombok:lombok:1.18.30'
54+
annotationProcessor 'org.projectlombok:lombok'
5555

56-
// 웹 관련 의존성
57-
implementation 'org.springframework.boot:spring-boot-starter-web'
58-
implementation 'org.springframework.boot:spring-boot-starter-validation'
56+
// 웹 관련 의존성
57+
implementation 'org.springframework.boot:spring-boot-starter-web'
58+
implementation 'org.springframework.boot:spring-boot-starter-validation'
5959

60-
// lombok 의존성
61-
implementation "org.projectlombok:lombok:1.18.38"
60+
// lombok 의존성
61+
implementation "org.projectlombok:lombok:1.18.38"
6262

63-
// 시큐리티 의존성
64-
implementation 'org.springframework.boot:spring-boot-starter-security'
63+
// 시큐리티 의존성
64+
implementation 'org.springframework.boot:spring-boot-starter-security'
6565

66-
// Redis DB Cloud 의존성
67-
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
68-
implementation 'org.springframework.session:spring-session-data-redis'
66+
// Redis DB Cloud 의존성
67+
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
68+
implementation 'org.springframework.session:spring-session-data-redis'
6969

70-
//JWT 의존성
71-
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
72-
implementation 'io.jsonwebtoken:jjwt-impl:0.12.3'
73-
implementation 'io.jsonwebtoken:jjwt-jackson:0.12.3'
70+
//JWT 의존성
71+
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
72+
implementation 'io.jsonwebtoken:jjwt-impl:0.12.3'
73+
implementation 'io.jsonwebtoken:jjwt-jackson:0.12.3'
7474

75-
// OAuth2 의존성
76-
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
75+
// OAuth2 의존성
76+
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
7777

78-
// swagger
79-
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0'
78+
// swagger
79+
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0'
8080

81-
// gemini
82-
implementation 'dev.langchain4j:langchain4j-spring-boot-starter:1.0.0-beta3'
83-
implementation 'dev.langchain4j:langchain4j-google-ai-gemini-spring-boot-starter:1.0.0-beta3'
81+
// gemini
82+
implementation 'dev.langchain4j:langchain4j-spring-boot-starter:1.0.0-beta3'
83+
implementation 'dev.langchain4j:langchain4j-google-ai-gemini-spring-boot-starter:1.0.0-beta3'
8484

8585

86-
// 배포 관련 의존성
86+
// 배포 관련 의존성
8787
// runtimeOnly 'org.postgresql:postgresql'
88-
implementation 'org.springframework.boot:spring-boot-devtools'
89-
implementation 'com.google.cloud:spring-cloud-gcp-starter-secretmanager:4.9.1'
90-
implementation 'com.google.cloud:google-cloud-storage:2.38.0'
88+
implementation 'org.springframework.boot:spring-boot-devtools'
89+
implementation 'com.google.cloud:spring-cloud-gcp-starter-secretmanager:4.9.1'
90+
implementation 'com.google.cloud:google-cloud-storage:2.38.0'
9191

9292
// WebSocket + STOMP 통신용
9393
implementation 'org.springframework.boot:spring-boot-starter-websocket'
9494

95-
// 이메일 전송 의존성
96-
implementation 'org.springframework.boot:spring-boot-starter-mail'
95+
// 이메일 전송 의존성
96+
implementation 'org.springframework.boot:spring-boot-starter-mail'
9797
}
9898

9999
tasks.named('test') {
100-
useJUnitPlatform()
100+
useJUnitPlatform()
101101
}
102102

103103
dependencyManagement {
104-
imports {
105-
// Spring Cloud 전반 (Feign, Gateway 등) 의존성 버전 관리
106-
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
104+
imports {
105+
// Spring Cloud 전반 (Feign, Gateway 등) 의존성 버전 관리
106+
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
107107

108-
// GCP 관련 스타터(BOM) 관리 - Secret Manager, GCS 등
109-
mavenBom "com.google.cloud:spring-cloud-gcp-dependencies:${springCloudGcpVersion}"
110-
}
108+
// GCP 관련 스타터(BOM) 관리 - Secret Manager, GCS 등
109+
mavenBom "com.google.cloud:spring-cloud-gcp-dependencies:${springCloudGcpVersion}"
110+
}
111111
}
112112

113113
// 환경별 application.properties 포함/제외 설정

src/main/java/grep/neogul_coder/NeogulCoderApplication.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import jakarta.annotation.PostConstruct;
66
import org.springframework.boot.SpringApplication;
77
import org.springframework.boot.autoconfigure.SpringBootApplication;
8+
import org.springframework.scheduling.annotation.EnableScheduling;
89

10+
@EnableScheduling
911
@SpringBootApplication
1012
public class NeogulCoderApplication {
1113

src/main/java/grep/neogul_coder/domain/buddy/service/BuddyEnergyService.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,27 @@ public BuddyEnergyResponse updateEnergyByReview(Long userId, ReviewType reviewTy
4545
return BuddyEnergyResponse.from(energy);
4646
}
4747

48+
// 스터디 종료 시 +1, 리더면 +2
49+
@Transactional
50+
public BuddyEnergyResponse updateEnergyByStudy(Long userId, boolean isLeader) {
51+
BuddyEnergy energy = buddyEnergyRepository.findByUserId(userId)
52+
.orElseThrow(() -> new BuddyEnergyNotFoundException(BUDDY_ENERGY_NOT_FOUND));
53+
54+
int points = BuddyEnergyReason.STUDY_DONE.getPoint();
55+
BuddyEnergyReason reason = BuddyEnergyReason.STUDY_DONE;
56+
57+
if (isLeader) {
58+
points += BuddyEnergyReason.TEAM_LEADER_BONUS.getPoint();
59+
reason = BuddyEnergyReason.TEAM_LEADER_BONUS;
60+
}
61+
62+
energy.updateLevel(energy.getLevel() + points);
63+
buddyEnergyLogRepository.save(BuddyLog.of(energy, reason));
64+
buddyEnergyRepository.save(energy);
65+
66+
return BuddyEnergyResponse.from(energy);
67+
}
68+
4869
// 회원가입 시 기본 에너지 생성
4970
@Transactional
5071
public BuddyEnergyResponse createDefaultEnergy(Long userId) {

src/main/java/grep/neogul_coder/domain/calender/controller/TeamCalendarController.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@ public ApiResponse<List<TeamCalendarResponse>> findByDate(
5151
return ApiResponse.success(teamCalendarService.findByDate(studyId, parsedDate));
5252
}
5353

54+
// 특정 월(한 달 단위) 팀 일정 조회 API
55+
@GetMapping("/month")
56+
public ApiResponse<List<TeamCalendarResponse>> findByMonth(
57+
@AuthenticationPrincipal(expression = "userId") Long userId,
58+
@PathVariable("studyId") Long studyId,
59+
@RequestParam int year,
60+
@RequestParam int month
61+
) {
62+
return ApiResponse.success(teamCalendarService.findByMonth(studyId, year, month));
63+
}
64+
5465
// 팀 일정 수정 API - 본인이 작성한 일정만 수정 가능
5566
@PutMapping("/{teamCalendarId}")
5667
public ApiResponse<Void> update(

src/main/java/grep/neogul_coder/domain/calender/controller/TeamCalendarSpecification.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,23 @@ ApiResponse<List<TeamCalendarResponse>> findByDate(
4242
@RequestParam String date
4343
);
4444

45+
@Operation(
46+
summary = "팀 일정 월 단위 조회",
47+
description = "특정 팀의 특정 월(year, month)에 등록된 모든 일정을 조회합니다.\n\n" +
48+
"예: `/api/teams/{studyId}/calendar/month?year=2025&month=7`"
49+
)
50+
ApiResponse<List<TeamCalendarResponse>> findByMonth(
51+
@Parameter(hidden = true) @AuthenticationPrincipal Long userId,
52+
@Parameter(name = "studyId", description = "조회할 팀 ID", required = true, in = ParameterIn.PATH)
53+
@PathVariable("studyId") Long studyId,
54+
55+
@Parameter(name = "year", description = "조회할 연도 (예: 2025)", required = true, in = ParameterIn.QUERY)
56+
@RequestParam int year,
57+
58+
@Parameter(name = "month", description = "조회할 월 (1~12)", required = true, in = ParameterIn.QUERY)
59+
@RequestParam int month
60+
);
61+
4562

4663
@Operation(
4764
summary = "팀 일정 생성",

src/main/java/grep/neogul_coder/domain/calender/repository/TeamCalendarQueryRepository.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,20 @@ public List<TeamCalendar> findByStudyIdAndDate(Long studyId, LocalDateTime start
3939
)
4040
.fetch();
4141
}
42+
43+
// 특정 월 구간 조회
44+
public List<TeamCalendar> findByStudyIdAndMonth(Long studyId, LocalDateTime start, LocalDateTime end) {
45+
QTeamCalendar tc = QTeamCalendar.teamCalendar;
46+
47+
return queryFactory
48+
.selectFrom(tc)
49+
.join(tc.calendar, calendar).fetchJoin()
50+
.where(
51+
tc.studyId.eq(studyId),
52+
tc.activated.eq(true),
53+
calendar.scheduledStart.lt(end),
54+
calendar.scheduledEnd.goe(start)
55+
)
56+
.fetch();
57+
}
4258
}

src/main/java/grep/neogul_coder/domain/calender/service/TeamCalendarService.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ public List<TeamCalendarResponse> findByDate(Long studyId, LocalDate date) {
5858
.toList();
5959
}
6060

61+
// 특정 월(한 달 단위) 조회
62+
public List<TeamCalendarResponse> findByMonth(Long studyId, int year, int month) {
63+
LocalDate startOfMonth = LocalDate.of(year, month, 1);
64+
LocalDateTime start = startOfMonth.atStartOfDay();
65+
LocalDateTime end = startOfMonth.plusMonths(1).atStartOfDay();
66+
67+
return teamCalendarQueryRepository
68+
.findByStudyIdAndMonth(studyId, start, end).stream()
69+
.map(tc -> {
70+
User user = userService.get(tc.getUserId());
71+
return TeamCalendarResponse.from(tc, user);
72+
})
73+
.toList();
74+
}
75+
6176
@Transactional
6277
public Long create(Long studyId, Long userId, TeamCalendarRequest request) {
6378
validateRequest(request);

src/main/java/grep/neogul_coder/domain/recruitment/comment/controller/dto/response/CommentsWithWriterInfo.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ public class CommentsWithWriterInfo {
2323
@Schema(example = "www.s3.com", description = "회원 이미지 접근 URL")
2424
private String imageUrl;
2525

26+
@Schema(example = "3", description = "댓글 식별자")
27+
private long commentId;
28+
2629
@Schema(example = "참여 하고 싶습니다!", description = "댓글 내용")
2730
private String content;
2831

@@ -33,18 +36,19 @@ public class CommentsWithWriterInfo {
3336
private boolean activated;
3437

3538
@QueryProjection
36-
public CommentsWithWriterInfo(Long userId, String nickname, String imageUrl,
39+
public CommentsWithWriterInfo(Long userId, String nickname, String imageUrl, long commentId,
3740
String content, LocalDateTime createdAt, boolean activated) {
3841
this.userId = userId;
3942
this.nickname = nickname;
4043
this.imageUrl = imageUrl;
44+
this.commentId = commentId;
4145
this.content = content;
4246
this.createdAt = createdAt.toLocalDate();
4347
this.activated = activated;
4448
}
4549

4650
public CommentsWithWriterInfo updateNickName(String nickname) {
47-
return new CommentsWithWriterInfo(this.userId, nickname, this.imageUrl, this.content,
51+
return new CommentsWithWriterInfo(this.userId, nickname, this.imageUrl, this.commentId, this.content,
4852
LocalDateTime.of(this.createdAt, LocalTime.MIDNIGHT), this.activated);
4953
}
5054
}

src/main/java/grep/neogul_coder/domain/recruitment/comment/repository/RecruitmentPostCommentQueryRepository.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public List<CommentsWithWriterInfo> findCommentsWithWriterInfo(Long recruitmentP
3939
user.id,
4040
user.nickname,
4141
user.profileImageUrl.as("imageUrl"),
42+
recruitmentPostComment.id,
4243
recruitmentPostComment.content,
4344
recruitmentPostComment.createdDate,
4445
user.activated

src/main/java/grep/neogul_coder/domain/recruitment/comment/service/RecruitmentPostCommentService.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package grep.neogul_coder.domain.recruitment.comment.service;
22

3-
import grep.neogul_coder.domain.recruitment.RecruitmentErrorCode;
43
import grep.neogul_coder.domain.recruitment.comment.RecruitmentPostComment;
54
import grep.neogul_coder.domain.recruitment.comment.controller.dto.request.RecruitmentCommentSaveRequest;
65
import grep.neogul_coder.domain.recruitment.comment.controller.dto.request.RecruitmentCommentUpdateRequest;
@@ -13,7 +12,8 @@
1312
import org.springframework.stereotype.Service;
1413
import org.springframework.transaction.annotation.Transactional;
1514

16-
import static grep.neogul_coder.domain.recruitment.RecruitmentErrorCode.*;
15+
import static grep.neogul_coder.domain.recruitment.RecruitmentErrorCode.NOT_FOUND;
16+
import static grep.neogul_coder.domain.recruitment.RecruitmentErrorCode.NOT_FOUND_COMMENT;
1717

1818
@Transactional(readOnly = true)
1919
@RequiredArgsConstructor
@@ -26,10 +26,10 @@ public class RecruitmentPostCommentService {
2626

2727
@Transactional
2828
public long save(RecruitmentCommentSaveRequest request, long userId) {
29-
RecruitmentPost myPost = postRepository.findMyPostBy(request.getPostId(), userId)
29+
RecruitmentPost post = postRepository.findPostBy(request.getPostId())
3030
.orElseThrow(() -> new NotFoundException(NOT_FOUND));
3131

32-
return commentRepository.save(request.toEntity(myPost, userId)).getId();
32+
return commentRepository.save(request.toEntity(post, userId)).getId();
3333
}
3434

3535
@Transactional

0 commit comments

Comments
 (0)