Skip to content

Commit

Permalink
v1.1.1
Browse files Browse the repository at this point in the history
v1.1.1
  • Loading branch information
mikekks authored Dec 30, 2024
2 parents 53723f3 + 5e39ac6 commit 9667f7c
Show file tree
Hide file tree
Showing 51 changed files with 969 additions and 365 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/aws-cicd-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ on:
push:
branches:
- develop
- feat/LA-20_3
pull_request:
branches:
- develop

env:
REGISTRY: "docker.io"
Expand Down Expand Up @@ -127,6 +129,7 @@ jobs:
name: Deploy
needs: [ build, setup ]
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
env:
DEPLOY_TARGET: ${{ needs.setup.outputs.deploy_target }}

Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/aws-cicd-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ on:
push:
branches:
- main
pull_request:
branches:
- main

env:
REGISTRY: "docker.io"
Expand Down Expand Up @@ -127,6 +130,7 @@ jobs:
name: Deploy
needs: [ build, setup ]
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
env:
DEPLOY_TARGET: ${{ needs.setup.outputs.deploy_target }}

Expand Down
9 changes: 6 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ out/
#*.properties


*.sql

layer-api/src/main/resources/data.sql
layer-domain/src/main/generated


Expand All @@ -58,4 +57,8 @@ credentials.json

layer-api/src/main/resources/tokens/StoredCredential
layer-batch/src/main/resources/application-secret.properties
layer-admin/src/main/resources/application-secret.properties
layer-admin/src/main/resources/application-secret.properties
layer-admin/src/main/resources/application.yml
layer-admin/src/main/resources/data.sql


5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ project(":layer-api") {

implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'

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

dependencies {
implementation project(path: ':layer-domain')
implementation project(path: ':layer-common')

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

// Security
implementation 'org.springframework.boot:spring-boot-starter-security'

// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.layer.common.exception;

public class AdminException extends BaseCustomException {
public AdminException(ExceptionType exceptionType) {
super(exceptionType);
}
}
68 changes: 68 additions & 0 deletions layer-admin/src/main/java/org/layer/config/RedisConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.layer.config;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;


@Configuration
@EnableRedisRepositories
public class RedisConfig {
@Value("${spring.data.redis.host}")
private String host;

@Value("${spring.data.redis.port}")
private int port;

@Value("${spring.data.redis.password}")
private String password;

// prod에서 최근 서비스 이용 시점 기록 - 1번 데이터베이스
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(host);
redisStandaloneConfiguration.setPort(port);
redisStandaloneConfiguration.setDatabase(1); // 1번 데이터베이스

return new LettuceConnectionFactory(redisStandaloneConfiguration);

}

@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory());

PolymorphicTypeValidator typeValidator = BasicPolymorphicTypeValidator
.builder()
.allowIfSubType(Object.class)
.build();

ObjectMapper objectMapper = new ObjectMapper()
.findAndRegisterModules()
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false)
.activateDefaultTyping(typeValidator, ObjectMapper.DefaultTyping.NON_FINAL)
.registerModule(new JavaTimeModule());

template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));

return template;
}

}
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package org.layer.member.controller.dto;

import java.time.LocalDateTime;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;

import java.time.LocalDateTime;

