Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] merge to main #303

Merged
merged 22 commits into from
Mar 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2b0622f
Merge pull request #119 from JNU-econovation/be
kssumin Nov 30, 2023
1f4d8ac
Merge pull request #123 from JNU-econovation/be
kssumin Nov 30, 2023
ec12667
Merge pull request #207 from JNU-econovation/be
kssumin Jan 11, 2024
5617911
Merge pull request #278 from JNU-econovation/be
kssumin Feb 22, 2024
709581d
feat : ํŒ€๋นŒ๋”ฉ ์‚ญ์ œ ์‹œ ๊ด€๋ จ ๋ฉค๋ฒ„๋“ค ์‚ญ์ œํ•˜๋Š” ์ด๋ฒคํŠธ ๋ฐœํ–‰
kssumin Feb 22, 2024
626cf3e
feat : ์ง„ํ–‰์ค‘์ธ ํŒ€๋นŒ๋”ฉ ์‚ญ์ œ ๊ตฌํ˜„
kssumin Feb 22, 2024
d8ccec0
refactor : ํŒ€๋นŒ๋”ฉ ์ข…๋ฃŒ์‹œํ‚ค๋Š” usecase ๋ฉ”์„œ๋“œ๋ช… ๋ณ€๊ฒฝ
kssumin Feb 22, 2024
552e4a3
feat : ํŒ€๋นŒ๋”ฉ ์‚ญ์ œ์‹œํ‚ค๋Š” api ๊ตฌํ˜„
kssumin Feb 22, 2024
c0255b1
Merge pull request #280 from kssumin/feat/#279/delete-team-building
kssumin Feb 22, 2024
1101692
feat : ๋ณ„๋„์˜ ํŠธ๋žœ์ ์…˜์œผ๋กœ ์‹คํ–‰ํ•˜๋„๋ก ํŠธ๋žœ์ ์…˜ ๋ถ„๋ฆฌ
kssumin Feb 22, 2024
6f1d536
Merge pull request #282 from kssumin/feat/#279/delete-team-building
Hyeonz1 Feb 22, 2024
d0898f9
docs : readme ์ ์šฉํ•˜๊ธฐ
kssumin Feb 28, 2024
f5d6fe2
docs : readme ๋ฌธ์„œ ์ค„๋ฐ”๊ฟˆ ์„ค์ •ํ•˜๊ธฐ
kssumin Feb 28, 2024
aa993f0
Merge pull request #292 from kssumin/main
kssumin Feb 28, 2024
85acd26
fix : chmod ๋ช…๋ น์„ ์‹คํ–‰(Execution) ๋‹จ๊ณ„์—์„œ ์‹คํ–‰ํ•˜๋„๋ก ๋ณ€๊ฒฝํ•œ๋‹ค.
kssumin Mar 1, 2024
68595a0
fix : given์—์„œ ์ง„ํ–‰์ค‘์ธ ํŒ€๋นŒ๋”ฉ์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋„๋ก ๋ณ€๊ฒฝ
kssumin Mar 1, 2024
6841161
Merge pull request #66 from kssumin/fix/#297/git-hooks
kssumin Mar 1, 2024
6d95c06
Merge pull request #299 from kssumin/main
kssumin Mar 1, 2024
5180860
feat : cacheControl์„ ํ†ตํ•ด cache๋ฅผ ์ง€์ •
kssumin Mar 3, 2024
d94afc2
feat : ETag ์ ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ ์œ ๋ฌด ํ™•์ธ
kssumin Mar 3, 2024
6f932fe
Merge pull request #67 from kssumin/feat/#286/cache
kssumin Mar 3, 2024
2464338
Merge pull request #302 from kssumin/main
kssumin Mar 3, 2024
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
28 changes: 28 additions & 0 deletions BE/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## TechStack

| ์นดํ…Œ๊ณ ๋ฆฌ | ๊ธฐ์ˆ  |
| --- | --- |
| Language, Framework | Java, Spring Boot |
| Database | MySQL, Redis, Flyway |
| ORM | Spring Data JPA, QueryDSL |
| ์šด์˜ ํ™˜๊ฒฝ ๊ตฌ์ถ• | ECR, ECS, EC2, Docker |
| Build | Gradle |
| CI/CD | Github Actions |
| library | Spring Open Feign, OAuth 2.0 |

