Skip to content

Commit 9667f7c

Browse files
authored
v1.1.1
v1.1.1
2 parents 53723f3 + 5e39ac6 commit 9667f7c

File tree

51 files changed

+969
-365
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+969
-365
lines changed

.github/workflows/aws-cicd-dev.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ on:
44
push:
55
branches:
66
- develop
7-
- feat/LA-20_3
7+
pull_request:
8+
branches:
9+
- develop
810

911
env:
1012
REGISTRY: "docker.io"
@@ -127,6 +129,7 @@ jobs:
127129
name: Deploy
128130
needs: [ build, setup ]
129131
runs-on: ubuntu-latest
132+
if: github.event_name != 'pull_request'
130133
env:
131134
DEPLOY_TARGET: ${{ needs.setup.outputs.deploy_target }}
132135

.github/workflows/aws-cicd-prod.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ on:
44
push:
55
branches:
66
- main
7+
pull_request:
8+
branches:
9+
- main
710

811
env:
912
REGISTRY: "docker.io"
@@ -127,6 +130,7 @@ jobs:
127130
name: Deploy
128131
needs: [ build, setup ]
129132
runs-on: ubuntu-latest
133+
if: github.event_name != 'pull_request'
130134
env:
131135
DEPLOY_TARGET: ${{ needs.setup.outputs.deploy_target }}
132136

.gitignore

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ out/
4747
#*.properties
4848

4949

50-
*.sql
51-
50+
layer-api/src/main/resources/data.sql
5251
layer-domain/src/main/generated
5352

5453

@@ -58,4 +57,8 @@ credentials.json
5857

5958
layer-api/src/main/resources/tokens/StoredCredential
6059
layer-batch/src/main/resources/application-secret.properties
61-
layer-admin/src/main/resources/application-secret.properties
60+
layer-admin/src/main/resources/application-secret.properties
61+
layer-admin/src/main/resources/application.yml
62+
layer-admin/src/main/resources/data.sql
63+
64+