@Schema(name = "GetMemberActivityResponse", description = "회원 활동 Dto")
public record GetMemberActivityResponse(
@NotNull
@Schema(description = "회원 이름", example = "홍길동")
String name,
@NotNull
@Schema(description = "최근 활동 날짜", example = "2024-11-30T16:21:47.031Z")
@Schema(description = "최근 활동 날짜, 최근 6개월 동안 접속 없을 시 null", example = "2024-11-30T16:21:47.031Z")
LocalDateTime recentActivityDate,
@NotNull
@Schema(description = "소속된 스페이스 수", example = "7")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package org.layer.member.service;

import java.util.List;
import lombok.RequiredArgsConstructor;

import org.layer.common.dto.RecentActivityDto;
import org.layer.domain.answer.repository.AdminAnswerRepository;
import org.layer.domain.member.entity.Member;
import org.layer.domain.member.repository.AdminMemberRepository;
Expand All @@ -11,10 +12,11 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import lombok.RequiredArgsConstructor;
import java.util.List;

@Service
@RequiredArgsConstructor
Expand All @@ -23,6 +25,7 @@ public class AdminMemberService {
private final AdminMemberRepository adminMemberRepository;
private final AdminMemberSpaceRelationRepository adminMemberSpaceRelationRepository;
private final AdminAnswerRepository adminAnswerRepository;
private final RedisTemplate<String, Object> redisTemplate;

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

return new GetMemberActivityResponse(member.getName(), null, spaceCount, retrospectAnswerCount,
member.getCreatedAt(), member.getSocialType().name());
RecentActivityDto recentActivityDto = (RecentActivityDto)redisTemplate.opsForValue()
.get(Long.toString(member.getId()));

return new GetMemberActivityResponse(member.getName(),
recentActivityDto == null ? null : recentActivityDto.getRecentActivityDate(),
spaceCount, retrospectAnswerCount, member.getCreatedAt(), member.getSocialType().name());
}).toList();

return new GetMembersActivitiesResponse(responses);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.layer.retrospect.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.layer.domain.retrospect.dto.AdminRetrospectCountGroupBySpaceGetResponse;
import org.layer.retrospect.controller.dto.AdminRetrospectCountGetResponse;
import org.layer.retrospect.controller.dto.AdminRetrospectsGetResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestParam;

import java.time.LocalDateTime;
import java.util.List;