## docs
[์„œ๋ธŒ ๋„๋ฉ”์ธ ์ ์šฉํ•˜๊ธฐ](https://velog.io/@kssumin/%EC%84%9C%EB%B8%8C-%EB%8F%84%EB%A9%94%EC%9D%B8-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0)

[ํƒ€์ž„์กด ์„ค์ •](https://velog.io/@kssumin/DB%EC%97%90-%EB%93%A4%EC%96%B4%EA%B0%80%EB%8A%94-%EC%8B%9C%EA%B0%84%EC%9D%B4-%EC%9D%B4%EC%83%81%ED%95%98%EB%8B%A4)

[๋ถ„๊ธฐ ์ฒ˜๋ฆฌ ์ฝ”๋“œ ๋ฆฌํŒฉํ„ฐ๋งํ•˜๊ธฐ](https://velog.io/@kssumin/%EB%B6%84%EA%B8%B0%EC%B2%98%EB%A6%AC-%EC%BD%94%EB%93%9C-%EB%A6%AC%ED%8C%A9%ED%84%B0%EB%A7%81-%ED%95%98%EA%B8%B0)

[์Šฌ๋ž™ API ํ˜ธ์ถœ ์ฝ”๋“œ๋ฅผ ์ถ”์ƒํ™”ํ•˜๊ธฐ](https://velog.io/@kssumin/%EC%8A%AC%EB%9E%99-API-%ED%98%B8%EC%B6%9C-%EC%BD%94%EB%93%9C%EB%A5%BC-%EC%B6%94%EC%83%81%ED%99%94%ED%95%98%EA%B8%B0)

[200 status code๋งŒ ์‚ฌ์šฉํ•˜์ง€ ๋ง์ž](https://velog.io/@kssumin/EEOS-%EC%BA%90%EC%8B%B1)

## ์‹คํ–‰๋ฐฉ๋ฒ•
1. git clone
2. ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค.(env.properties)
3. docker-compose๋ฅผ ํ†ตํ•ด db๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
4. spring boot๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.blackcompany.eeos.config;

import java.util.concurrent.TimeUnit;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.WebContentInterceptor;

@Configuration
public class CacheWebConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(final InterceptorRegistry registry) {
CacheControl cacheControl = CacheControl.maxAge(60, TimeUnit.SECONDS);

WebContentInterceptor interceptor = new WebContentInterceptor();
interceptor.addCacheMapping(cacheControl, "/api/**");

registry.addInterceptor(interceptor);
}
}
18 changes: 18 additions & 0 deletions BE/eeos/src/main/java/com/blackcompany/eeos/config/EtagConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.blackcompany.eeos.config;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.ShallowEtagHeaderFilter;

@Configuration
public class EtagConfig {
@Bean
public FilterRegistrationBean<ShallowEtagHeaderFilter> shallowEtagHeaderFilter() {
FilterRegistrationBean<ShallowEtagHeaderFilter> filterRegistrationBean =
new FilterRegistrationBean<>(new ShallowEtagHeaderFilter());
filterRegistrationBean.addUrlPatterns("/api/*");

return filterRegistrationBean;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
Expand All @@ -17,6 +18,7 @@ public class QueryTeamBuildingTargetService {
private final TeamBuildingTargetRepository teamBuildingTargetRepository;
private final TeamBuildingTargetEntityConverter entityConverter;

@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public TeamBuildingTargetModel getTarget(Long memberId, Long teamBuildingId) {
return teamBuildingTargetRepository
.findByTeamBuildingIdAndMemberId(teamBuildingId, memberId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ Optional<TeamBuildingTargetEntity> findByTeamBuildingIdAndMemberId(
Long teamBuildingId, Long memberId);

List<TeamBuildingTargetEntity> findByTeamBuildingId(Long teamBuildingId);

void deleteByTeamBuildingId(Long teamBuildingId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.blackcompany.eeos.teamBuilding.application.event;

import lombok.Getter;

@Getter
public class DeletedTeamBuildingEvent {
private final Long teamBuildingId;

private DeletedTeamBuildingEvent(Long teamBuildingId) {
this.teamBuildingId = teamBuildingId;
}

/**
* ํŒ€๋นŒ๋”ฉ ์‚ญ์ œ ์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
*
* <p>์ด๋ฒคํŠธ ์ƒ์„ฑ์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์„œ๋น„์Šค ๋กœ์ง์— ์˜ํ–ฅ์„ ์ฃผ๋ฏ€๋กœ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ์—์„œ ํ•ธ๋“ค๋ง์„ ํ•  ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋‹ค.
*
* @param teamBuildingId ์‚ญ์ œ๋œ ํŒ€๋นŒ๋”ฉ ์ •๋ณด
* @return
*/
public static DeletedTeamBuildingEvent of(Long teamBuildingId) {
return new DeletedTeamBuildingEvent(teamBuildingId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.blackcompany.eeos.teamBuilding.application.event;

import com.blackcompany.eeos.target.persistence.TeamBuildingTargetRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
import org.springframework.transaction.support.TransactionSynchronizationManager;

@Component
@RequiredArgsConstructor
@Slf4j
public class DeletedTeamBuildingEventListener {
private final TeamBuildingTargetRepository teamBuildingTargetRepository;

@Async
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void handleDeletedTeamBuilding(DeletedTeamBuildingEvent event) {
log.info(
"ํŒ€๋นŒ๋”ฉ ์‚ญ์ œ Transaction committed: {}",
TransactionSynchronizationManager.isActualTransactionActive());
teamBuildingTargetRepository.deleteByTeamBuildingId(event.getTeamBuildingId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.blackcompany.eeos.teamBuilding.application.dto.EachMemberResponse;
import com.blackcompany.eeos.teamBuilding.application.dto.ResultTeamBuildingResponse;
import com.blackcompany.eeos.teamBuilding.application.dto.converter.ResultTeamBuildingResponseConverter;
import com.blackcompany.eeos.teamBuilding.application.event.DeletedTeamBuildingEvent;
import com.blackcompany.eeos.teamBuilding.application.exception.CompleteTeamBuildingException;
import com.blackcompany.eeos.teamBuilding.application.exception.EndTeamBuildingException;
import com.blackcompany.eeos.teamBuilding.application.exception.NotFoundProgressTeamBuildingException;
Expand All @@ -20,6 +21,7 @@
import com.blackcompany.eeos.teamBuilding.application.model.converter.TeamBuildingResultConverter;
import com.blackcompany.eeos.teamBuilding.application.usecase.CompleteTeamBuildingUsecase;
import com.blackcompany.eeos.teamBuilding.application.usecase.CreateTeamBuildingUsecase;
import com.blackcompany.eeos.teamBuilding.application.usecase.DeleteTeamBuildingUsecase;
import com.blackcompany.eeos.teamBuilding.application.usecase.EndTeamBuildingUsecase;
import com.blackcompany.eeos.teamBuilding.application.usecase.GetResultTeamBuildingUsecase;
import com.blackcompany.eeos.teamBuilding.application.usecase.GetTeamBuildingUsecase;
Expand All @@ -35,6 +37,7 @@
import java.util.function.Supplier;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -46,7 +49,8 @@ public class TeamBuildingService
EndTeamBuildingUsecase,
CompleteTeamBuildingUsecase,
GetResultTeamBuildingUsecase,
GetTeamBuildingUsecase {
GetTeamBuildingUsecase,
DeleteTeamBuildingUsecase {
private final RestrictTeamBuildingService restrictTeamBuildingService;
private final TeamBuildingRequestConverter requestConverter;
private final TeamBuildingEntityConverter entityConverter;
Expand All @@ -60,6 +64,7 @@ public class TeamBuildingService
private final TeamBuildingResultConverter teamBuildingResultConverter;
private final MemberRepository memberRepository;
private final ResultTeamBuildingResponseConverter responseConverter;
private final ApplicationEventPublisher publisher;

@Override
@Transactional
Expand All @@ -74,7 +79,7 @@ public void create(Long memberId, CreateTeamBuildingRequest request) {

@Override
@Transactional
public void delete(Long memberId) {
public void end(Long memberId) {
TeamBuildingStatus status = TeamBuildingStatus.COMPLETE;

TeamBuildingModel model =
Expand Down Expand Up @@ -135,6 +140,24 @@ public QueryTeamBuildingResponse getTeamBuilding(Long memberId) {
.build();
}

@Override
@Transactional
public void delete(Long memberId) {
TeamBuildingStatus status = TeamBuildingStatus.PROGRESS;

TeamBuildingModel model =
teamBuildingRepository
.findByStatus(status)
.map(entityConverter::from)
.orElseThrow(() -> new NotFoundTeamBuildingStatusException(status.getStatus()));

model.validateEdit(memberId);

teamBuildingRepository.delete(entityConverter.toEntity(model));
restrictTeamBuildingService.subtractTeamBuilding();
publisher.publishEvent(DeletedTeamBuildingEvent.of(model.getId()));
}

private List<List<EachMemberResponse>> combines(
List<List<MemberEntity>> members, List<List<Long>> memberIds) {
return members.stream()
Expand Down Expand Up @@ -191,8 +214,7 @@ private void validateReadAccessibility(Long memberId, Long programId) {
generateNotFoundProgressTeamBuildingException() {
if (teamBuildingRepository.existsByStatus(TeamBuildingStatus.COMPLETE)) {
return CompleteTeamBuildingException::new;
} else {
return EndTeamBuildingException::new;
}
return EndTeamBuildingException::new;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.blackcompany.eeos.teamBuilding.application.usecase;

public interface DeleteTeamBuildingUsecase {
/**
* ํŒ€๋นŒ๋”ฉ ์™„๋ฃŒ๋ฅผ ์š”์ฒญํ•œ๋‹ค.
*
* @param memberId ํŒ€๋นŒ๋”ฉ ์ž‘์„ฑ์ž
*/
void delete(Long memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ public interface EndTeamBuildingUsecase {
*
* @param memberId ํŒ€๋นŒ๋”ฉ ์ž‘์„ฑ์ž
*/
void delete(Long memberId);
void end(Long memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.blackcompany.eeos.teamBuilding.application.dto.ValidateTeamBuildingResponse;
import com.blackcompany.eeos.teamBuilding.application.usecase.CompleteTeamBuildingUsecase;
import com.blackcompany.eeos.teamBuilding.application.usecase.CreateTeamBuildingUsecase;
import com.blackcompany.eeos.teamBuilding.application.usecase.DeleteTeamBuildingUsecase;
import com.blackcompany.eeos.teamBuilding.application.usecase.EndTeamBuildingUsecase;
import com.blackcompany.eeos.teamBuilding.application.usecase.GetResultTeamBuildingUsecase;
import com.blackcompany.eeos.teamBuilding.application.usecase.GetTeamBuildingUsecase;
Expand All @@ -36,6 +37,7 @@ public class TeamBuildingController {
private final CompleteTeamBuildingUsecase completeTeamBuildingUsecase;
private final GetResultTeamBuildingUsecase getResultTeamBuildingUsecase;
private final GetTeamBuildingUsecase getTeamBuildingUsecase;
private final DeleteTeamBuildingUsecase deleteTeamBuildingUsecase;

@PostMapping
public ApiResponse<SuccessBody<Void>> create(
Expand All @@ -46,7 +48,7 @@ public ApiResponse<SuccessBody<Void>> create(

@DeleteMapping("/end")
public ApiResponse<SuccessBody<Void>> end(@Member Long memberId) {
endTeamBuildingUsecase.delete(memberId);
endTeamBuildingUsecase.end(memberId);
return ApiResponseGenerator.success(HttpStatus.OK, MessageCode.DELETE);
}

Expand Down Expand Up @@ -75,4 +77,10 @@ public ApiResponse<SuccessBody<QueryTeamBuildingResponse>> getTeamBuilding(
QueryTeamBuildingResponse response = getTeamBuildingUsecase.getTeamBuilding(memberId);
return ApiResponseGenerator.success(response, HttpStatus.OK, MessageCode.GET);
}

@DeleteMapping
public ApiResponse<SuccessBody<Void>> deleteTeamBuilding(@Member Long memberId) {
deleteTeamBuildingUsecase.delete(memberId);
return ApiResponseGenerator.success(HttpStatus.OK, MessageCode.DELETE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ void save_team_building() {
@DisplayName("์ง„ํ–‰ ์ค‘์ธ ํŒ€๋นŒ๋”ฉ์˜ ์ž‘์„ฑ์ž๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์ˆ˜์ • ๊ถŒํ•œ์ด ์—†์Œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.")
void denied_edit_team_building() {
// given
TeamBuildingEntity ์ƒ์„ฑ๋œ_ํŒ€๋นŒ๋”ฉ = TeamBuildingFixture.ํŒ€๋นŒ๋”ฉ(TeamBuildingStatus.COMPLETE, 1L);
when(teamBuildingRepository.findByStatus(TeamBuildingStatus.COMPLETE))
TeamBuildingEntity ์ƒ์„ฑ๋œ_ํŒ€๋นŒ๋”ฉ = TeamBuildingFixture.ํŒ€๋นŒ๋”ฉ(TeamBuildingStatus.PROGRESS, 1L);
when(teamBuildingRepository.findByStatus(TeamBuildingStatus.PROGRESS))
.thenReturn(Optional.of(์ƒ์„ฑ๋œ_ํŒ€๋นŒ๋”ฉ));

// when & then
Expand Down
6 changes: 4 additions & 2 deletions BE/eeos/tasks/install-git-hooks.gradle
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
tasks.create(name: 'gitExecutableHooks') {
Runtime.getRuntime().exec("chmod -R +x ../../.git/hooks/");
doLast {
Runtime.getRuntime().exec("chmod -R +x ../../.git/hooks/")
}
}

task installGitHooks(type: Copy) {
String scriptDir = rootProject.rootDir.toString() + '/scripts'
from new File(scriptDir, 'pre-commit')
into { new File(rootProject.rootDir, '../../.git/hooks') }
into { new File(rootProject.rootDir, '.git/hooks') }
}

gitExecutableHooks.dependsOn installGitHooks
Expand Down
Loading