build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ project(":layer-api") {
6868

6969
implementation 'org.springframework.boot:spring-boot-starter-actuator'
7070
implementation 'org.springframework.boot:spring-boot-starter-validation'
71+
implementation 'org.springframework.boot:spring-boot-starter-web'
7172

7273
//== jwt ==//
7374
implementation 'io.jsonwebtoken:jjwt-api:0.12.5'
@@ -201,6 +202,7 @@ project(":layer-admin") {
201202

202203
dependencies {
203204
implementation project(path: ':layer-domain')
205+
implementation project(path: ':layer-common')
204206

205207
implementation 'org.springframework.boot:spring-boot-starter-web'
206208
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
@@ -211,6 +213,9 @@ project(":layer-admin") {
211213

212214
// Security
213215
implementation 'org.springframework.boot:spring-boot-starter-security'
216+
217+
// redis
218+
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
214219
}
215220

216221
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.layer.common.exception;
2+
3+
public class AdminException extends BaseCustomException {
4+
public AdminException(ExceptionType exceptionType) {
5+
super(exceptionType);
6+
}
7+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package org.layer.config;
2+
3+
import com.fasterxml.jackson.databind.DeserializationFeature;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.fasterxml.jackson.databind.SerializationFeature;
6+
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
7+
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
8+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
9+
import org.springframework.beans.factory.annotation.Value;
10+
import org.springframework.context.annotation.Bean;
11+
import org.springframework.context.annotation.Configuration;
12+
import org.springframework.data.redis.connection.RedisConnectionFactory;
13+
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
14+
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
15+
import org.springframework.data.redis.core.RedisTemplate;
16+
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
17+
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
18+
import org.springframework.data.redis.serializer.StringRedisSerializer;
19+
20+
21+
@Configuration
22+
@EnableRedisRepositories
23+
public class RedisConfig {
24+
@Value("${spring.data.redis.host}")
25+
private String host;
26+
27+
@Value("${spring.data.redis.port}")
28+
private int port;
29+
30+
@Value("${spring.data.redis.password}")
31+
private String password;
32+
33+
// prod에서 최근 서비스 이용 시점 기록 - 1번 데이터베이스
34+
@Bean
35+
public RedisConnectionFactory redisConnectionFactory() {
36+
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
37+
redisStandaloneConfiguration.setHostName(host);
38+
redisStandaloneConfiguration.setPort(port);
39+
redisStandaloneConfiguration.setDatabase(1); // 1번 데이터베이스
40+
41+
return new LettuceConnectionFactory(redisStandaloneConfiguration);
42+
43+
}
44+
45+
@Bean
46+
public RedisTemplate<String, Object> redisTemplate() {
47+
RedisTemplate<String, Object> template = new RedisTemplate<>();
48+
template.setConnectionFactory(redisConnectionFactory());
49+
50+
PolymorphicTypeValidator typeValidator = BasicPolymorphicTypeValidator
51+
.builder()
52+
.allowIfSubType(Object.class)
53+
.build();
54+
55+
ObjectMapper objectMapper = new ObjectMapper()
56+
.findAndRegisterModules()
57+
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
58+
.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false)
59+
.activateDefaultTyping(typeValidator, ObjectMapper.DefaultTyping.NON_FINAL)
60+
.registerModule(new JavaTimeModule());
61+
62+
template.setKeySerializer(new StringRedisSerializer());
63+
template.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));
64+
65+
return template;
66+
}
67+
68+
}

layer-admin/src/main/java/org/layer/member/controller/dto/GetMemberActivityResponse.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
package org.layer.member.controller.dto;
22

3-
import java.time.LocalDateTime;
4-
53
import io.swagger.v3.oas.annotations.media.Schema;
64
import jakarta.validation.constraints.NotNull;
75

6+
import java.time.LocalDateTime;
7+
88
@Schema(name = "GetMemberActivityResponse", description = "회원 활동 Dto")
99
public record GetMemberActivityResponse(
1010
@NotNull
1111
@Schema(description = "회원 이름", example = "홍길동")
1212
String name,
1313
@NotNull
14-
@Schema(description = "최근 활동 날짜", example = "2024-11-30T16:21:47.031Z")
14+
@Schema(description = "최근 활동 날짜, 최근 6개월 동안 접속 없을 시 null", example = "2024-11-30T16:21:47.031Z")
1515
LocalDateTime recentActivityDate,
1616
@NotNull
1717
@Schema(description = "소속된 스페이스 수", example = "7")

layer-admin/src/main/java/org/layer/member/service/AdminMemberService.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package org.layer.member.service;
22

3-
import java.util.List;
3+
import lombok.RequiredArgsConstructor;
44

5+
import org.layer.common.dto.RecentActivityDto;
56
import org.layer.domain.answer.repository.AdminAnswerRepository;
67
import org.layer.domain.member.entity.Member;
78
import org.layer.domain.member.repository.AdminMemberRepository;
@@ -11,10 +12,11 @@
1112
import org.springframework.beans.factory.annotation.Value;
1213
import org.springframework.data.domain.Page;
1314
import org.springframework.data.domain.PageRequest;
15+
import org.springframework.data.redis.core.RedisTemplate;
1416
import org.springframework.stereotype.Service;
1517
import org.springframework.transaction.annotation.Transactional;
1618

17-
import lombok.RequiredArgsConstructor;
19+
import java.util.List;
1820

1921
@Service
2022
@RequiredArgsConstructor
@@ -23,6 +25,7 @@ public class AdminMemberService {
2325
private final AdminMemberRepository adminMemberRepository;
2426
private final AdminMemberSpaceRelationRepository adminMemberSpaceRelationRepository;
2527
private final AdminAnswerRepository adminAnswerRepository;
28+
private final RedisTemplate<String, Object> redisTemplate;
2629

2730
@Value("${admin.password}")
2831
private String password;
@@ -43,8 +46,12 @@ public GetMembersActivitiesResponse getMemberActivities(String password, int pag
4346
Long spaceCount = adminMemberSpaceRelationRepository.countAllByMemberId(member.getId());
4447
Long retrospectAnswerCount = adminAnswerRepository.countAllByMemberId(member.getId());
4548

46-
return new GetMemberActivityResponse(member.getName(), null, spaceCount, retrospectAnswerCount,
47-
member.getCreatedAt(), member.getSocialType().name());
49+
RecentActivityDto recentActivityDto = (RecentActivityDto)redisTemplate.opsForValue()
50+
.get(Long.toString(member.getId()));
51+
52+
return new GetMemberActivityResponse(member.getName(),
53+
recentActivityDto == null ? null : recentActivityDto.getRecentActivityDate(),
54+
spaceCount, retrospectAnswerCount, member.getCreatedAt(), member.getSocialType().name());
4855
}).toList();
4956

5057
return new GetMembersActivitiesResponse(responses);
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.layer.retrospect.controller;
2+
3+
import io.swagger.v3.oas.annotations.Operation;
4+
import io.swagger.v3.oas.annotations.Parameter;
5+
import io.swagger.v3.oas.annotations.Parameters;
6+
import io.swagger.v3.oas.annotations.media.Schema;
7+
import io.swagger.v3.oas.annotations.tags.Tag;
8+
import org.layer.domain.retrospect.dto.AdminRetrospectCountGroupBySpaceGetResponse;
9+
import org.layer.retrospect.controller.dto.AdminRetrospectCountGetResponse;
10+
import org.layer.retrospect.controller.dto.AdminRetrospectsGetResponse;
11+
import org.springframework.http.ResponseEntity;
12+
import org.springframework.web.bind.annotation.RequestParam;
13+
14+
import java.time.LocalDateTime;
15+
import java.util.List;
16+
17+
@Tag(name = "[ADMIN] 회고 데이터", description = "회고 관련 api")
18+
public interface AdminRetrospectApi {
19+
20+
21+
@Operation(summary = "회고 관련 데이터 조회", description = "")
22+
@Parameters({
23+
@Parameter(name = "startDate", description = "검색 시작 시간", example = "2024-09-05T15:30:45", required = true, schema = @Schema(type = "string")),
24+
@Parameter(name = "endDate", description = "검색 종료 시간", example = "2024-09-13T15:30:45", required = true, schema = @Schema(type = "string")),
25+
@Parameter(name = "password", description = "비밀번호 [카톡방으로 공유]", example = "[카톡방으로 공유]", required = true, schema = @Schema(type = "string", format = "string"))})
26+
ResponseEntity<AdminRetrospectsGetResponse> getRetrospectData(@RequestParam("startDate") LocalDateTime startDate,
27+
@RequestParam("endDate") LocalDateTime endDate, @RequestParam("password") String password);
28+
29+
@Operation(summary = "회고 개수 조회", description = "특정 기간내에 시작된 회고 개수를 조회합니다. (우리 팀원이 만든 스페이스에서 진행된 회고는 제외)")
30+
@Parameters({
31+
@Parameter(name = "startDate", description = "검색 시작 시간", example = "2024-09-05T15:30:45", required = true, schema = @Schema(type = "string")),
32+
@Parameter(name = "endDate", description = "검색 종료 시간", example = "2024-09-13T15:30:45", required = true, schema = @Schema(type = "string")),
33+
@Parameter(name = "password", description = "비밀번호 [카톡방으로 공유]", example = "[카톡방으로 공유]", required = true, schema = @Schema(type = "string", format = "string"))})
34+
ResponseEntity<AdminRetrospectCountGetResponse> getRetrospectCount(@RequestParam("startDate") LocalDateTime startDate,
35+
@RequestParam("endDate") LocalDateTime endDate, @RequestParam("password") String password);
36+
37+
@Operation(summary = "특정 기간 내 회고 개수 스페이스 별로 보기", description = "특정 기간내에 시작된 회고 개수를 스페이스 별로 조회합니다. (우리 팀원이 만든 스페이스는 제외)")
38+
@Parameters({
39+
@Parameter(name = "startDate", description = "검색 시작 시간", example = "2024-09-05T15:30:45", required = true, schema = @Schema(type = "string")),
40+
@Parameter(name = "endDate", description = "검색 종료 시간", example = "2024-09-13T15:30:45", required = true, schema = @Schema(type = "string")),
41+
@Parameter(name = "password", description = "비밀번호 [카톡방으로 공유]", example = "[카톡방으로 공유]", required = true, schema = @Schema(type = "string", format = "string"))})
42+
ResponseEntity<List<AdminRetrospectCountGroupBySpaceGetResponse>> getRetrospectCountGroupBySpace (@RequestParam("startDate") LocalDateTime startDate,
43+
@RequestParam("endDate") LocalDateTime endDate,
44+
@RequestParam("password") String password);
45+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package org.layer.retrospect.controller;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import org.layer.domain.retrospect.dto.AdminRetrospectCountGroupBySpaceGetResponse;
5+
import org.layer.retrospect.controller.dto.AdminRetrospectCountGetResponse;
6+
import org.layer.retrospect.controller.dto.AdminRetrospectsGetResponse;
7+
import org.layer.retrospect.service.AdminRetrospectService;
8+
import org.springframework.http.ResponseEntity;
9+
import org.springframework.web.bind.annotation.*;
10+
11+
import java.time.LocalDateTime;
12+
import java.util.List;
13+
14+
@RequestMapping("/retrospect")
15+
@RequiredArgsConstructor
16+
@RestController
17+
public class AdminRetrospectController implements AdminRetrospectApi {
18+
private final AdminRetrospectService adminRetrospectService;
19+
20+
@Override
21+
@GetMapping
22+
public ResponseEntity<AdminRetrospectsGetResponse> getRetrospectData(
23+
@RequestParam("startDate") LocalDateTime startDate,
24+
@RequestParam("endDate") LocalDateTime endDate,
25+
@RequestParam("password") String password) {
26+
27+
return ResponseEntity.ok(adminRetrospectService.getRetrospectData(startDate, endDate, password));
28+
}
29+
30+
@Override
31+
@GetMapping("/count/user-only")
32+
public ResponseEntity<AdminRetrospectCountGetResponse> getRetrospectCount(
33+
@RequestParam("startDate") LocalDateTime startDate,
34+
@RequestParam("endDate") LocalDateTime endDate,
35+
@RequestParam("password") String password) {
36+
37+
return ResponseEntity.ok(adminRetrospectService.getRetrospectCount(startDate, endDate, password));
38+
}
39+
40+
@Override
41+
@GetMapping("/count/group-by-space")
42+
public ResponseEntity<List<AdminRetrospectCountGroupBySpaceGetResponse>> getRetrospectCountGroupBySpace(LocalDateTime startDate, LocalDateTime endDate, String password) {
43+
return ResponseEntity.ok(adminRetrospectService.getRetrospectCountGroupSpace(startDate, endDate, password));
44+
}
45+
46+
}

0 commit comments

Comments
 (0)