@Tag(name = "[ADMIN] 회고 데이터", description = "회고 관련 api")
public interface AdminRetrospectApi {


@Operation(summary = "회고 관련 데이터 조회", description = "")
@Parameters({
@Parameter(name = "startDate", description = "검색 시작 시간", example = "2024-09-05T15:30:45", required = true, schema = @Schema(type = "string")),
@Parameter(name = "endDate", description = "검색 종료 시간", example = "2024-09-13T15:30:45", required = true, schema = @Schema(type = "string")),
@Parameter(name = "password", description = "비밀번호 [카톡방으로 공유]", example = "[카톡방으로 공유]", required = true, schema = @Schema(type = "string", format = "string"))})
ResponseEntity<AdminRetrospectsGetResponse> getRetrospectData(@RequestParam("startDate") LocalDateTime startDate,
@RequestParam("endDate") LocalDateTime endDate, @RequestParam("password") String password);

@Operation(summary = "회고 개수 조회", description = "특정 기간내에 시작된 회고 개수를 조회합니다. (우리 팀원이 만든 스페이스에서 진행된 회고는 제외)")
@Parameters({
@Parameter(name = "startDate", description = "검색 시작 시간", example = "2024-09-05T15:30:45", required = true, schema = @Schema(type = "string")),
@Parameter(name = "endDate", description = "검색 종료 시간", example = "2024-09-13T15:30:45", required = true, schema = @Schema(type = "string")),
@Parameter(name = "password", description = "비밀번호 [카톡방으로 공유]", example = "[카톡방으로 공유]", required = true, schema = @Schema(type = "string", format = "string"))})
ResponseEntity<AdminRetrospectCountGetResponse> getRetrospectCount(@RequestParam("startDate") LocalDateTime startDate,
@RequestParam("endDate") LocalDateTime endDate, @RequestParam("password") String password);

@Operation(summary = "특정 기간 내 회고 개수 스페이스 별로 보기", description = "특정 기간내에 시작된 회고 개수를 스페이스 별로 조회합니다. (우리 팀원이 만든 스페이스는 제외)")
@Parameters({
@Parameter(name = "startDate", description = "검색 시작 시간", example = "2024-09-05T15:30:45", required = true, schema = @Schema(type = "string")),
@Parameter(name = "endDate", description = "검색 종료 시간", example = "2024-09-13T15:30:45", required = true, schema = @Schema(type = "string")),
@Parameter(name = "password", description = "비밀번호 [카톡방으로 공유]", example = "[카톡방으로 공유]", required = true, schema = @Schema(type = "string", format = "string"))})
ResponseEntity<List<AdminRetrospectCountGroupBySpaceGetResponse>> getRetrospectCountGroupBySpace (@RequestParam("startDate") LocalDateTime startDate,
@RequestParam("endDate") LocalDateTime endDate,
@RequestParam("password") String password);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.layer.retrospect.controller;

import lombok.RequiredArgsConstructor;
import org.layer.domain.retrospect.dto.AdminRetrospectCountGroupBySpaceGetResponse;
import org.layer.retrospect.controller.dto.AdminRetrospectCountGetResponse;
import org.layer.retrospect.controller.dto.AdminRetrospectsGetResponse;
import org.layer.retrospect.service.AdminRetrospectService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

@RequestMapping("/retrospect")
@RequiredArgsConstructor
@RestController
public class AdminRetrospectController implements AdminRetrospectApi {
private final AdminRetrospectService adminRetrospectService;

@Override
@GetMapping
public ResponseEntity<AdminRetrospectsGetResponse> getRetrospectData(
@RequestParam("startDate") LocalDateTime startDate,
@RequestParam("endDate") LocalDateTime endDate,
@RequestParam("password") String password) {

return ResponseEntity.ok(adminRetrospectService.getRetrospectData(startDate, endDate, password));
}

@Override
@GetMapping("/count/user-only")
public ResponseEntity<AdminRetrospectCountGetResponse> getRetrospectCount(
@RequestParam("startDate") LocalDateTime startDate,
@RequestParam("endDate") LocalDateTime endDate,
@RequestParam("password") String password) {

return ResponseEntity.ok(adminRetrospectService.getRetrospectCount(startDate, endDate, password));
}

@Override
@GetMapping("/count/group-by-space")
public ResponseEntity<List<AdminRetrospectCountGroupBySpaceGetResponse>> getRetrospectCountGroupBySpace(LocalDateTime startDate, LocalDateTime endDate, String password) {
return ResponseEntity.ok(adminRetrospectService.getRetrospectCountGroupSpace(startDate, endDate, password));
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.layer.domain.admin.controller.dto;
package org.layer.retrospect.controller.dto;

import io.swagger.v3.oas.annotations.media.Schema;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.layer.domain.admin.controller.dto;
package org.layer.retrospect.controller.dto;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.layer.retrospect.service;

import lombok.RequiredArgsConstructor;
import org.layer.domain.retrospect.dto.AdminRetrospectCountGroupBySpaceGetResponse;
import org.layer.domain.retrospect.dto.AdminRetrospectGetResponse;
import org.layer.domain.retrospect.repository.RetrospectAdminRepository;
import org.layer.retrospect.controller.dto.AdminRetrospectCountGetResponse;
import org.layer.retrospect.controller.dto.AdminRetrospectsGetResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class AdminRetrospectService {
private final RetrospectAdminRepository retrospectAdminRepository;

@Value("${admin.password}")
private String password;

public AdminRetrospectsGetResponse getRetrospectData(LocalDateTime startDate, LocalDateTime endDate, String requestPassword){

if(!requestPassword.equals(password)){
throw new IllegalArgumentException("비밀번호가 틀렸습니다.");
}

List<AdminRetrospectGetResponse> retrospects = retrospectAdminRepository.findAllByCreatedAtAfterAndCreatedAtBefore(startDate, endDate);

return new AdminRetrospectsGetResponse(retrospects, retrospects.size());
}

public AdminRetrospectCountGetResponse getRetrospectCount(LocalDateTime startDate, LocalDateTime endDate, String requestPassword) {
if(!requestPassword.equals(password)) {
throw new IllegalArgumentException("비밀번호가 틀렸습니다.");
}

Long count = retrospectAdminRepository.countRetrospectsExceptForAdminSpace(startDate, endDate);
return new AdminRetrospectCountGetResponse(count);
}

public List<AdminRetrospectCountGroupBySpaceGetResponse> getRetrospectCountGroupSpace(LocalDateTime startDate, LocalDateTime endDate, String requestPassword) {
if(!requestPassword.equals(password)) {
throw new IllegalArgumentException("비밀번호가 틀렸습니다.");
}

return retrospectAdminRepository.countRetrospectsGroupBySpace(startDate, endDate);
}
}
Loading

0 comments on commit 9667f7c

Please sign in to comment.