diff --git a/.ebextensions-dev/00-makeFiles.config b/.ebextensions-dev/00-makeFiles.config deleted file mode 100644 index 852258da..00000000 --- a/.ebextensions-dev/00-makeFiles.config +++ /dev/null @@ -1,11 +0,0 @@ -files: - "/sbin/appstart" : - mode: "000755" - owner: webapp - group: webapp - content: | - #!/usr/bin/env bash - JAR_PATH=/var/app/current/application.jar - - # run app - java -Dfile.encoding=UTF-8 -Dspring.profiles.active=dev -jar $JAR_PATH \ No newline at end of file diff --git a/.ebextensions-real/00-makeFiles.config b/.ebextensions-real/00-makeFiles.config index e880de45..a54d1b59 100644 --- a/.ebextensions-real/00-makeFiles.config +++ b/.ebextensions-real/00-makeFiles.config @@ -1,11 +1,17 @@ files: - "/sbin/appstart" : + "/sbin/api_start" : mode: "000755" owner: webapp group: webapp content: | - #!/usr/bin/env bash - JAR_PATH=/var/app/current/application.jar - # run app - java -Duser.timezone="Asia/Seoul" -Dspring.profiles.active=real -jar $JAR_PATH \ No newline at end of file + kill `ps -ef | grep fairer-api | awk '{print $2}'` + java -Duser.timezone="Asia/Seoul" -Dspring.profiles.active=real -jar /var/app/current/fairer-api.jar + "/sbin/batch_start" : + mode: "000755" + owner: webapp + group: webapp + content: | + # run app + kill `ps -ef | grep fairer-batch | awk '{print $2}'` + java -Duser.timezone="Asia/Seoul" -Dspring.profiles.active=real -jar /var/app/current/fairer-batch.jar \ No newline at end of file diff --git a/.github/workflows/dev-fairer-api.yml b/.github/workflows/dev-fairer-api.yml new file mode 100644 index 00000000..f4ae2360 --- /dev/null +++ b/.github/workflows/dev-fairer-api.yml @@ -0,0 +1,66 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created +# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle + +name: dev-fairer-api + +on: + workflow_dispatch: + push: + branches: [ develop ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' + + - name: Login to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Grant execute permission for gradlew + run: chmod +x ./gradlew # gradle wrapper를 실행할 수 있도록 권한 부여 + shell: bash + + - name: Set timezone to Seoul + run: sudo timedatectl set-timezone Asia/Seoul + shell: bash + + - name: JIB Build with Gradle + run: ./gradlew :fairer-api:jib # 프로젝트 빌드 + shell: bash + + - name: Get current time + uses: 1466587594/get-current-time@v2 # 빌드 완료 시간 가져오기 + id: current-time + with: + format: YYYY-MM-DD-HH-mm-ss + utcOffset: "+09:00" + + - name: Show Current Time + run: echo "CurrentTime=${{steps.current-time.outputs.formattedTime}}" # 빌드 완료 시간 출력하기 + shell: bash + + deploy: + needs: build + name: Deploy + runs-on: [ self-hosted, label-development ] + steps: + - name: Docker run + run: | + sudo docker ps -q --filter "name=fairer-dev" | grep -q . && sudo docker stop "fairer-dev" && sudo docker rmi "fairerbe/fairer-dev-repo:latest" + sudo docker run -d --name fairer-dev --rm -p 8080:8080 fairerbe/fairer-dev-repo:latest diff --git a/.github/workflows/dev-fairer.yml b/.github/workflows/dev-fairer-batch.yml similarity index 54% rename from .github/workflows/dev-fairer.yml rename to .github/workflows/dev-fairer-batch.yml index 0d2147c3..c1b5a2f4 100644 --- a/.github/workflows/dev-fairer.yml +++ b/.github/workflows/dev-fairer-batch.yml @@ -5,7 +5,7 @@ # This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created # For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle -name: dev-fairer +name: dev-fairer-batch on: workflow_dispatch: @@ -26,12 +26,22 @@ jobs: java-version: '11' distribution: 'adopt' + - name: Login to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Grant execute permission for gradlew run: chmod +x ./gradlew # gradle wrapper를 실행할 수 있도록 권한 부여 shell: bash - - name: Build with Gradle - run: ./gradlew clean build # 프로젝트 빌드 + - name: Set timezone to Seoul + run: sudo timedatectl set-timezone Asia/Seoul + shell: bash + + - name: JIB Build with Gradle + run: ./gradlew :fairer-batch:jib # 프로젝트 빌드 shell: bash - name: Get current time @@ -45,23 +55,12 @@ jobs: run: echo "CurrentTime=${{steps.current-time.outputs.formattedTime}}" # 빌드 완료 시간 출력하기 shell: bash - # gradle build를 통해 만들어진 jar 파일 codedeploy에 배포하기 위한 zip 파일로 만듬 - - name: Generate deployment package + deploy: + needs: build + name: Deploy + runs-on: [ self-hosted, label-development ] + steps: + - name: Docker run run: | - mkdir -p deploy - cp build/libs/*.jar deploy/fairer-dev.jar - cp deploy.sh deploy/deploy.sh - cd deploy - - - name: aws 세팅 - uses: aws-actions/configure-aws-credentials@v1 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_DEV }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEV }} - aws-region: ap-northeast-2 - - - name: S3 업로드 - run: aws deploy push --application-name 2-Team-CodeDeploy --s3-location s3://depromeet11th/2team/fairer_dev/build.zip --source . - - - name: code deploy - run: aws deploy create-deployment --application-name 2-Team-CodeDeploy --deployment-config-name CodeDeployDefault.OneAtATime --deployment-group-name 2-Team-CodeDeploy-Group --s3-location bucket=depromeet11th,bundleType=zip,key=2team/fairer_dev/build.zip + sudo docker ps -q --filter "name=fairer-batch-dev" | grep -q . && sudo docker stop "fairer-batch-dev" && sudo docker rmi "fairerbe/fairer-batch-dev:latest" + sudo docker run -d --name fairer-batch-dev --rm -p 8081:8081 fairerbe/fairer-batch-dev:latest diff --git a/.github/workflows/real-fairer.yml b/.github/workflows/real-fairer.yml index 7dd9fa6a..2336e8ff 100644 --- a/.github/workflows/real-fairer.yml +++ b/.github/workflows/real-fairer.yml @@ -30,8 +30,12 @@ jobs: run: chmod +x ./gradlew # gradle wrapper를 실행할 수 있도록 권한 부여 shell: bash - - name: Build with Gradle - run: ./gradlew clean build # 프로젝트 빌드 + - name: Build API with Gradle + run: ./gradlew :fairer-api:build # 프로젝트 빌드 + shell: bash + + - name: Build Batch with Gradle + run: ./gradlew :fairer-batch:build # 프로젝트 빌드 shell: bash - name: Get current time @@ -49,7 +53,8 @@ jobs: - name: Generate deployment package run: | mkdir -p deploy - cp build/libs/*.jar deploy/application.jar + cp fairer-api/build/libs/*.jar deploy/fairer-api.jar + cp fairer-batch/build/libs/*.jar deploy/fairer-batch.jar cp Procfile deploy/Procfile cp -r .ebextensions-real deploy/.ebextensions cp -r .platform deploy/.platform diff --git a/Procfile b/Procfile index 58dab8d4..ae9b293b 100644 --- a/Procfile +++ b/Procfile @@ -1 +1,2 @@ -web: appstart \ No newline at end of file +api: api_start +batch: batch_start \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..125b3b9c --- /dev/null +++ b/README.md @@ -0,0 +1,126 @@ +# 🧹 fairer +

+ + + +

+ +
+집안일을 하는 모든 이들의 평화를 위한 집안일 관리, 분담 서비스 👨‍👧‍👧
+fairer의 백엔드 레포지토리 입니다. +> Play 스토어 : https://play.google.com/store/apps/details?id=com.depromeet.housekeeper + +
+ +## 🎬 Preview +    + +
+ +## 👨‍👩‍👧‍👧 BackEnd Developer + + + +| | | | | +| :-----------------------------------: | :-----------------: | :----------------: |:----------------: | +| [김승윤](https://github.com/dskym) | [신동빈](https://github.com/SDB016) | [김다슬](https://github.com/daseulll) | [곽다은](https://github.com/daeunkwak) | + +
+ +## **💻 Tech Stack** + +- Skills + + > Spring Boot, Data JPA(+Querydsl) + > +- Database + + > Mysql, RDS + > +- 개발 환경 + + > AWS EC2 + > +- 운영 환경 + + > Elastic Beanstalk + > +- CI/CD + + > [Github Actions](https://github.com/depromeet/fairer-be/actions) + > +- 문서화 + + > [Swagger](http://ec2-13-125-232-180.ap-northeast-2.compute.amazonaws.com:8080/swagger-ui/index.html) + > +- ETC + + > JWT, Oauth2(google) + + > Spring Batch + > + +
+ +## 📚 Architecture + + +
+ +## 🗂 Directory +``` +📂 fairer + 📂 api + 📂 domain + 📂 dto + 📂 global + ├── 📂 config + ├── 📂 exception + | ├── 📂 dto + | └── 📂 handler + ├── 📂 resolver + └── 📂 util + 📂 repository + 📂 service + 📂 vo + - Application.java +``` + +
+ +## 📝ERD + + +
+ +## 💻 Build & Run +1. 빌드 +``` +$ ./gradlew build +``` +2. 빌드된 파일 (*.jar) 실행 +``` +$ fairer-0.0.1-SNAPSHOT.jar +$ java -jar fairer-0.0.1-SNAPSHOT.jar +``` + +
+ + +## 📢 Commit message + + +`feat` : 새로운 기능에 대한 커밋 + +`fix` : 버그 수정에 대한 커밋 + +`refactor` : 새로운 기능 추가나 수정 없이 기존 코드 리팩토링 + +`docs` : 문서화에 대한 커밋 + + +
+ +## 📞 Contact +[![Facebook](https://img.shields.io/badge/facebook-1877f2?style=flat-square&logo=facebook&logoColor=white&link=https://www.facebook.com/fairer.official/)](https://www.facebook.com/fairer.official) +[![instagram](https://img.shields.io/badge/instagram-E4405F?style=flat-square&logo=Instagram&logoColor=white&link=https://www.instagram.com/fairer.official/)](https://www.instagram.com/fairer.official/) diff --git a/appspec.yml b/appspec.yml deleted file mode 100644 index 7588c25c..00000000 --- a/appspec.yml +++ /dev/null @@ -1,16 +0,0 @@ -version: 0.0 -os: linux - -files: - - source: /deploy - destination: /home/ec2-user -permissions: - - object: /home/ec2-user - owner: ec2-user - group: ec2-user - mode: 755 -hooks: - AfterInstall: - - location: deploy.sh - timeout: 60 - runas: ec2-user \ No newline at end of file diff --git a/build.gradle b/build.gradle index ae293601..15128f2c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,99 +1,35 @@ -plugins { - id 'org.springframework.boot' version '2.6.5' - id 'io.spring.dependency-management' version '1.0.11.RELEASE' - // querydsl 추가 - id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" - id 'java' -} - -group = 'com.depromeet' -version = '0.0.1-SNAPSHOT' -sourceCompatibility = '11' - -configurations { - compileOnly { - extendsFrom annotationProcessor +buildscript { + repositories { + mavenCentral() } -} - -ext{ - set('springCloudVersion', "2021.0.2") -} - -dependencyManagement { - imports { - mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" + dependencies { + classpath("org.springframework.boot:spring-boot-gradle-plugin:2.6.5") + classpath "io.spring.gradle:dependency-management-plugin:1.0.11.RELEASE" } } -repositories { - mavenCentral() +allprojects { + group = 'com.depromeet' + version = '0.0.1-SNAPSHOT' } -dependencies { - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-security' - implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' - implementation 'org.springframework.boot:spring-boot-starter-validation' - - //mysql connector - implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.28' - - //modelMapper - implementation group: 'org.modelmapper', name: 'modelmapper', version: '3.1.0' - - //lucy - implementation group: 'com.navercorp.lucy', name: 'lucy-xss-servlet', version: '2.0.1' - - //jwt - implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.2' - - //swagger - implementation group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0' - - implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.2' - implementation 'org.jetbrains:annotations:20.1.0' - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' - - testImplementation 'org.springframework.boot:spring-boot-starter-test' +subprojects { + apply plugin: 'java' + apply plugin: 'org.springframework.boot' + apply plugin: 'io.spring.dependency-management' - // feign - implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' + sourceCompatibility = '11' - // logger - implementation 'org.slf4j:jcl-over-slf4j' - implementation 'ch.qos.logback:logback-classic' - - // querydsl - implementation 'com.querydsl:querydsl-jpa' -} - -tasks.named('test') { - useJUnitPlatform() -} - -jar { - enabled = false -} - -// querydsl -def querydslDir = "$buildDir/generated/querydsl" + repositories { + mavenCentral() + } -querydsl { - library = "com.querydsl:querydsl-apt" - jpa = true - querydslSourcesDir = querydslDir -} -sourceSets { - main.java.srcDir querydslDir -} -configurations { - querydsl.extendsFrom compileClasspath + dependencies { + //mysql connector + implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.28' -} -compileQuerydsl { - options.annotationProcessorPath = configurations.querydsl -} -// querydsl 끝 + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.2' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + } +} \ No newline at end of file diff --git a/deploy.sh b/deploy.sh deleted file mode 100644 index 04f86140..00000000 --- a/deploy.sh +++ /dev/null @@ -1,18 +0,0 @@ -# deploy.sh -#!/usr/bin/env bash - -REPOSITORY=/home/ec2-user -cd $REPOSITORY - -JAR_NAME=fairer-dev.jar -JAR_PATH=$REPOSITORY/$JAR_NAME - -CURRENT_PID=$(pgrep -f $JAR_NAME) - -if ! [ -z $CURRENT_PID ] -then - kill $CURRENT_PID - sleep 5 -fi - -nohup java -jar -Duser.timezone="Asia/Seoul" -Dspring.profiles.active=dev $JAR_PATH & \ No newline at end of file diff --git a/fairer-api/build.gradle b/fairer-api/build.gradle new file mode 100644 index 00000000..73f87222 --- /dev/null +++ b/fairer-api/build.gradle @@ -0,0 +1,107 @@ +import java.text.SimpleDateFormat + +plugins { + // querydsl 추가 + id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" + // jib + id 'com.google.cloud.tools.jib' version '3.2.1' +} + +jib { + from { + image = "adoptopenjdk/openjdk11:centos-jre" + } + container { + environment = [TZ:"Asia/Seoul"] + } + to { + image = "registry.hub.docker.com/fairerbe/fairer-dev-repo" + tags = ['latest', new SimpleDateFormat('yyyyMMddHHmmss').format(System.currentTimeMillis())] // 2개의 태그에 모두 push + } + container { + creationTime = "USE_CURRENT_TIMESTAMP" + jvmFlags = ['-Dspring.profiles.active=dev', '-XX:+UseContainerSupport', '-Dfile.encoding=UTF-8', '-Duser.timezone="Asia/Seoul"'] + } +} + +group = 'com.depromeet' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '11' + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + +ext{ + set('springCloudVersion', "2021.0.2") +} + +dependencyManagement { + imports { + mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" + } +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-security' + implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.springframework.boot:spring-boot-starter-aop' + + //firebase sdk + implementation 'com.google.firebase:firebase-admin:9.0.0' + + //modelMapper + implementation group: 'org.modelmapper', name: 'modelmapper', version: '3.1.0' + + //lucy + implementation group: 'com.navercorp.lucy', name: 'lucy-xss-servlet', version: '2.0.1' + + //jwt + implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.2' + + //swagger + implementation group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0' + + implementation 'org.jetbrains:annotations:20.1.0' + + testImplementation 'org.springframework.boot:spring-boot-starter-test' + + // feign + implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' + + // querydsl + implementation 'com.querydsl:querydsl-jpa' +} + +tasks.named('test') { + useJUnitPlatform() +} + +jar { + enabled = false +} + +// querydsl +def querydslDir = "$buildDir/generated/querydsl" + +querydsl { + library = "com.querydsl:querydsl-apt" + jpa = true + querydslSourcesDir = querydslDir +} +sourceSets { + main.java.srcDir querydslDir +} +configurations { + querydsl.extendsFrom compileClasspath + +} +compileQuerydsl { + options.annotationProcessorPath = configurations.querydsl +} +// querydsl 끝 diff --git a/src/main/java/com/depromeet/fairer/Application.java b/fairer-api/src/main/java/com/depromeet/fairer/Application.java similarity index 84% rename from src/main/java/com/depromeet/fairer/Application.java rename to fairer-api/src/main/java/com/depromeet/fairer/Application.java index 602efab0..f06f4949 100644 --- a/src/main/java/com/depromeet/fairer/Application.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/Application.java @@ -3,8 +3,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.scheduling.annotation.EnableAsync; @EnableJpaAuditing +@EnableAsync @SpringBootApplication public class Application { diff --git a/src/main/java/com/depromeet/fairer/api/HouseWorkController.java b/fairer-api/src/main/java/com/depromeet/fairer/api/HouseWorkController.java similarity index 55% rename from src/main/java/com/depromeet/fairer/api/HouseWorkController.java rename to fairer-api/src/main/java/com/depromeet/fairer/api/HouseWorkController.java index 31641cc3..3ff9e09a 100644 --- a/src/main/java/com/depromeet/fairer/api/HouseWorkController.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/api/HouseWorkController.java @@ -4,6 +4,7 @@ import com.depromeet.fairer.domain.member.Member; import com.depromeet.fairer.dto.member.MemberDto; import com.depromeet.fairer.global.resolver.RequestMemberId; +import com.depromeet.fairer.global.util.DateTimeUtils; import com.depromeet.fairer.service.housework.HouseWorkService; import com.depromeet.fairer.dto.housework.request.HouseWorksCreateRequestDto; import com.depromeet.fairer.dto.housework.request.HouseWorkUpdateRequestDto; @@ -11,6 +12,7 @@ import com.depromeet.fairer.dto.housework.response.*; import com.depromeet.fairer.service.member.MemberService; +import com.depromeet.fairer.service.team.TeamService; import com.depromeet.fairer.vo.houseWork.HouseWorkUpdateVo; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -25,9 +27,10 @@ import javax.validation.Valid; import java.time.LocalDate; -import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @Slf4j @@ -38,18 +41,20 @@ public class HouseWorkController { private final HouseWorkService houseWorkService; private final MemberService memberService; + private final TeamService teamService; private final ModelMapper modelMapper; @Tag(name = "houseWorks") @ApiOperation(value = "집안일 생성 API ") @PostMapping("") - public ResponseEntity createHouseWorks(@ApiIgnore @RequestMemberId Long memberId, @RequestBody @Valid HouseWorksCreateRequestDto dto) { + public ResponseEntity createHouseWorks(@ApiIgnore @RequestMemberId Long memberId, + @RequestBody @Valid HouseWorksCreateRequestDto dto) { List houseWorkList = houseWorkService.createHouseWorks(memberId, dto.getHouseWorks()); return new ResponseEntity<>(new HouseWorksCreateResponseDto(houseWorkList), HttpStatus.CREATED); } @Tag(name = "houseWorks") - @ApiOperation(value = "집안일 수정 API ") + @ApiOperation(value = "집안일 수정 API") @PutMapping("/{houseWorkId}") public ResponseEntity editHouseWork(@ApiIgnore @RequestMemberId Long memberId, @RequestBody @Valid HouseWorkUpdateRequestDto dto, @@ -74,9 +79,10 @@ public ResponseEntity deleteHouseWork( @Tag(name = "houseWorks") @ApiOperation(value = "날짜별 집안일 조회", notes = "본인 포함 팀원들의 집안일까지 모두 조회") @GetMapping(value = "") + @Deprecated public ResponseEntity> getHouseWork(@RequestParam("scheduledDate") String scheduledDate, @ApiIgnore @RequestMemberId Long memberId) { - LocalDate scheduledDateParse = LocalDate.parse(scheduledDate, DateTimeFormatter.ISO_DATE); + LocalDate scheduledDateParse = DateTimeUtils.stringToLocalDate(scheduledDate); List members = memberService.getMemberList(memberId); @@ -100,6 +106,57 @@ public ResponseEntity> getHouseWork(@RequestParam return ResponseEntity.ok(houseWorkDateResponseDtos); } + @Tag(name = "houseWorks") + @ApiOperation(value = "팀원의 특정 기간 집안일 목록 조회", notes = "본인이 속한 팀의 팀원의 특정 기간 집안일 목록 조회") + @GetMapping("/list/member/{teamMemberId}") + public ResponseEntity> getHouseWorkListByTeamMemberAndDate(@RequestParam("fromDate") String fromDate, + @RequestParam("toDate") String toDate, + @PathVariable("teamMemberId") Long teamMemberId, + @ApiIgnore @RequestMemberId Long memberId) { + final LocalDate from = DateTimeUtils.stringToLocalDate(fromDate); + final LocalDate to = DateTimeUtils.stringToLocalDate(toDate); + + teamService.checkJoinSameTeam(teamMemberId, memberId); + + Member teamMember = memberService.find(teamMemberId); + List houseWorkList = houseWorkService.getHouseWorkByDate(teamMember, from, to); + Map> houseWorkListGroupByScheduledDate = getHouseWorkListGroupByScheduledDate(houseWorkList); + return ResponseEntity.ok(makeHouseWorkListResponse(teamMemberId, houseWorkListGroupByScheduledDate)); + } + + @Tag(name = "houseWorks") + @ApiOperation(value = "특정 날짜별 집안일 조회", notes = "특정 날짜별 집안일 조회") + @GetMapping("/list") + public ResponseEntity> getHouseWorkListByDate(@RequestParam("fromDate") String fromDate, + @RequestParam("toDate") String toDate, + @ApiIgnore @RequestMemberId Long memberId) { + final LocalDate from = DateTimeUtils.stringToLocalDate(fromDate); + final LocalDate to = DateTimeUtils.stringToLocalDate(toDate); + + Member member = memberService.find(memberId); + List houseWorkList = houseWorkService.getHouseWorkByDateAndTeam(member.getTeam(), from, to); + Map> houseWorkListGroupByScheduledDate = getHouseWorkListGroupByScheduledDate(houseWorkList); + return ResponseEntity.ok(makeHouseWorkListResponse(memberId, houseWorkListGroupByScheduledDate)); + } + + private Map> getHouseWorkListGroupByScheduledDate(List houseWorkList) { + return houseWorkList.stream().map(houseWork -> { + List memberDtoList = memberService.getMemberListByHouseWorkId(houseWork.getHouseWorkId()) + .stream().map(MemberDto::from).collect(Collectors.toList()); + return HouseWorkResponseDto.from(houseWork, memberDtoList); + }).collect(Collectors.groupingBy(HouseWorkResponseDto::getScheduledDate, HashMap::new, Collectors.toCollection(ArrayList::new))); + } + + private Map makeHouseWorkListResponse(Long memberId, Map> houseWorkListGroupByScheduledDate) { + Map response = new HashMap<>(); + houseWorkListGroupByScheduledDate.forEach((scheduledDate, houseWorkResponseDtoList) -> { + long countDone = houseWorkResponseDtoList.stream().filter(HouseWorkResponseDto::getSuccess).count(); + long countLeft = houseWorkResponseDtoList.stream().filter(houseWorkResponseDto -> !houseWorkResponseDto.getSuccess()).count(); + response.put(DateTimeUtils.localDateToString(scheduledDate), HouseWorkDateResponseDto.from(memberId, scheduledDate, countDone, countLeft, houseWorkResponseDtoList)); + }); + return response; + } + @Tag(name = "houseWorks") @ApiOperation(value = "개별 집안일 조회", notes = "") @GetMapping(value = "{houseWorkId}/detail") @@ -110,13 +167,15 @@ public ResponseEntity getHouseWorkDetail(@PathVariable("ho @Tag(name = "houseWorks") @ApiOperation(value = "집안일 완료여부 수정", notes = "toBeStatus=0이면 완료->미완료, toBeStatus=1이면 미완료->완료") @PatchMapping(value = "{houseWorkId}") - public ResponseEntity updateHouseWorkStatus(@PathVariable("houseWorkId") Long houseWorkId, @RequestBody @Valid HouseWorkStatusRequestDto req) { + public ResponseEntity updateHouseWorkStatus(@PathVariable("houseWorkId") Long houseWorkId, + @RequestBody @Valid HouseWorkStatusRequestDto req) { return ResponseEntity.ok(houseWorkService.updateHouseWorkStatus(houseWorkId, req.getToBeStatus())); } @Tag(name = "houseWorks") @GetMapping("/success/count") - public ResponseEntity getSuccessCount(@RequestParam(required = true) String scheduledDate, @ApiIgnore @RequestMemberId Long memberId) { + public ResponseEntity getSuccessCount(@RequestParam String scheduledDate, + @ApiIgnore @RequestMemberId Long memberId) { HouseWorkSuccessCountResponseDto houseWorkSuccessCountResponseDto = houseWorkService.getSuccessCount(scheduledDate, memberId); return ResponseEntity.ok(houseWorkSuccessCountResponseDto); } diff --git a/src/main/java/com/depromeet/fairer/api/MemberController.java b/fairer-api/src/main/java/com/depromeet/fairer/api/MemberController.java similarity index 95% rename from src/main/java/com/depromeet/fairer/api/MemberController.java rename to fairer-api/src/main/java/com/depromeet/fairer/api/MemberController.java index a76978df..6a3a19dd 100644 --- a/src/main/java/com/depromeet/fairer/api/MemberController.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/api/MemberController.java @@ -7,7 +7,6 @@ import com.depromeet.fairer.dto.member.response.MemberResponseDto; import com.depromeet.fairer.global.resolver.RequestMemberId; import com.depromeet.fairer.service.member.MemberService; -import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; @@ -57,7 +56,7 @@ public ResponseEntity getDefaultProfileImageList( @ApiOperation(value = "멤버 업데이트", notes = "멤버 정보 업데이트

" + "멤버 이름
프로필 url") @PatchMapping(value = "") - public ResponseEntity updateTeam(@ApiIgnore @RequestMemberId Long memberId, @RequestBody MemberUpdateRequestDto requestDto) { + public ResponseEntity updateTeam(@ApiIgnore @RequestMemberId Long memberId, @Valid @RequestBody MemberUpdateRequestDto requestDto) { // TODO 이름, url 정규식 검증 memberService.updateMember(memberId, requestDto.getMemberName(), requestDto.getProfilePath(), requestDto.getStatusMessage()); return ResponseEntity.ok(CommonApiResult.createOk("멤버 정보가 업데이트 되었습니다.")); diff --git a/src/main/java/com/depromeet/fairer/api/OauthLoginController.java b/fairer-api/src/main/java/com/depromeet/fairer/api/OauthLoginController.java similarity index 91% rename from src/main/java/com/depromeet/fairer/api/OauthLoginController.java rename to fairer-api/src/main/java/com/depromeet/fairer/api/OauthLoginController.java index b7e02cf9..e1f3abb2 100644 --- a/src/main/java/com/depromeet/fairer/api/OauthLoginController.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/api/OauthLoginController.java @@ -1,25 +1,20 @@ package com.depromeet.fairer.api; -import com.depromeet.fairer.dto.member.oauth.OauthLoginDto; import com.depromeet.fairer.dto.member.oauth.OauthRequestDto; import com.depromeet.fairer.dto.member.jwt.ResponseJwtTokenDto; import com.depromeet.fairer.domain.member.constant.SocialType; import com.depromeet.fairer.service.member.oauth.OauthLoginService; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.EnumUtils; -import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; -import java.security.InvalidParameterException; import java.time.LocalDateTime; @Slf4j diff --git a/src/main/java/com/depromeet/fairer/api/PresetController.java b/fairer-api/src/main/java/com/depromeet/fairer/api/PresetController.java similarity index 59% rename from src/main/java/com/depromeet/fairer/api/PresetController.java rename to fairer-api/src/main/java/com/depromeet/fairer/api/PresetController.java index 35414258..768b9326 100644 --- a/src/main/java/com/depromeet/fairer/api/PresetController.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/api/PresetController.java @@ -1,9 +1,8 @@ package com.depromeet.fairer.api; -import com.depromeet.fairer.domain.preset.constant.Space; -import com.depromeet.fairer.dto.preset.response.HouseWorkPresetListResponseDto; +import com.depromeet.fairer.domain.preset.Preset; +import com.depromeet.fairer.domain.preset.Space; import com.depromeet.fairer.dto.preset.response.HouseWorkPresetResponseDto; -import com.depromeet.fairer.service.PresetService; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -13,13 +12,15 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.ArrayList; +import java.util.List; + @Slf4j @RestController @RequiredArgsConstructor @Tag(name = "presets", description = "프리셋 API") @RequestMapping("/api/preset") public class PresetController { - private final PresetService presetService; /** * 공간 -> 집안일 프리셋 조회 @@ -29,12 +30,19 @@ public class PresetController { @Tag(name = "presets") @GetMapping(value = "{space}") public ResponseEntity getHouseWorkPreset(@PathVariable Space space){ - return ResponseEntity.ok(presetService.getHouseWorkPreset(space)); + return ResponseEntity.ok(new HouseWorkPresetResponseDto(space.name(), Preset.getHouseworkNameListBySpace(space))); } @Tag(name = "presets") @GetMapping(value = "") - public ResponseEntity getPreset(){ - return ResponseEntity.ok(presetService.getPreset()); + public ResponseEntity> getAllPreset(){ + List response = new ArrayList<>(); + for (Space space : Space.values()) { + if (space.equals(Space.ETC)) { + continue; + } + response.add(new HouseWorkPresetResponseDto(space.name(), Preset.getHouseworkNameListBySpace(space))); + } + return ResponseEntity.ok(response); } } diff --git a/src/main/java/com/depromeet/fairer/api/RuleController.java b/fairer-api/src/main/java/com/depromeet/fairer/api/RuleController.java similarity index 78% rename from src/main/java/com/depromeet/fairer/api/RuleController.java rename to fairer-api/src/main/java/com/depromeet/fairer/api/RuleController.java index 9546e2d0..48a160ca 100644 --- a/src/main/java/com/depromeet/fairer/api/RuleController.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/api/RuleController.java @@ -1,13 +1,14 @@ package com.depromeet.fairer.api; import com.depromeet.fairer.domain.rule.Rule; +import com.depromeet.fairer.domain.team.Team; import com.depromeet.fairer.dto.common.CommonApiResult; import com.depromeet.fairer.dto.rule.request.RuleRequestDto; import com.depromeet.fairer.dto.rule.response.RuleResponseDto; import com.depromeet.fairer.dto.rule.response.RulesResponseDto; +import com.depromeet.fairer.global.exception.BadRequestException; import com.depromeet.fairer.global.resolver.RequestMemberId; import com.depromeet.fairer.service.member.MemberService; import com.depromeet.fairer.service.rule.RuleService; -import com.depromeet.fairer.service.team.TeamService; import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; @@ -20,6 +21,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import static org.springframework.http.ResponseEntity.ok; @@ -31,7 +33,6 @@ public class RuleController { private final RuleService ruleService; - private final TeamService teamService; private final MemberService memberService; @Tag(name = "rules") @@ -39,19 +40,22 @@ public class RuleController { @PostMapping(value = "") public ResponseEntity createTeamRules(@ApiIgnore @RequestMemberId Long memberId, @RequestBody @Valid RuleRequestDto req){ + Team team = memberService.findWithTeam(memberId).getTeam(); + + // 규칙 조회 + Long count = ruleService.countRules(team); + if(count >= 10) { + throw new BadRequestException("규칙은 최대 10개까지 생성할 수 있습니다."); + } + // 규칙 생성 - Rule rule = ruleService.createRules(memberId, req.getRuleName()); + ruleService.createRules(team, req.getRuleName()); // 반환 객체 생성 - List rules = ruleService.findAllByTeam(rule.getTeam()); - - List ruleResponseDtos = new ArrayList<>(); - for(Rule rulee : rules){ - ruleResponseDtos.add(RuleResponseDto.createRule(rulee)); - } + List rules = ruleService.findAllByTeam(team); - Long teamId = memberService.findWithTeam(memberId).getTeam().getTeamId(); - return ok(RulesResponseDto.createRules(teamId, ruleResponseDtos)); + List ruleResponseDtos = rules.stream().map(RuleResponseDto::createRule).collect(Collectors.toList()); + return ok(RulesResponseDto.createRules(team.getTeamId(), ruleResponseDtos)); } @Tag(name = "rules") diff --git a/src/main/java/com/depromeet/fairer/api/TeamController.java b/fairer-api/src/main/java/com/depromeet/fairer/api/TeamController.java similarity index 100% rename from src/main/java/com/depromeet/fairer/api/TeamController.java rename to fairer-api/src/main/java/com/depromeet/fairer/api/TeamController.java diff --git a/fairer-api/src/main/java/com/depromeet/fairer/api/fcm/FCMController.java b/fairer-api/src/main/java/com/depromeet/fairer/api/fcm/FCMController.java new file mode 100644 index 00000000..4cd11ee3 --- /dev/null +++ b/fairer-api/src/main/java/com/depromeet/fairer/api/fcm/FCMController.java @@ -0,0 +1,40 @@ +package com.depromeet.fairer.api.fcm; + +import com.depromeet.fairer.dto.fcm.request.FCMMessageRequest; +import com.depromeet.fairer.dto.fcm.request.SaveTokenRequest; +import com.depromeet.fairer.dto.fcm.response.FCMMessageResponse; +import com.depromeet.fairer.dto.fcm.response.SaveTokenResponse; +import com.depromeet.fairer.global.resolver.RequestMemberId; +import com.depromeet.fairer.service.fcm.FCMService; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.annotations.ApiIgnore; + +import javax.validation.Valid; + +@Slf4j +@RestController +@RequiredArgsConstructor +@Tag(name = "fcm", description = "FCM 관련 API") +@RequestMapping(value = "/api/fcm") +public class FCMController { + private final FCMService fcmService; + + @Tag(name = "fcm") + @PostMapping("/token") + public ResponseEntity saveToken(@Valid @RequestBody SaveTokenRequest request, @ApiIgnore @RequestMemberId Long memberId) { + return ResponseEntity.ok(fcmService.saveToken(request, memberId)); + } + + @Tag(name = "fcm") + @PostMapping("/message") + public ResponseEntity sendMessage(@Valid @RequestBody FCMMessageRequest request) { + return ResponseEntity.ok(fcmService.sendMessage(request)); + } +} diff --git a/src/main/java/com/depromeet/fairer/domain/assignment/Assignment.java b/fairer-api/src/main/java/com/depromeet/fairer/domain/assignment/Assignment.java similarity index 100% rename from src/main/java/com/depromeet/fairer/domain/assignment/Assignment.java rename to fairer-api/src/main/java/com/depromeet/fairer/domain/assignment/Assignment.java diff --git a/src/main/java/com/depromeet/fairer/domain/base/BaseTimeEntity.java b/fairer-api/src/main/java/com/depromeet/fairer/domain/base/BaseTimeEntity.java similarity index 96% rename from src/main/java/com/depromeet/fairer/domain/base/BaseTimeEntity.java rename to fairer-api/src/main/java/com/depromeet/fairer/domain/base/BaseTimeEntity.java index f592624d..1e38126f 100644 --- a/src/main/java/com/depromeet/fairer/domain/base/BaseTimeEntity.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/domain/base/BaseTimeEntity.java @@ -1,6 +1,5 @@ package com.depromeet.fairer.domain.base; -import lombok.Data; import lombok.Getter; import lombok.Setter; import org.springframework.data.annotation.CreatedDate; diff --git a/src/main/java/com/depromeet/fairer/domain/housework/HouseWork.java b/fairer-api/src/main/java/com/depromeet/fairer/domain/housework/HouseWork.java similarity index 96% rename from src/main/java/com/depromeet/fairer/domain/housework/HouseWork.java rename to fairer-api/src/main/java/com/depromeet/fairer/domain/housework/HouseWork.java index ec5e61d2..e01d393f 100644 --- a/src/main/java/com/depromeet/fairer/domain/housework/HouseWork.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/domain/housework/HouseWork.java @@ -2,7 +2,7 @@ import com.depromeet.fairer.domain.assignment.Assignment; import com.depromeet.fairer.domain.base.BaseTimeEntity; -import com.depromeet.fairer.domain.preset.constant.Space; +import com.depromeet.fairer.domain.preset.Space; import com.depromeet.fairer.domain.team.Team; import lombok.*; diff --git a/src/main/java/com/depromeet/fairer/domain/member/Member.java b/fairer-api/src/main/java/com/depromeet/fairer/domain/member/Member.java similarity index 86% rename from src/main/java/com/depromeet/fairer/domain/member/Member.java rename to fairer-api/src/main/java/com/depromeet/fairer/domain/member/Member.java index a49dc42b..c6719431 100644 --- a/src/main/java/com/depromeet/fairer/domain/member/Member.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/domain/member/Member.java @@ -3,11 +3,9 @@ import com.depromeet.fairer.domain.base.BaseTimeEntity; import com.depromeet.fairer.dto.member.oauth.OAuthAttributes; import com.depromeet.fairer.domain.assignment.Assignment; -import com.depromeet.fairer.domain.memberToken.MemberToken; import com.depromeet.fairer.domain.team.Team; import com.depromeet.fairer.domain.member.constant.SocialType; import com.depromeet.fairer.global.exception.CannotJoinTeamException; -import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.*; import javax.persistence.*; @@ -15,6 +13,13 @@ import java.util.ArrayList; import java.util.List; +@NamedEntityGraph(name = "Member.withMyTeamMembers", attributeNodes = { + @NamedAttributeNode(value = "team", subgraph = "team") + }, + subgraphs = @NamedSubgraph(name = "team", attributeNodes = { + @NamedAttributeNode("members") + }) +) @Entity @Table(name = "member") @Getter @@ -43,10 +48,6 @@ public class Member extends BaseTimeEntity { @Column(name = "member_name", columnDefinition = "VARCHAR(50)", nullable = false) private String memberName; - @JsonIgnore - @Column(name = "password", columnDefinition = "VARCHAR(300)", nullable = false) - private String password; - @Column(name = "status_message", columnDefinition = "VARCHAR(40)") private String statusMessage; @@ -57,6 +58,12 @@ public class Member extends BaseTimeEntity { @JoinColumn(name = "team_id") private Team team; + @Column(name = "fcm_token", columnDefinition = "VARCHAR(200)") + private String fcmToken; + + @Column(name = "fcm_token_date", columnDefinition = "DATETIME") + private LocalDateTime fcmTokenDate; + /** * TODO 닉네임 동의 안했을 때 처리 (입력한 닉네임으로 변경) * @@ -67,7 +74,6 @@ public static Member create(OAuthAttributes socialUserInfo) { return Member.builder() .email(socialUserInfo.getEmail()) .socialType(socialUserInfo.getSocialType()) - .password(socialUserInfo.getPassword()) .assignments(new ArrayList<>()) .memberName("") // 회원가입 할때는 빈값으로 세팅, 이후 멤버 업데이트 api 로 변경 .profilePath("") diff --git a/src/main/java/com/depromeet/fairer/domain/member/constant/ProfileImage.java b/fairer-api/src/main/java/com/depromeet/fairer/domain/member/constant/ProfileImage.java similarity index 87% rename from src/main/java/com/depromeet/fairer/domain/member/constant/ProfileImage.java rename to fairer-api/src/main/java/com/depromeet/fairer/domain/member/constant/ProfileImage.java index 531ff6c2..a11f9d2c 100644 --- a/src/main/java/com/depromeet/fairer/domain/member/constant/ProfileImage.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/domain/member/constant/ProfileImage.java @@ -31,6 +31,10 @@ public enum ProfileImage { final String bigImageName; public static List getBigImageFullPathList(String domain, String path) { - return Arrays.stream(values()).map(profileImage -> UriComponentsBuilder.fromHttpUrl(domain).path(path).path(profileImage.bigImageName).build().toString()).collect(Collectors.toList()); + return Arrays.stream(values()) + .map(profileImage -> UriComponentsBuilder.fromHttpUrl(domain) + .path(path).path(profileImage.bigImageName) + .build().toString()) + .collect(Collectors.toList()); } } diff --git a/src/main/java/com/depromeet/fairer/domain/member/constant/SocialType.java b/fairer-api/src/main/java/com/depromeet/fairer/domain/member/constant/SocialType.java similarity index 100% rename from src/main/java/com/depromeet/fairer/domain/member/constant/SocialType.java rename to fairer-api/src/main/java/com/depromeet/fairer/domain/member/constant/SocialType.java diff --git a/src/main/java/com/depromeet/fairer/domain/memberToken/MemberToken.java b/fairer-api/src/main/java/com/depromeet/fairer/domain/memberToken/MemberToken.java similarity index 97% rename from src/main/java/com/depromeet/fairer/domain/memberToken/MemberToken.java rename to fairer-api/src/main/java/com/depromeet/fairer/domain/memberToken/MemberToken.java index 679266d8..70b8b96c 100644 --- a/src/main/java/com/depromeet/fairer/domain/memberToken/MemberToken.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/domain/memberToken/MemberToken.java @@ -1,7 +1,6 @@ package com.depromeet.fairer.domain.memberToken; import com.depromeet.fairer.domain.base.BaseTimeEntity; -import com.depromeet.fairer.domain.member.Member; import com.depromeet.fairer.domain.memberToken.constant.RemainingTokenTime; import lombok.*; diff --git a/src/main/java/com/depromeet/fairer/domain/memberToken/constant/JwtTokenType.java b/fairer-api/src/main/java/com/depromeet/fairer/domain/memberToken/constant/JwtTokenType.java similarity index 100% rename from src/main/java/com/depromeet/fairer/domain/memberToken/constant/JwtTokenType.java rename to fairer-api/src/main/java/com/depromeet/fairer/domain/memberToken/constant/JwtTokenType.java diff --git a/src/main/java/com/depromeet/fairer/domain/memberToken/constant/RemainingTokenTime.java b/fairer-api/src/main/java/com/depromeet/fairer/domain/memberToken/constant/RemainingTokenTime.java similarity index 100% rename from src/main/java/com/depromeet/fairer/domain/memberToken/constant/RemainingTokenTime.java rename to fairer-api/src/main/java/com/depromeet/fairer/domain/memberToken/constant/RemainingTokenTime.java diff --git a/fairer-api/src/main/java/com/depromeet/fairer/domain/preset/Preset.java b/fairer-api/src/main/java/com/depromeet/fairer/domain/preset/Preset.java new file mode 100644 index 00000000..b5915985 --- /dev/null +++ b/fairer-api/src/main/java/com/depromeet/fairer/domain/preset/Preset.java @@ -0,0 +1,61 @@ +package com.depromeet.fairer.domain.preset; + +import com.depromeet.fairer.global.exception.FairerException; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +@Getter +@AllArgsConstructor +public enum Preset { + ORGANIZING_SHOES(Space.ENTRANCE,"신발 정리"), + CLEANING_ENTRANCE(Space.ENTRANCE,"현관 청소"), + SEPARATING_TRASH(Space.ENTRANCE,"분리수거하기"), + CLEANING_BATHTUB(Space.BATHROOM,"욕조 청소"), + CLEANING_TOILET_BOWL(Space.BATHROOM,"변기 청소"), + CLEANING_BATHROOM(Space.BATHROOM,"화장실 청소"), + ORGANIZING_BATHROOM_ITEMS(Space.BATHROOM,"욕실 용품 정리"), + ORGANIZING_CLOSET(Space.ROOM,"옷장 정리"), + ARRANGEMENT_DRESSING_TABLE(Space.ROOM,"화장대 정리"), + CLEANING_ROOM(Space.ROOM,"방 청소"), + ORGANIZING_ROOM_ITEMS(Space.ROOM,"물건 정리정돈"), + MAKING_BED(Space.ROOM,"이불 정리"), + WASHING_DISH(Space.KITCHEN,"설거지"), + CLEANING_STOVE(Space.KITCHEN,"가스렌지 닦기"), + CLEANING_UP_REFRIGERATOR(Space.KITCHEN,"냉장고 정리"), + CLEANING_UP_KITCHEN(Space.KITCHEN,"부엌 정리정돈"), + DISPOSAL_FOOD_WASTE(Space.KITCHEN,"음식물 쓰레기 버리기"), + PREPARING_MEAL(Space.KITCHEN,"식사 준비하기"), + PREPARING_SNACK(Space.KITCHEN,"간식 준비하기"), + DISPOSAL_GARBAGE(Space.OUTSIDE,"쓰레기 버리기"), + SHOPPING(Space.OUTSIDE,"장보기"), + PET_WALKING(Space.OUTSIDE,"반려동물 산책"), + MEETING(Space.OUTSIDE,"마중 나가기"), + CLEANING_WINDOW(Space.LIVINGROOM,"창 청소"), + CLEANING_LININGROOM(Space.LIVINGROOM,"거실 청소"), + ORGANIZING_LININGROOM_ITEMS(Space.LIVINGROOM,"물건 정리정돈"), + VENTILATION(Space.LIVINGROOM,"환기 시키기"), + WASHING_CLOTHES(Space.LIVINGROOM,"빨래 돌리기"), + FOLDING_LAUNDRY(Space.LIVINGROOM,"빨래 개기"), + CLEANING_WASHING_MACHINE(Space.LIVINGROOM,"세탁기 청소"), + ; + + public static Preset getPreset(Space space, String houseWorkName) { + return Arrays.stream(values()).filter(p -> p.houseworkName.equals(houseWorkName) && p.space.equals(space)) + .findFirst().orElseThrow(() -> new FairerException("Preset Not Found")); + } + + public static List getPresetListBySpace(Space space) { + return Arrays.stream(values()).filter(p -> p.space.equals(space)).collect(Collectors.toList()); + } + + public static List getHouseworkNameListBySpace(Space space) { + return Arrays.stream(values()).filter(p -> p.space.equals(space)).map(Preset::getHouseworkName).collect(Collectors.toList()); + } + + private Space space; + private String houseworkName; +} diff --git a/src/main/java/com/depromeet/fairer/domain/preset/constant/Space.java b/fairer-api/src/main/java/com/depromeet/fairer/domain/preset/Space.java similarity index 80% rename from src/main/java/com/depromeet/fairer/domain/preset/constant/Space.java rename to fairer-api/src/main/java/com/depromeet/fairer/domain/preset/Space.java index fc40b483..0a32ba5a 100644 --- a/src/main/java/com/depromeet/fairer/domain/preset/constant/Space.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/domain/preset/Space.java @@ -1,4 +1,4 @@ -package com.depromeet.fairer.domain.preset.constant; +package com.depromeet.fairer.domain.preset; import lombok.Getter; diff --git a/src/main/java/com/depromeet/fairer/domain/rule/Rule.java b/fairer-api/src/main/java/com/depromeet/fairer/domain/rule/Rule.java similarity index 100% rename from src/main/java/com/depromeet/fairer/domain/rule/Rule.java rename to fairer-api/src/main/java/com/depromeet/fairer/domain/rule/Rule.java diff --git a/src/main/java/com/depromeet/fairer/domain/team/Team.java b/fairer-api/src/main/java/com/depromeet/fairer/domain/team/Team.java similarity index 100% rename from src/main/java/com/depromeet/fairer/domain/team/Team.java rename to fairer-api/src/main/java/com/depromeet/fairer/domain/team/Team.java diff --git a/src/main/java/com/depromeet/fairer/domain/team/constant/TeamConstant.java b/fairer-api/src/main/java/com/depromeet/fairer/domain/team/constant/TeamConstant.java similarity index 100% rename from src/main/java/com/depromeet/fairer/domain/team/constant/TeamConstant.java rename to fairer-api/src/main/java/com/depromeet/fairer/domain/team/constant/TeamConstant.java diff --git a/src/main/java/com/depromeet/fairer/dto/common/CommonApiResult.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/common/CommonApiResult.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/common/CommonApiResult.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/common/CommonApiResult.java diff --git a/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/FCMMessageTemplate.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/FCMMessageTemplate.java new file mode 100644 index 00000000..62bc800a --- /dev/null +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/FCMMessageTemplate.java @@ -0,0 +1,13 @@ +package com.depromeet.fairer.dto.fcm; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum FCMMessageTemplate { + JOIN_MEMBER_IN_TEAM("%s님이 %s에 참여", "앞으로 함께 평화롭게 집안일 해보아요✨"); + + private final String title; + private final String body; +} diff --git a/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/FCMSendRequest.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/FCMSendRequest.java new file mode 100644 index 00000000..33eba930 --- /dev/null +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/FCMSendRequest.java @@ -0,0 +1,23 @@ +package com.depromeet.fairer.dto.fcm; + +import com.google.firebase.messaging.Message; +import lombok.Builder; +import lombok.Data; + +/*** + * https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages/send + */ +@Data +@Builder +public class FCMSendRequest { + private boolean validate_only; + private Message message; + + public static FCMSendRequest of(Message message, boolean validate_only) { + return FCMSendRequest.builder() + .message(message) + .validate_only(validate_only) + .build(); + } +} + diff --git a/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/request/FCMMessageRequest.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/request/FCMMessageRequest.java new file mode 100644 index 00000000..dae5bb8c --- /dev/null +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/request/FCMMessageRequest.java @@ -0,0 +1,16 @@ +package com.depromeet.fairer.dto.fcm.request; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +@Data +public class FCMMessageRequest { + @NotNull + private Long memberId; + @NotBlank + private String title; + @NotBlank + private String body; +} diff --git a/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/request/SaveTokenRequest.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/request/SaveTokenRequest.java new file mode 100644 index 00000000..8be0f886 --- /dev/null +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/request/SaveTokenRequest.java @@ -0,0 +1,11 @@ +package com.depromeet.fairer.dto.fcm.request; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class SaveTokenRequest { + @NotBlank + private String token; +} diff --git a/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/response/FCMMessageResponse.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/response/FCMMessageResponse.java new file mode 100644 index 00000000..3ab58573 --- /dev/null +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/response/FCMMessageResponse.java @@ -0,0 +1,20 @@ +package com.depromeet.fairer.dto.fcm.response; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class FCMMessageResponse { + private String title; + private String body; + private Long memberId; + + public static FCMMessageResponse of(String title, String body, Long memberId) { + return FCMMessageResponse.builder() + .title(title) + .body(body) + .memberId(memberId) + .build(); + } +} diff --git a/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/response/SaveTokenResponse.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/response/SaveTokenResponse.java new file mode 100644 index 00000000..8f045d0e --- /dev/null +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/fcm/response/SaveTokenResponse.java @@ -0,0 +1,16 @@ +package com.depromeet.fairer.dto.fcm.response; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class SaveTokenResponse { + private String token; + + public static SaveTokenResponse of(String token) { + return SaveTokenResponse.builder() + .token(token) + .build(); + } +} diff --git a/src/main/java/com/depromeet/fairer/dto/housework/request/HouseWorkStatusRequestDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/housework/request/HouseWorkStatusRequestDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/housework/request/HouseWorkStatusRequestDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/housework/request/HouseWorkStatusRequestDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/housework/request/HouseWorkUpdateRequestDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/housework/request/HouseWorkUpdateRequestDto.java similarity index 97% rename from src/main/java/com/depromeet/fairer/dto/housework/request/HouseWorkUpdateRequestDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/housework/request/HouseWorkUpdateRequestDto.java index 5fd278d0..e99e32f9 100644 --- a/src/main/java/com/depromeet/fairer/dto/housework/request/HouseWorkUpdateRequestDto.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/housework/request/HouseWorkUpdateRequestDto.java @@ -1,7 +1,7 @@ package com.depromeet.fairer.dto.housework.request; import com.depromeet.fairer.domain.housework.HouseWork; -import com.depromeet.fairer.domain.preset.constant.Space; +import com.depromeet.fairer.domain.preset.Space; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; diff --git a/src/main/java/com/depromeet/fairer/dto/housework/request/HouseWorksCreateRequestDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/housework/request/HouseWorksCreateRequestDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/housework/request/HouseWorksCreateRequestDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/housework/request/HouseWorksCreateRequestDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkDateResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkDateResponseDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkDateResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkDateResponseDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkMemberResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkMemberResponseDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkMemberResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkMemberResponseDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkResponseDto.java similarity index 97% rename from src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkResponseDto.java index 136fa979..53509aa0 100644 --- a/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkResponseDto.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkResponseDto.java @@ -1,7 +1,7 @@ package com.depromeet.fairer.dto.housework.response; import com.depromeet.fairer.domain.housework.HouseWork; -import com.depromeet.fairer.domain.preset.constant.Space; +import com.depromeet.fairer.domain.preset.Space; import com.depromeet.fairer.dto.member.MemberDto; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonSerialize; diff --git a/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkStatusResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkStatusResponseDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkStatusResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkStatusResponseDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkSuccessCountResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkSuccessCountResponseDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkSuccessCountResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorkSuccessCountResponseDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorksCreateResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorksCreateResponseDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorksCreateResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/housework/response/HouseWorksCreateResponseDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/member/MemberDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/member/MemberDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/member/MemberDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/member/MemberDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/member/jwt/ResponseJwtTokenDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/member/jwt/ResponseJwtTokenDto.java similarity index 96% rename from src/main/java/com/depromeet/fairer/dto/member/jwt/ResponseJwtTokenDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/member/jwt/ResponseJwtTokenDto.java index b8c93387..b2dee2ec 100644 --- a/src/main/java/com/depromeet/fairer/dto/member/jwt/ResponseJwtTokenDto.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/member/jwt/ResponseJwtTokenDto.java @@ -27,9 +27,11 @@ public class ResponseJwtTokenDto { private Date refreshTokenExpireTime; @ApiModelProperty(value = "신규 회원 여부 - 이름이 저장되어 있는지 여부") + @Builder.Default private Boolean isNewMember = false; @ApiModelProperty(value = "팀 소속 여부") + @Builder.Default private Boolean hasTeam = false; @ApiModelProperty(value = "멤버 이름") diff --git a/src/main/java/com/depromeet/fairer/dto/member/jwt/TokenDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/member/jwt/TokenDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/member/jwt/TokenDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/member/jwt/TokenDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/member/oauth/GoogleUserInfo.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/member/oauth/GoogleUserInfo.java similarity index 92% rename from src/main/java/com/depromeet/fairer/dto/member/oauth/GoogleUserInfo.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/member/oauth/GoogleUserInfo.java index 6994f5a7..a92fb58a 100644 --- a/src/main/java/com/depromeet/fairer/dto/member/oauth/GoogleUserInfo.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/member/oauth/GoogleUserInfo.java @@ -28,4 +28,7 @@ public class GoogleUserInfo { @JsonProperty("locale") private String locale; + + @JsonProperty("hd") + private String hd; } diff --git a/src/main/java/com/depromeet/fairer/dto/member/oauth/OAuthAttributes.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/member/oauth/OAuthAttributes.java similarity index 89% rename from src/main/java/com/depromeet/fairer/dto/member/oauth/OAuthAttributes.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/member/oauth/OAuthAttributes.java index 0ce2de3f..ce2ae25f 100644 --- a/src/main/java/com/depromeet/fairer/dto/member/oauth/OAuthAttributes.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/member/oauth/OAuthAttributes.java @@ -16,15 +16,13 @@ public class OAuthAttributes { private String name; private String email; private SocialType socialType; - private String password; @Builder - public OAuthAttributes(Map attributes, String nameAttributesKey, String name, String email, SocialType socialType, String password) { + public OAuthAttributes(Map attributes, String nameAttributesKey, String name, String email, SocialType socialType) { this.attributes = attributes; this.nameAttributesKey = nameAttributesKey; this.name = name; this.email = email; this.socialType = socialType; - this.password = password; } } diff --git a/src/main/java/com/depromeet/fairer/dto/member/oauth/OauthLoginDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/member/oauth/OauthLoginDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/member/oauth/OauthLoginDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/member/oauth/OauthLoginDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/member/oauth/OauthRequestDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/member/oauth/OauthRequestDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/member/oauth/OauthRequestDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/member/oauth/OauthRequestDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/member/request/MemberUpdateRequestDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/member/request/MemberUpdateRequestDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/member/request/MemberUpdateRequestDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/member/request/MemberUpdateRequestDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/member/response/MemberProfileImageResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/member/response/MemberProfileImageResponseDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/member/response/MemberProfileImageResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/member/response/MemberProfileImageResponseDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/member/response/MemberResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/member/response/MemberResponseDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/member/response/MemberResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/member/response/MemberResponseDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/preset/response/HouseWorkPresetResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/preset/response/HouseWorkPresetResponseDto.java similarity index 90% rename from src/main/java/com/depromeet/fairer/dto/preset/response/HouseWorkPresetResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/preset/response/HouseWorkPresetResponseDto.java index 950a8c2d..d4870097 100644 --- a/src/main/java/com/depromeet/fairer/dto/preset/response/HouseWorkPresetResponseDto.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/preset/response/HouseWorkPresetResponseDto.java @@ -3,12 +3,14 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.ToString; import java.util.List; @NoArgsConstructor @AllArgsConstructor @Getter +@ToString public class HouseWorkPresetResponseDto { private String space; private List houseWorks; diff --git a/src/main/java/com/depromeet/fairer/dto/rule/request/RuleRequestDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/rule/request/RuleRequestDto.java similarity index 89% rename from src/main/java/com/depromeet/fairer/dto/rule/request/RuleRequestDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/rule/request/RuleRequestDto.java index ce587f7a..002dc5ce 100644 --- a/src/main/java/com/depromeet/fairer/dto/rule/request/RuleRequestDto.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/rule/request/RuleRequestDto.java @@ -7,13 +7,15 @@ import lombok.Data; import lombok.NoArgsConstructor; +import javax.validation.constraints.NotBlank; + @Data @Builder @NoArgsConstructor @AllArgsConstructor @ApiModel(value = "팀 규칙 요청 객체", description = "팀 규칙 요청 객체") public class RuleRequestDto { - @ApiModelProperty(value = "규칙 이름") + @NotBlank private String ruleName; } \ No newline at end of file diff --git a/src/main/java/com/depromeet/fairer/dto/rule/response/RuleResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/rule/response/RuleResponseDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/rule/response/RuleResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/rule/response/RuleResponseDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/rule/response/RulesResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/rule/response/RulesResponseDto.java similarity index 95% rename from src/main/java/com/depromeet/fairer/dto/rule/response/RulesResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/rule/response/RulesResponseDto.java index 75da1f31..615bef50 100644 --- a/src/main/java/com/depromeet/fairer/dto/rule/response/RulesResponseDto.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/rule/response/RulesResponseDto.java @@ -1,6 +1,5 @@ package com.depromeet.fairer.dto.rule.response; -import com.depromeet.fairer.domain.rule.Rule; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/depromeet/fairer/dto/team/TeamLeaveRequestDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/team/TeamLeaveRequestDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/team/TeamLeaveRequestDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/team/TeamLeaveRequestDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/team/request/TeamCreateRequestDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/team/request/TeamCreateRequestDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/team/request/TeamCreateRequestDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/team/request/TeamCreateRequestDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/team/request/TeamJoinRequestDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/team/request/TeamJoinRequestDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/team/request/TeamJoinRequestDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/team/request/TeamJoinRequestDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/team/request/TeamUpdateRequestDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/team/request/TeamUpdateRequestDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/team/request/TeamUpdateRequestDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/team/request/TeamUpdateRequestDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/team/response/TeamCreateResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/team/response/TeamCreateResponseDto.java similarity index 88% rename from src/main/java/com/depromeet/fairer/dto/team/response/TeamCreateResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/team/response/TeamCreateResponseDto.java index abd15c4f..f3105690 100644 --- a/src/main/java/com/depromeet/fairer/dto/team/response/TeamCreateResponseDto.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/dto/team/response/TeamCreateResponseDto.java @@ -1,6 +1,5 @@ package com.depromeet.fairer.dto.team.response; -import com.depromeet.fairer.domain.member.Member; import com.depromeet.fairer.domain.team.Team; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -9,9 +8,6 @@ import lombok.Data; import lombok.NoArgsConstructor; -import java.util.List; -import java.util.stream.Collectors; - @Data @Builder @ApiModel(value = "Team 생성 반환 객체", description = "Team 생성 반환 객체") diff --git a/src/main/java/com/depromeet/fairer/dto/team/response/TeamInfoResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/team/response/TeamInfoResponseDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/team/response/TeamInfoResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/team/response/TeamInfoResponseDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/team/response/TeamInviteCodeResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/team/response/TeamInviteCodeResponseDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/team/response/TeamInviteCodeResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/team/response/TeamInviteCodeResponseDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/team/response/TeamJoinResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/team/response/TeamJoinResponseDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/team/response/TeamJoinResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/team/response/TeamJoinResponseDto.java diff --git a/src/main/java/com/depromeet/fairer/dto/team/response/TeamUpdateResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/dto/team/response/TeamUpdateResponseDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/dto/team/response/TeamUpdateResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/dto/team/response/TeamUpdateResponseDto.java diff --git a/fairer-api/src/main/java/com/depromeet/fairer/global/aop/ControllerLoggingAspect.java b/fairer-api/src/main/java/com/depromeet/fairer/global/aop/ControllerLoggingAspect.java new file mode 100644 index 00000000..449cb5e3 --- /dev/null +++ b/fairer-api/src/main/java/com/depromeet/fairer/global/aop/ControllerLoggingAspect.java @@ -0,0 +1,30 @@ +package com.depromeet.fairer.global.aop; + +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.*; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; + +@Slf4j +@Aspect +@Component +public class ControllerLoggingAspect { + @Pointcut("execution(* com.depromeet.fairer.api.*.*(..))") + private void controllerPointCut(){} + + @Around(value = "controllerPointCut()") + public Object aroundControllerPointCut(ProceedingJoinPoint joinPoint) throws Throwable { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); + Object[] args = joinPoint.getArgs(); + log.info("[{}|{}] request : {}", request.getRequestURI(), request.getMethod(), args); + Object response = joinPoint.proceed(); + ResponseEntity responseEntity = (ResponseEntity)response; + log.info("[{}|{}] response : {}", request.getRequestURI(), responseEntity.getStatusCode(), responseEntity.getBody()); + return response; + } +} diff --git a/src/main/java/com/depromeet/fairer/global/config/ArgResolverConfig.java b/fairer-api/src/main/java/com/depromeet/fairer/global/config/ArgResolverConfig.java similarity index 100% rename from src/main/java/com/depromeet/fairer/global/config/ArgResolverConfig.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/config/ArgResolverConfig.java diff --git a/src/main/java/com/depromeet/fairer/global/config/FeignConfiguration.java b/fairer-api/src/main/java/com/depromeet/fairer/global/config/FeignConfiguration.java similarity index 100% rename from src/main/java/com/depromeet/fairer/global/config/FeignConfiguration.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/config/FeignConfiguration.java diff --git a/src/main/java/com/depromeet/fairer/global/config/MapperConfig.java b/fairer-api/src/main/java/com/depromeet/fairer/global/config/MapperConfig.java similarity index 65% rename from src/main/java/com/depromeet/fairer/global/config/MapperConfig.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/config/MapperConfig.java index 96b01582..a708c21b 100644 --- a/src/main/java/com/depromeet/fairer/global/config/MapperConfig.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/global/config/MapperConfig.java @@ -1,5 +1,8 @@ package com.depromeet.fairer.global.config; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.modelmapper.ModelMapper; @@ -18,6 +21,8 @@ public ModelMapper modelMapper() { public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.registerModule(new JavaTimeModule()); + objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); return objectMapper; } } diff --git a/src/main/java/com/depromeet/fairer/global/config/QuerydslConfig.java b/fairer-api/src/main/java/com/depromeet/fairer/global/config/QuerydslConfig.java similarity index 100% rename from src/main/java/com/depromeet/fairer/global/config/QuerydslConfig.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/config/QuerydslConfig.java diff --git a/src/main/java/com/depromeet/fairer/global/config/SecurityConfig.java b/fairer-api/src/main/java/com/depromeet/fairer/global/config/SecurityConfig.java similarity index 87% rename from src/main/java/com/depromeet/fairer/global/config/SecurityConfig.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/config/SecurityConfig.java index 170a3d04..5839cfb1 100644 --- a/src/main/java/com/depromeet/fairer/global/config/SecurityConfig.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/global/config/SecurityConfig.java @@ -2,9 +2,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; -import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -20,7 +18,7 @@ protected void configure(HttpSecurity http) throws Exception { .csrf().disable().headers().frameOptions().disable() .and() .authorizeRequests() // url별 권한 관리를 설정하는 옵션의 시작점 - .antMatchers("/oauth/login").permitAll() + .antMatchers("/oauth/login", "/fcm/message").permitAll() .antMatchers("/", "/css/**", "**.html", "/images/**", "/js/**" , "/assets/**", "/swagger-ui.html").permitAll(); } diff --git a/src/main/java/com/depromeet/fairer/global/config/SwaggerConfig.java b/fairer-api/src/main/java/com/depromeet/fairer/global/config/SwaggerConfig.java similarity index 100% rename from src/main/java/com/depromeet/fairer/global/config/SwaggerConfig.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/config/SwaggerConfig.java diff --git a/fairer-api/src/main/java/com/depromeet/fairer/global/config/TaskExecutorConfig.java b/fairer-api/src/main/java/com/depromeet/fairer/global/config/TaskExecutorConfig.java new file mode 100644 index 00000000..31378409 --- /dev/null +++ b/fairer-api/src/main/java/com/depromeet/fairer/global/config/TaskExecutorConfig.java @@ -0,0 +1,18 @@ +package com.depromeet.fairer.global.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +@Configuration +public class TaskExecutorConfig { + @Bean(name = "fcmTaskExecutor") + public ThreadPoolTaskExecutor fcmTaskExecutor() { + ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); + taskExecutor.setCorePoolSize(20); + taskExecutor.setMaxPoolSize(100); + taskExecutor.setQueueCapacity(200); + taskExecutor.setThreadNamePrefix("fcm-"); + return taskExecutor; + } +} diff --git a/src/main/java/com/depromeet/fairer/global/config/WebConfig.java b/fairer-api/src/main/java/com/depromeet/fairer/global/config/WebConfig.java similarity index 96% rename from src/main/java/com/depromeet/fairer/global/config/WebConfig.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/config/WebConfig.java index 62ed73d6..467a5bfa 100644 --- a/src/main/java/com/depromeet/fairer/global/config/WebConfig.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/global/config/WebConfig.java @@ -7,7 +7,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; -import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -24,7 +23,7 @@ public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authInterceptor()) .order(1) .addPathPatterns("/api/**") - .excludePathPatterns("/api/oauth/login", "/api/member/profile-image"); + .excludePathPatterns("/api/oauth/login", "/api/member/profile-image", "/api/fcm/message"); } @Bean diff --git a/src/main/java/com/depromeet/fairer/global/config/Workaround.java b/fairer-api/src/main/java/com/depromeet/fairer/global/config/Workaround.java similarity index 100% rename from src/main/java/com/depromeet/fairer/global/config/Workaround.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/config/Workaround.java diff --git a/src/main/java/com/depromeet/fairer/global/config/XssConfig.java b/fairer-api/src/main/java/com/depromeet/fairer/global/config/XssConfig.java similarity index 96% rename from src/main/java/com/depromeet/fairer/global/config/XssConfig.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/config/XssConfig.java index 16d2e646..fdc40754 100644 --- a/src/main/java/com/depromeet/fairer/global/config/XssConfig.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/global/config/XssConfig.java @@ -6,8 +6,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import javax.servlet.Filter; - @Configuration public class XssConfig implements WebMvcConfigurer { diff --git a/src/main/java/com/depromeet/fairer/global/config/interceptor/AuthInterceptor.java b/fairer-api/src/main/java/com/depromeet/fairer/global/config/interceptor/AuthInterceptor.java similarity index 100% rename from src/main/java/com/depromeet/fairer/global/config/interceptor/AuthInterceptor.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/config/interceptor/AuthInterceptor.java diff --git a/src/main/java/com/depromeet/fairer/global/exception/BadRequestException.java b/fairer-api/src/main/java/com/depromeet/fairer/global/exception/BadRequestException.java similarity index 100% rename from src/main/java/com/depromeet/fairer/global/exception/BadRequestException.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/exception/BadRequestException.java diff --git a/src/main/java/com/depromeet/fairer/global/exception/CannotJoinTeamException.java b/fairer-api/src/main/java/com/depromeet/fairer/global/exception/CannotJoinTeamException.java similarity index 100% rename from src/main/java/com/depromeet/fairer/global/exception/CannotJoinTeamException.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/exception/CannotJoinTeamException.java diff --git a/fairer-api/src/main/java/com/depromeet/fairer/global/exception/FairerException.java b/fairer-api/src/main/java/com/depromeet/fairer/global/exception/FairerException.java new file mode 100644 index 00000000..cc0ba177 --- /dev/null +++ b/fairer-api/src/main/java/com/depromeet/fairer/global/exception/FairerException.java @@ -0,0 +1,7 @@ +package com.depromeet.fairer.global.exception; + +public class FairerException extends RuntimeException { + public FairerException(String message) { + super(message); + } +} diff --git a/src/main/java/com/depromeet/fairer/global/exception/FeignClientException.java b/fairer-api/src/main/java/com/depromeet/fairer/global/exception/FeignClientException.java similarity index 100% rename from src/main/java/com/depromeet/fairer/global/exception/FeignClientException.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/exception/FeignClientException.java diff --git a/src/main/java/com/depromeet/fairer/global/exception/MemberTokenNotFoundException.java b/fairer-api/src/main/java/com/depromeet/fairer/global/exception/MemberTokenNotFoundException.java similarity index 100% rename from src/main/java/com/depromeet/fairer/global/exception/MemberTokenNotFoundException.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/exception/MemberTokenNotFoundException.java diff --git a/src/main/java/com/depromeet/fairer/global/exception/NoSuchMemberException.java b/fairer-api/src/main/java/com/depromeet/fairer/global/exception/NoSuchMemberException.java similarity index 83% rename from src/main/java/com/depromeet/fairer/global/exception/NoSuchMemberException.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/exception/NoSuchMemberException.java index 082d619f..5ea66c39 100644 --- a/src/main/java/com/depromeet/fairer/global/exception/NoSuchMemberException.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/global/exception/NoSuchMemberException.java @@ -1,7 +1,5 @@ package com.depromeet.fairer.global.exception; -import java.util.function.Supplier; - public class NoSuchMemberException extends RuntimeException { public NoSuchMemberException(String message) { super(message); diff --git a/src/main/java/com/depromeet/fairer/global/exception/PermissionDeniedException.java b/fairer-api/src/main/java/com/depromeet/fairer/global/exception/PermissionDeniedException.java similarity index 100% rename from src/main/java/com/depromeet/fairer/global/exception/PermissionDeniedException.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/exception/PermissionDeniedException.java diff --git a/src/main/java/com/depromeet/fairer/global/exception/dto/ErrorResponseDto.java b/fairer-api/src/main/java/com/depromeet/fairer/global/exception/dto/ErrorResponseDto.java similarity index 100% rename from src/main/java/com/depromeet/fairer/global/exception/dto/ErrorResponseDto.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/exception/dto/ErrorResponseDto.java diff --git a/src/main/java/com/depromeet/fairer/global/exception/handler/FeignClientExceptionErrorDecoder.java b/fairer-api/src/main/java/com/depromeet/fairer/global/exception/handler/FeignClientExceptionErrorDecoder.java similarity index 95% rename from src/main/java/com/depromeet/fairer/global/exception/handler/FeignClientExceptionErrorDecoder.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/exception/handler/FeignClientExceptionErrorDecoder.java index d8d3fa96..64c09650 100644 --- a/src/main/java/com/depromeet/fairer/global/exception/handler/FeignClientExceptionErrorDecoder.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/global/exception/handler/FeignClientExceptionErrorDecoder.java @@ -1,7 +1,6 @@ package com.depromeet.fairer.global.exception.handler; import com.depromeet.fairer.global.exception.FeignClientException; -import feign.FeignException; import feign.Response; import feign.codec.ErrorDecoder; import feign.codec.StringDecoder; diff --git a/src/main/java/com/depromeet/fairer/global/exception/handler/GlobalExceptionHandler.java b/fairer-api/src/main/java/com/depromeet/fairer/global/exception/handler/GlobalExceptionHandler.java similarity index 95% rename from src/main/java/com/depromeet/fairer/global/exception/handler/GlobalExceptionHandler.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/exception/handler/GlobalExceptionHandler.java index 682b3b1e..0b5f24fc 100644 --- a/src/main/java/com/depromeet/fairer/global/exception/handler/GlobalExceptionHandler.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/global/exception/handler/GlobalExceptionHandler.java @@ -15,7 +15,6 @@ import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import javax.servlet.http.HttpServletRequest; -import java.nio.file.AccessDeniedException; import java.util.List; @RestControllerAdvice @@ -117,6 +116,11 @@ protected ResponseEntity handleMemberTokenNotFoundException(Me return exceptionResponseEntity(e.getMessage(), HttpStatus.NOT_FOUND, request.getRequestURI()); } + @ExceptionHandler(FairerException.class) + protected ResponseEntity handleFairerException(FairerException e, HttpServletRequest request) { + log.error("FairerException", e); + return exceptionResponseEntity(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR, request.getRequestURI()); + } /** diff --git a/fairer-api/src/main/java/com/depromeet/fairer/global/factory/RestTemplateFactory.java b/fairer-api/src/main/java/com/depromeet/fairer/global/factory/RestTemplateFactory.java new file mode 100644 index 00000000..74e0cacf --- /dev/null +++ b/fairer-api/src/main/java/com/depromeet/fairer/global/factory/RestTemplateFactory.java @@ -0,0 +1,11 @@ +package com.depromeet.fairer.global.factory; + +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.web.client.RestTemplate; + +public class RestTemplateFactory { + public static RestTemplate getRestTemplate() { + return new RestTemplateBuilder() + .build(); + } +} diff --git a/src/main/java/com/depromeet/fairer/global/resolver/RequestMemberId.java b/fairer-api/src/main/java/com/depromeet/fairer/global/resolver/RequestMemberId.java similarity index 85% rename from src/main/java/com/depromeet/fairer/global/resolver/RequestMemberId.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/resolver/RequestMemberId.java index 28e00486..78ea8f5b 100644 --- a/src/main/java/com/depromeet/fairer/global/resolver/RequestMemberId.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/global/resolver/RequestMemberId.java @@ -1,7 +1,5 @@ package com.depromeet.fairer.global.resolver; -import springfox.documentation.annotations.ApiIgnore; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/src/main/java/com/depromeet/fairer/global/resolver/RequestMemberIdArgumentResolver.java b/fairer-api/src/main/java/com/depromeet/fairer/global/resolver/RequestMemberIdArgumentResolver.java similarity index 96% rename from src/main/java/com/depromeet/fairer/global/resolver/RequestMemberIdArgumentResolver.java rename to fairer-api/src/main/java/com/depromeet/fairer/global/resolver/RequestMemberIdArgumentResolver.java index b2de253e..a3ed9c46 100644 --- a/src/main/java/com/depromeet/fairer/global/resolver/RequestMemberIdArgumentResolver.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/global/resolver/RequestMemberIdArgumentResolver.java @@ -1,6 +1,5 @@ package com.depromeet.fairer.global.resolver; -import com.depromeet.fairer.domain.member.Member; import com.depromeet.fairer.service.member.jwt.TokenProvider; import lombok.extern.slf4j.Slf4j; import org.springframework.core.MethodParameter; diff --git a/fairer-api/src/main/java/com/depromeet/fairer/global/util/DateTimeUtils.java b/fairer-api/src/main/java/com/depromeet/fairer/global/util/DateTimeUtils.java new file mode 100644 index 00000000..0ae34422 --- /dev/null +++ b/fairer-api/src/main/java/com/depromeet/fairer/global/util/DateTimeUtils.java @@ -0,0 +1,23 @@ +package com.depromeet.fairer.global.util; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.Date; + +public class DateTimeUtils { + public static LocalDateTime convertToLocalDateTime(Date date) { + return date.toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDateTime(); + } + + public static LocalDate stringToLocalDate(String localDate) { + return LocalDate.parse(localDate, DateTimeFormatter.ISO_DATE); + } + + public static String localDateToString(LocalDate localDate) { + return localDate.format(DateTimeFormatter.ISO_DATE); + } +} diff --git a/src/main/java/com/depromeet/fairer/repository/assignment/AssignmentRepository.java b/fairer-api/src/main/java/com/depromeet/fairer/repository/assignment/AssignmentRepository.java similarity index 100% rename from src/main/java/com/depromeet/fairer/repository/assignment/AssignmentRepository.java rename to fairer-api/src/main/java/com/depromeet/fairer/repository/assignment/AssignmentRepository.java diff --git a/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkCustomRepository.java b/fairer-api/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkCustomRepository.java similarity index 57% rename from src/main/java/com/depromeet/fairer/repository/housework/HouseWorkCustomRepository.java rename to fairer-api/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkCustomRepository.java index 88057099..1cc4716b 100644 --- a/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkCustomRepository.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkCustomRepository.java @@ -1,12 +1,7 @@ package com.depromeet.fairer.repository.housework; -import com.depromeet.fairer.domain.housework.HouseWork; - import java.time.LocalDate; -import java.util.List; public interface HouseWorkCustomRepository { Long getHouseWorkSuccessCount(Long memberId, LocalDate startDate, LocalDate endDate); - - // List getHouseWorkList(LocalDate scheduledDate, Long memberId); } diff --git a/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkCustomRepositoryImpl.java b/fairer-api/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkCustomRepositoryImpl.java similarity index 93% rename from src/main/java/com/depromeet/fairer/repository/housework/HouseWorkCustomRepositoryImpl.java rename to fairer-api/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkCustomRepositoryImpl.java index 0cee9742..44133b9c 100644 --- a/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkCustomRepositoryImpl.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkCustomRepositoryImpl.java @@ -1,12 +1,10 @@ package com.depromeet.fairer.repository.housework; -import com.depromeet.fairer.domain.housework.HouseWork; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; import java.time.LocalDate; -import java.util.List; import static com.depromeet.fairer.domain.assignment.QAssignment.assignment; import static com.depromeet.fairer.domain.housework.QHouseWork.houseWork; diff --git a/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkRepository.java b/fairer-api/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkRepository.java similarity index 66% rename from src/main/java/com/depromeet/fairer/repository/housework/HouseWorkRepository.java rename to fairer-api/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkRepository.java index 4c37cf6a..6ee486bf 100644 --- a/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkRepository.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/repository/housework/HouseWorkRepository.java @@ -2,21 +2,17 @@ import com.depromeet.fairer.domain.assignment.Assignment; import com.depromeet.fairer.domain.housework.HouseWork; -import com.depromeet.fairer.domain.member.Member; -import org.apache.tomcat.jni.Local; -import org.springframework.data.jpa.repository.EntityGraph; +import com.depromeet.fairer.domain.team.Team; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.time.LocalDate; import java.util.List; -import java.util.Optional; @Repository public interface HouseWorkRepository extends JpaRepository, HouseWorkCustomRepository { List findAllByScheduledDateAndAssignmentsIn(LocalDate scheduledDate, List assignments); - -// @EntityGraph(attributePaths = {"assignments"}) -// List findHouseWorksByMember(Member member); + List findAllByScheduledDateBetweenAndAssignmentsIn(LocalDate fromDate, LocalDate toDate, List assignments); + List findAllByScheduledDateBetweenAndTeam(LocalDate fromDate, LocalDate toDate, Team team); } \ No newline at end of file diff --git a/src/main/java/com/depromeet/fairer/repository/member/MemberCustomRepository.java b/fairer-api/src/main/java/com/depromeet/fairer/repository/member/MemberCustomRepository.java similarity index 99% rename from src/main/java/com/depromeet/fairer/repository/member/MemberCustomRepository.java rename to fairer-api/src/main/java/com/depromeet/fairer/repository/member/MemberCustomRepository.java index e238d10c..e91f26f8 100644 --- a/src/main/java/com/depromeet/fairer/repository/member/MemberCustomRepository.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/repository/member/MemberCustomRepository.java @@ -6,5 +6,4 @@ public interface MemberCustomRepository { List getMemberDtoListByHouseWorkId(Long houseWorkId); - } diff --git a/src/main/java/com/depromeet/fairer/repository/member/MemberCustomRepositoryImpl.java b/fairer-api/src/main/java/com/depromeet/fairer/repository/member/MemberCustomRepositoryImpl.java similarity index 100% rename from src/main/java/com/depromeet/fairer/repository/member/MemberCustomRepositoryImpl.java rename to fairer-api/src/main/java/com/depromeet/fairer/repository/member/MemberCustomRepositoryImpl.java diff --git a/src/main/java/com/depromeet/fairer/repository/member/MemberRepository.java b/fairer-api/src/main/java/com/depromeet/fairer/repository/member/MemberRepository.java similarity index 93% rename from src/main/java/com/depromeet/fairer/repository/member/MemberRepository.java rename to fairer-api/src/main/java/com/depromeet/fairer/repository/member/MemberRepository.java index 04b9557f..2b53645e 100644 --- a/src/main/java/com/depromeet/fairer/repository/member/MemberRepository.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/repository/member/MemberRepository.java @@ -11,8 +11,6 @@ @Repository public interface MemberRepository extends JpaRepository, MemberCustomRepository { - Optional findByEmail(String email); - List findAllByTeam(Team team); @EntityGraph(attributePaths = {"team"}) @@ -20,4 +18,5 @@ public interface MemberRepository extends JpaRepository, MemberCus @EntityGraph(attributePaths = {"team"}) Optional findWithTeamByMemberId(Long memberId); + } \ No newline at end of file diff --git a/src/main/java/com/depromeet/fairer/repository/memberToken/MemberTokenRepository.java b/fairer-api/src/main/java/com/depromeet/fairer/repository/memberToken/MemberTokenRepository.java similarity index 84% rename from src/main/java/com/depromeet/fairer/repository/memberToken/MemberTokenRepository.java rename to fairer-api/src/main/java/com/depromeet/fairer/repository/memberToken/MemberTokenRepository.java index 4c94867c..0d61c2a6 100644 --- a/src/main/java/com/depromeet/fairer/repository/memberToken/MemberTokenRepository.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/repository/memberToken/MemberTokenRepository.java @@ -2,7 +2,6 @@ import com.depromeet.fairer.domain.memberToken.MemberToken; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.support.SimpleJpaRepository; import org.springframework.stereotype.Repository; import java.util.Optional; diff --git a/src/main/java/com/depromeet/fairer/repository/rule/RuleRepository.java b/fairer-api/src/main/java/com/depromeet/fairer/repository/rule/RuleRepository.java similarity index 92% rename from src/main/java/com/depromeet/fairer/repository/rule/RuleRepository.java rename to fairer-api/src/main/java/com/depromeet/fairer/repository/rule/RuleRepository.java index c141dd82..8144f195 100644 --- a/src/main/java/com/depromeet/fairer/repository/rule/RuleRepository.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/repository/rule/RuleRepository.java @@ -11,4 +11,5 @@ public interface RuleRepository extends JpaRepository { List findAllByTeam(Team team); + long countByTeam(Team team); } diff --git a/src/main/java/com/depromeet/fairer/repository/team/TeamRepository.java b/fairer-api/src/main/java/com/depromeet/fairer/repository/team/TeamRepository.java similarity index 82% rename from src/main/java/com/depromeet/fairer/repository/team/TeamRepository.java rename to fairer-api/src/main/java/com/depromeet/fairer/repository/team/TeamRepository.java index bb59ccc5..19687bfb 100644 --- a/src/main/java/com/depromeet/fairer/repository/team/TeamRepository.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/repository/team/TeamRepository.java @@ -9,10 +9,6 @@ @Repository public interface TeamRepository extends JpaRepository { - - @EntityGraph(attributePaths = {"members"}) - Optional findWithMembersByTeamId(Long teamId); - @EntityGraph(attributePaths = {"members"}) Optional findWithMembersByInviteCode(String inviteCode); } diff --git a/fairer-api/src/main/java/com/depromeet/fairer/service/fcm/FCMService.java b/fairer-api/src/main/java/com/depromeet/fairer/service/fcm/FCMService.java new file mode 100644 index 00000000..e5de0e38 --- /dev/null +++ b/fairer-api/src/main/java/com/depromeet/fairer/service/fcm/FCMService.java @@ -0,0 +1,100 @@ +package com.depromeet.fairer.service.fcm; + +import com.depromeet.fairer.domain.member.Member; +import com.depromeet.fairer.dto.fcm.FCMSendRequest; +import com.depromeet.fairer.dto.fcm.request.FCMMessageRequest; +import com.depromeet.fairer.dto.fcm.request.SaveTokenRequest; +import com.depromeet.fairer.dto.fcm.response.FCMMessageResponse; +import com.depromeet.fairer.dto.fcm.response.SaveTokenResponse; +import com.depromeet.fairer.global.exception.FairerException; +import com.depromeet.fairer.global.factory.RestTemplateFactory; +import com.depromeet.fairer.repository.member.MemberRepository; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.auth.oauth2.GoogleCredentials; +import com.google.firebase.messaging.Message; +import com.google.firebase.messaging.Notification; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.List; + +@Slf4j +@Service +@RequiredArgsConstructor +public class FCMService { + private static final String FCM_DOMAIN = "https://fcm.googleapis.com/v1/projects/fairer-def59/messages:send"; + private static final String FIREBASE_KEY_PATH = "firebase/fairer-def59-firebase-adminsdk-uvxs2-2b35d6203d.json"; + private static final RestTemplate restTemplate = RestTemplateFactory.getRestTemplate(); + private final ObjectMapper objectMapper; + + private final MemberRepository memberRepository; + + public SaveTokenResponse saveToken(SaveTokenRequest request, Long memberId) { + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new IllegalArgumentException("memberId에 해당하는 회원을 찾지 못했습니다.")); + member.setFcmToken(request.getToken()); + member.setFcmTokenDate(LocalDateTime.now()); + memberRepository.save(member); + return SaveTokenResponse.of(request.getToken()); + } + + public FCMMessageResponse sendMessage(FCMMessageRequest fcmMessageRequest) { + Member member = memberRepository.findById(fcmMessageRequest.getMemberId()) + .orElseThrow(() -> new IllegalArgumentException("memberId에 해당하는 회원을 찾지 못했습니다.")); + + FCMSendRequest fcmSendRequest = createMessage(member.getFcmToken(), fcmMessageRequest.getTitle(), fcmMessageRequest.getBody()); + String body = convertFCMSendRequestToString(fcmSendRequest); + this.sendFCMMessage(body); + + return FCMMessageResponse.of(fcmMessageRequest.getTitle(), fcmMessageRequest.getBody(), fcmMessageRequest.getMemberId()); + } + + private String convertFCMSendRequestToString(FCMSendRequest fcmSendRequest) { + try { + return objectMapper.writeValueAsString(fcmSendRequest); + } catch (JsonProcessingException e) { + throw new FairerException("객체 파싱 실패"); + } + } + + private FCMSendRequest createMessage(String token, String title, String body) { + Message message = Message.builder() + .setToken(token) + .setNotification(Notification.builder() + .setTitle(title) + .setBody(body) + .build()) + .build(); + + return FCMSendRequest.of(message, false); + } + + @Async(value = "fcmTaskExecutor") + private void sendFCMMessage(String body) { + try { + HttpHeaders headers = new HttpHeaders(); + headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + getAccessToken()); + headers.add(HttpHeaders.CONTENT_TYPE, "application/json; UTF-8"); + + HttpEntity request = new HttpEntity<>(body, headers); + String message = restTemplate.postForObject(FCM_DOMAIN, request, String.class); + } catch (Exception e) { + log.error("Error to send message. body : {}", body, e); + } + } + + private String getAccessToken() throws IOException { + GoogleCredentials googleCredentials = GoogleCredentials.fromStream(new ClassPathResource(FIREBASE_KEY_PATH).getInputStream()).createScoped(List.of("https://www.googleapis.com/auth/cloud-platform")); + googleCredentials.refreshIfExpired(); + return googleCredentials.getAccessToken().getTokenValue(); + } +} diff --git a/src/main/java/com/depromeet/fairer/service/housework/HouseWorkService.java b/fairer-api/src/main/java/com/depromeet/fairer/service/housework/HouseWorkService.java similarity index 79% rename from src/main/java/com/depromeet/fairer/service/housework/HouseWorkService.java rename to fairer-api/src/main/java/com/depromeet/fairer/service/housework/HouseWorkService.java index 1e39f361..1440c545 100644 --- a/src/main/java/com/depromeet/fairer/service/housework/HouseWorkService.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/service/housework/HouseWorkService.java @@ -13,6 +13,7 @@ import com.depromeet.fairer.repository.housework.HouseWorkRepository; import com.depromeet.fairer.repository.member.MemberRepository; import com.depromeet.fairer.service.member.MemberService; +import com.depromeet.fairer.service.team.TeamService; import com.depromeet.fairer.vo.houseWork.HouseWorkUpdateVo; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -24,10 +25,7 @@ import java.time.DayOfWeek; import java.time.LocalDateTime; import java.time.temporal.TemporalAdjusters; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; @Slf4j @@ -39,6 +37,7 @@ public class HouseWorkService { private final MemberRepository memberRepository; private final AssignmentRepository assignmentRepository; private final MemberService memberService; + private final TeamService teamService; public List createHouseWorks(Long memberId, List houseWorksDto) { @@ -71,7 +70,6 @@ private HouseWorkResponseDto createHouseWork(Long memberId, HouseWorkUpdateReque return HouseWorkResponseDto.from(houseWork, memberDtoList); } - @Transactional public HouseWorkResponseDto updateHouseWork(HouseWorkUpdateVo houseWorkUpdateVo) { Member member = memberService.findWithTeam(houseWorkUpdateVo.getMemberId()); HouseWork houseWork = getHouseWorkById(houseWorkUpdateVo.getHouseWorkId()); @@ -106,7 +104,6 @@ public HouseWorkResponseDto updateHouseWork(HouseWorkUpdateVo houseWorkUpdateVo) return HouseWorkResponseDto.from(houseWork, memberDtoList); } - @Transactional public void deleteHouseWork(Long memberId, Long houseWorkId) { try { HouseWork houseWork = houseWorkRepository.getById(houseWorkId); @@ -122,39 +119,13 @@ public void deleteHouseWork(Long memberId, Long houseWorkId) { } public HouseWorkSuccessCountResponseDto getSuccessCount(String scheduledDate, Long memberId) { - LocalDate startDate = LocalDate.parse(scheduledDate).with(TemporalAdjusters.previous(DayOfWeek.MONDAY)); - LocalDate endDate = LocalDate.parse(scheduledDate).with(TemporalAdjusters.previous(DayOfWeek.SUNDAY)).plusWeeks(1); + LocalDate startDate = LocalDate.parse(scheduledDate).with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY)); + LocalDate endDate = LocalDate.parse(scheduledDate).with(TemporalAdjusters.nextOrSame(DayOfWeek.SATURDAY)); Long count = houseWorkRepository.getHouseWorkSuccessCount(memberId, startDate, endDate); return HouseWorkSuccessCountResponseDto.of(count); } -// @Transactional -// public HouseWorkMemberResponseDto getHouseWork(LocalDate scheduledDate, Long memberId){ -// Team team = memberService.findWithTeam(memberId).getTeam(); -// List memberList = memberRepository.findAllByTeam(team); -// -// List houseWorkDateResponseDtos = new ArrayList<>(); -// -// for (Member memberr : memberList){ -// List assignmentList = assignmentRepository.findAllByMember(memberr); -// List houseWorkList = houseWorkRepository.findAllByScheduledDateAndAssignmentsIn(scheduledDate, assignmentList); -// -// List houseWorkResponseDtoList = houseWorkList.stream().map(houseWork -> { -// List memberDtoList = memberRepository.getMemberDtoListByHouseWorkId(houseWork.getHouseWorkId()).stream().map(MemberDto::from).collect(Collectors.toList()); -// -// return HouseWorkResponseDto.from(houseWork, memberDtoList); -// }).collect(Collectors.toList()); -// -// long countDone = houseWorkResponseDtoList.stream().filter(HouseWorkResponseDto::getSuccess).count(); -// long countLeft = houseWorkResponseDtoList.stream().filter(houseWorkResponseDto -> !houseWorkResponseDto.getSuccess()).count(); -// -// houseWorkDateResponseDtos.add(HouseWorkDateResponseDto.from(memberr.getMemberId(), scheduledDate, countDone, countLeft, houseWorkResponseDtoList)); -// } -// -// return HouseWorkMemberResponseDto.from(team.getTeamId(), houseWorkDateResponseDtos); -// } - - @Transactional + @Deprecated public List getHouseWorks(LocalDate scheduledDate, Member member) { List assignmentList = assignmentRepository.findAllByMember(member); List houseWorkList = houseWorkRepository.findAllByScheduledDateAndAssignmentsIn(scheduledDate, assignmentList); @@ -162,15 +133,21 @@ public List getHouseWorks(LocalDate scheduledDate, Member member) { return houseWorkList; } + public List getHouseWorkByDate(Member member, LocalDate fromDate, LocalDate toDate) { + List assignmentList = assignmentRepository.findAllByMember(member); + return houseWorkRepository.findAllByScheduledDateBetweenAndAssignmentsIn(fromDate, toDate, assignmentList); + } + + public List getHouseWorkByDateAndTeam(Team team, LocalDate fromDate, LocalDate toDate) { + return houseWorkRepository.findAllByScheduledDateBetweenAndTeam(fromDate, toDate, team); + } - @Transactional public HouseWorkResponseDto getHouseWorkDetail(Long houseWorkId) { HouseWork houseWork = getHouseWorkById(houseWorkId); List memberDtoList = memberRepository.getMemberDtoListByHouseWorkId(houseWorkId).stream().map(MemberDto::from).collect(Collectors.toList()); return HouseWorkResponseDto.from(houseWork, memberDtoList); } - @Transactional public HouseWorkStatusResponseDto updateHouseWorkStatus(Long houseWorkId, int toBeStatus) { boolean status = toBeStatus == 1; diff --git a/src/main/java/com/depromeet/fairer/service/member/MemberService.java b/fairer-api/src/main/java/com/depromeet/fairer/service/member/MemberService.java similarity index 99% rename from src/main/java/com/depromeet/fairer/service/member/MemberService.java rename to fairer-api/src/main/java/com/depromeet/fairer/service/member/MemberService.java index 2f09dc65..9f2ab00c 100644 --- a/src/main/java/com/depromeet/fairer/service/member/MemberService.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/service/member/MemberService.java @@ -13,7 +13,6 @@ import java.util.List; - @Service @Transactional @RequiredArgsConstructor @@ -42,4 +41,5 @@ public Member updateMember(Long memberId, String memberName, String profilePath, Member member = this.find(memberId); member.update(memberName, profilePath, statusMessage); return memberRepository.save(member); - }} + } +} diff --git a/src/main/java/com/depromeet/fairer/service/member/jwt/TokenProvider.java b/fairer-api/src/main/java/com/depromeet/fairer/service/member/jwt/TokenProvider.java similarity index 100% rename from src/main/java/com/depromeet/fairer/service/member/jwt/TokenProvider.java rename to fairer-api/src/main/java/com/depromeet/fairer/service/member/jwt/TokenProvider.java diff --git a/src/main/java/com/depromeet/fairer/service/member/oauth/OauthLoginService.java b/fairer-api/src/main/java/com/depromeet/fairer/service/member/oauth/OauthLoginService.java similarity index 100% rename from src/main/java/com/depromeet/fairer/service/member/oauth/OauthLoginService.java rename to fairer-api/src/main/java/com/depromeet/fairer/service/member/oauth/OauthLoginService.java diff --git a/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleAuthFeignClient.java b/fairer-api/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleAuthFeignClient.java similarity index 97% rename from src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleAuthFeignClient.java rename to fairer-api/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleAuthFeignClient.java index 4f5e414b..a0cb10e8 100644 --- a/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleAuthFeignClient.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleAuthFeignClient.java @@ -1,6 +1,5 @@ package com.depromeet.fairer.service.member.oauth.google; -import feign.Headers; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.PostMapping; diff --git a/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleFeignService.java b/fairer-api/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleFeignService.java similarity index 97% rename from src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleFeignService.java rename to fairer-api/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleFeignService.java index e1fc7a6b..dd5a078f 100644 --- a/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleFeignService.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleFeignService.java @@ -36,7 +36,6 @@ public class GoogleFeignService { @Value("${oauth2.clientSecret}") private String CLIENT_SECRET; - private final String PASSWORD = "autoPassword"; private final String GRANT_TYPE = "authorization_code"; private final String REQUEST_URI = "https://www.googleapis.com/oauth2/v4/token"; @@ -53,7 +52,6 @@ public OAuthAttributes getUserInfo(String accessToken) { .email(StringUtils.isBlank(googleUserInfo.getEmail()) ? googleUserInfo.getId() : googleUserInfo.getEmail()) // 이메일 동의 x 경우 .name(googleUserInfo.getName()) .socialType(SocialType.GOOGLE) - .password(passwordEncoder.encode(PASSWORD)) .build(); } diff --git a/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleInfoFeignClient.java b/fairer-api/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleInfoFeignClient.java similarity index 96% rename from src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleInfoFeignClient.java rename to fairer-api/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleInfoFeignClient.java index 280d3ae1..1c6e2fc3 100644 --- a/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleInfoFeignClient.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/service/member/oauth/google/GoogleInfoFeignClient.java @@ -1,7 +1,6 @@ package com.depromeet.fairer.service.member.oauth.google; import com.depromeet.fairer.dto.member.oauth.GoogleUserInfo; -import feign.Headers; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.*; diff --git a/src/main/java/com/depromeet/fairer/service/member/oauth/google/OauthTokenResponse.java b/fairer-api/src/main/java/com/depromeet/fairer/service/member/oauth/google/OauthTokenResponse.java similarity index 100% rename from src/main/java/com/depromeet/fairer/service/member/oauth/google/OauthTokenResponse.java rename to fairer-api/src/main/java/com/depromeet/fairer/service/member/oauth/google/OauthTokenResponse.java diff --git a/src/main/java/com/depromeet/fairer/service/rule/RuleService.java b/fairer-api/src/main/java/com/depromeet/fairer/service/rule/RuleService.java similarity index 80% rename from src/main/java/com/depromeet/fairer/service/rule/RuleService.java rename to fairer-api/src/main/java/com/depromeet/fairer/service/rule/RuleService.java index b1b2a185..8b407cc6 100644 --- a/src/main/java/com/depromeet/fairer/service/rule/RuleService.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/service/rule/RuleService.java @@ -2,10 +2,8 @@ import com.depromeet.fairer.domain.rule.Rule; import com.depromeet.fairer.domain.team.Team; -import com.depromeet.fairer.dto.rule.request.RuleRequestDto; import com.depromeet.fairer.repository.rule.RuleRepository; import com.depromeet.fairer.service.member.MemberService; -import com.depromeet.fairer.service.team.TeamService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -21,12 +19,9 @@ public class RuleService { private final MemberService memberService; @Transactional - public Rule createRules(Long memberId, String ruleName){ - Team team = memberService.findWithTeam(memberId).getTeam(); + public Rule createRules(Team team, String ruleName){ Rule rule = Rule.builder().team(team).ruleName(ruleName).build(); - ruleRepository.save(rule); - - return rule; + return ruleRepository.save(rule); } @Transactional @@ -43,4 +38,9 @@ public List deleteRules(Long memberId, Long ruleId){ public List findAllByTeam(Team team) { return ruleRepository.findAllByTeam(team); } + + public Long countRules(Team team) { + return ruleRepository.countByTeam(team); + } + } diff --git a/src/main/java/com/depromeet/fairer/service/team/TeamService.java b/fairer-api/src/main/java/com/depromeet/fairer/service/team/TeamService.java similarity index 78% rename from src/main/java/com/depromeet/fairer/service/team/TeamService.java rename to fairer-api/src/main/java/com/depromeet/fairer/service/team/TeamService.java index 9bd0bbfb..76c8400f 100644 --- a/src/main/java/com/depromeet/fairer/service/team/TeamService.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/service/team/TeamService.java @@ -4,13 +4,17 @@ import com.depromeet.fairer.domain.assignment.Assignment; import com.depromeet.fairer.domain.member.Member; import com.depromeet.fairer.domain.team.Team; +import com.depromeet.fairer.dto.fcm.FCMMessageTemplate; +import com.depromeet.fairer.dto.fcm.request.FCMMessageRequest; import com.depromeet.fairer.global.exception.BadRequestException; import com.depromeet.fairer.global.exception.CannotJoinTeamException; import com.depromeet.fairer.global.exception.MemberTokenNotFoundException; +import com.depromeet.fairer.global.exception.PermissionDeniedException; import com.depromeet.fairer.repository.assignment.AssignmentRepository; import com.depromeet.fairer.repository.housework.HouseWorkRepository; import com.depromeet.fairer.repository.member.MemberRepository; import com.depromeet.fairer.repository.team.TeamRepository; +import com.depromeet.fairer.service.fcm.FCMService; import com.depromeet.fairer.service.member.MemberService; import com.depromeet.fairer.vo.team.InviteCodeVo; @@ -21,8 +25,8 @@ import javax.transaction.Transactional; import java.time.LocalDateTime; import java.util.List; +import java.util.Objects; import java.util.Set; -import java.util.stream.Collectors; @Slf4j @Service @@ -35,6 +39,7 @@ public class TeamService { private final MemberRepository memberRepository; private final AssignmentRepository assignmentRepository; private final HouseWorkRepository houseWorkRepository; + private final FCMService fcmService; public Team createTeam(Long memberId, String teamName) { final Member reqMember = memberService.findWithTeam(memberId); @@ -62,9 +67,22 @@ public Team joinTeam(Long memberId, String inviteCode) { validateInviteCode(team, inviteCode); Member member = reqMember.joinTeam(team); + + pushMessageToTeamMember(member, team.getMembers()); + return member.getTeam(); } + private void pushMessageToTeamMember(Member member, Set teamMemberList) { + for(Member teamMember : teamMemberList) { + FCMMessageRequest request = new FCMMessageRequest(); + request.setMemberId(teamMember.getMemberId()); + request.setTitle(String.format(FCMMessageTemplate.JOIN_MEMBER_IN_TEAM.getTitle(), member.getMemberName(), member.getTeam().getTeamName())); + request.setBody(FCMMessageTemplate.JOIN_MEMBER_IN_TEAM.getBody()); + fcmService.sendMessage(request); + } + } + private void validateInviteCode(Team team, String reqInviteCode) { // 초대 코드 및 유효기간 검증 @@ -102,16 +120,6 @@ public Team updateTeam(Long memberId, String teamName) { return reqTeam; } - public Set getTeamMembers(Long memberId) { - Member member = memberService.findWithTeam(memberId); - - if (member.hasTeam()) { - return member.getTeam().getMembers(); - } - - throw new BadRequestException("소속된 팀이 없습니다."); - } - public void leaveTeam(Long memberId) { final Member member = memberService.findWithTeam(memberId); @@ -141,4 +149,13 @@ public Team getTeam(Long memberId) { .getTeam(); } + + public void checkJoinSameTeam(Long teamMemberId, Long memberId) { + Member teamMember = memberService.find(teamMemberId); + Member member = memberService.find(memberId); + + if (!Objects.equals(member.getTeam(), teamMember.getTeam())) { + throw new PermissionDeniedException("해당 멤버의 정보를 가져올 수 없습니다."); + } + } } \ No newline at end of file diff --git a/src/main/java/com/depromeet/fairer/vo/houseWork/HouseWorkUpdateVo.java b/fairer-api/src/main/java/com/depromeet/fairer/vo/houseWork/HouseWorkUpdateVo.java similarity index 51% rename from src/main/java/com/depromeet/fairer/vo/houseWork/HouseWorkUpdateVo.java rename to fairer-api/src/main/java/com/depromeet/fairer/vo/houseWork/HouseWorkUpdateVo.java index 2e4760f2..b1825ea5 100644 --- a/src/main/java/com/depromeet/fairer/vo/houseWork/HouseWorkUpdateVo.java +++ b/fairer-api/src/main/java/com/depromeet/fairer/vo/houseWork/HouseWorkUpdateVo.java @@ -1,15 +1,9 @@ package com.depromeet.fairer.vo.houseWork; -import com.depromeet.fairer.domain.preset.constant.Space; -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; -import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; -import io.swagger.annotations.ApiModelProperty; +import com.depromeet.fairer.domain.preset.Space; import lombok.Getter; import lombok.Setter; -import javax.validation.constraints.NotNull; import java.time.LocalDate; import java.time.LocalTime; import java.util.List; diff --git a/src/main/java/com/depromeet/fairer/vo/team/InviteCodeVo.java b/fairer-api/src/main/java/com/depromeet/fairer/vo/team/InviteCodeVo.java similarity index 100% rename from src/main/java/com/depromeet/fairer/vo/team/InviteCodeVo.java rename to fairer-api/src/main/java/com/depromeet/fairer/vo/team/InviteCodeVo.java diff --git a/src/main/resources/application.yml b/fairer-api/src/main/resources/application.yml similarity index 96% rename from src/main/resources/application.yml rename to fairer-api/src/main/resources/application.yml index 7b870fe8..91a96326 100644 --- a/src/main/resources/application.yml +++ b/fairer-api/src/main/resources/application.yml @@ -2,6 +2,10 @@ spring: profiles: active: "local" +logging: + file: + name: spring-api.log + --- spring: @@ -27,7 +31,7 @@ spring: on-profile: ["dev"] swagger: - url: http://ec2-13-125-232-180.ap-northeast-2.compute.amazonaws.com:8080 + url: http://ec2-3-39-60-64.ap-northeast-2.compute.amazonaws.com:8080 desc: for dev usages oauth2: diff --git a/src/main/resources/db/migration/V1__init.sql b/fairer-api/src/main/resources/db/migration/V1__init.sql similarity index 100% rename from src/main/resources/db/migration/V1__init.sql rename to fairer-api/src/main/resources/db/migration/V1__init.sql diff --git a/fairer-api/src/main/resources/firebase/fairer-def59-firebase-adminsdk-uvxs2-2b35d6203d.json b/fairer-api/src/main/resources/firebase/fairer-def59-firebase-adminsdk-uvxs2-2b35d6203d.json new file mode 100644 index 00000000..7899de08 --- /dev/null +++ b/fairer-api/src/main/resources/firebase/fairer-def59-firebase-adminsdk-uvxs2-2b35d6203d.json @@ -0,0 +1,12 @@ +{ + "type": "service_account", + "project_id": "fairer-def59", + "private_key_id": "2b35d6203d536ecd7f9a3d4515623d3c5ac9e8a5", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDRDOnG9/PEg6Sf\n4EuGNECa47lw22hJTIHhPSUxkliWxIcF+AevacOG2zxidhLXUMiufJIVDlbb+4Jc\n0PNvuZT4ZJhSw5N39otG4nd9AXKOnmcNh2wZZdGW1TCcLpers1Ga3WYRBQ+SqOV+\na0sBzFSdibHezjqXIo5J0ND6fH8Tz7NUYForvQcZHtcDPE5Lb6dDbTgnqfVJ5Xra\no9v45hIv4lq8ZqBn6U9Xb2qbepiPPQik24z6VUOV8IrxVqFOJwstJbaac3Pebd8k\n0ALKPyvbXRIa1DHTh/Rue8i1OfZQBr+iftKL6Z7W/rsNQmL9o2XyLFi5lRWaoG4H\n3PXwk8wvAgMBAAECggEALyHyM2IEG/JyU3mGjaOKTWG6la9iO+R8BAR9NkgAoT1+\nE+JwGSSHaQhU/P4SEWmtVWnQpd6txrtWEQcrW61D4R0NGtvti8aScFDvD8gbw/wC\n0BIQVUmXj6JRa2U13Qh5BamVMZEqia56z53xM16WVU6OQ+XLX/fyjMH/2/nlzNlH\nCuCBYtXqHVg4KsB3WLJoJIFrM6cY2h61NnjJGh2st/lpdSf91D/j2tPG9puzz2ys\nJKV7nyOtHzHxo+E8mK40Sb4NW4KGtUb+Ll1dqU5NgrvjsLBm1TkX4YikEcBhHwFZ\nDPa4dNJrkrO5c2eNXoqCDxITpVkQX24Dok+AypxWQQKBgQDp1JMqc/Q9q7kdYjp/\n7z0EwSTjEtcNUVZ1f9r/IFTa3OOAWaI/AmmqTkxtDCbyZIRonlPwxcIlwfj3XZ2e\nKkOyAGoDtcqTmGul98Nd1aV7mJPcxeSzr+O8+GTlbluuCYIU81oMxL3ILyfreWE+\n2fpkID0x2DUUCMrM9yf1vZa0awKBgQDk3uQe45hUHNQYqMIDJdXBkypCsqcrCKTu\niLJqljKSAupQo5u3z7VIQ1s7eWGbKb4bf4CJafL0wHCzflP2WwDsX0hlhozW/Y8f\ncQrF09JCVKQ6hPW897SfOsIarTgMIeJcio5uz/30OlrT47KOnppxgb/60IW+5JvH\nUGj+FWCYTQKBgQDgb6ExxkpQR1tO0NHFqiOvRJPbQGIZ7lBGR4o0BxxrVkknEOGi\nCPbS+IRyxo87aS+OGyoGmEpZY21MQRbgkUCYwb0AAqWGNW5dxwpGLqK/lxuVdHyn\n29ODtgdiECL/UTECWvG7/7sJQfnXEpI8eYzUPf1+sj+AE1BUm4ZHYMoeMQKBgCRE\nUZ+3bv79JnrV2xCGoU2wVUUGbEj8cK4/yQ3syQysG5c1pcpFxrMxwTY2cMoWnkJb\nPPIJcO9pwzIeNY3XM9lA7AbygETdHx3bWtqoSywpn3CKeyo7kkqdE/8ILdZ2VBlX\n92QF33cg/B2RekzxQwXzioljG555OVonGswQdSMNAoGAO9wGzytPSYgdp6l1GKFp\nGXtOD+XnxDDwiW4FAu/aWqpYr4MmSGQz910HatK6ndS1OHWqkl9OCOQJfPduDFTK\nadUZXQhpveOI+ap7dp+XcmZlWEFXQbXyghhrr7UekBXJp1yFOQnRZWEnoiO0Ho40\nSEofrS1onMwXruF9/2upTM4=\n-----END PRIVATE KEY-----\n", + "client_email": "firebase-adminsdk-uvxs2@fairer-def59.iam.gserviceaccount.com", + "client_id": "109541995676989814778", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-uvxs2%40fairer-def59.iam.gserviceaccount.com" +} diff --git a/src/main/resources/logback-spring.xml b/fairer-api/src/main/resources/logback-spring.xml similarity index 81% rename from src/main/resources/logback-spring.xml rename to fairer-api/src/main/resources/logback-spring.xml index 5f15a0da..3646f5fc 100644 --- a/src/main/resources/logback-spring.xml +++ b/fairer-api/src/main/resources/logback-spring.xml @@ -4,13 +4,13 @@ - %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-10contextName %logger{36} - %msg%n + %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%t] %-10contextName %logger{36} - %msg%n utf8 - logs/spring.log + logs/spring-api.log ${LOG_PATH_NAME}/%d{yyyy-MM-dd}.%i.log @@ -23,7 +23,7 @@ 7 - %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-10contextName %logger{36} - %msg%n + %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%t] %-10contextName %logger{36} - %msg%n @@ -32,7 +32,7 @@ - + diff --git a/src/main/resources/lucy-xss-servlet-filter-rule.xml b/fairer-api/src/main/resources/lucy-xss-servlet-filter-rule.xml similarity index 100% rename from src/main/resources/lucy-xss-servlet-filter-rule.xml rename to fairer-api/src/main/resources/lucy-xss-servlet-filter-rule.xml diff --git a/src/main/resources/lucy-xss-superset-sax.xml b/fairer-api/src/main/resources/lucy-xss-superset-sax.xml similarity index 100% rename from src/main/resources/lucy-xss-superset-sax.xml rename to fairer-api/src/main/resources/lucy-xss-superset-sax.xml diff --git a/src/test/java/com/depromeet/fairer/ApplicationTests.java b/fairer-api/src/test/java/com/depromeet/fairer/ApplicationTests.java similarity index 100% rename from src/test/java/com/depromeet/fairer/ApplicationTests.java rename to fairer-api/src/test/java/com/depromeet/fairer/ApplicationTests.java diff --git a/fairer-batch/build.gradle b/fairer-batch/build.gradle new file mode 100644 index 00000000..9a7c12cf --- /dev/null +++ b/fairer-batch/build.gradle @@ -0,0 +1,38 @@ +import java.text.SimpleDateFormat + +plugins { + // jib + id 'com.google.cloud.tools.jib' version '3.2.1' +} + +jib { + from { + image = "adoptopenjdk/openjdk11:centos-jre" + } + container { + environment = [TZ:"Asia/Seoul"] + } + to { + image = "registry.hub.docker.com/fairerbe/fairer-batch-dev" + tags = ['latest', new SimpleDateFormat('yyyyMMddHHmmss').format(System.currentTimeMillis())] // 2개의 태그에 모두 push + } + container { + creationTime = "USE_CURRENT_TIMESTAMP" + jvmFlags = ['-Dspring.profiles.active=dev', '-XX:+UseContainerSupport', '-Dfile.encoding=UTF-8', '-Duser.timezone="Asia/Seoul"'] + } +} + +group = 'com.depromeet' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '11' + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-batch' + + // https://mvnrepository.com/artifact/de.codecentric/batch-web-spring-boot-starter + implementation 'de.codecentric:batch-web-spring-boot-starter:2.2.0' +} + +jar { + enabled = false +} diff --git a/fairer-batch/src/main/java/com/depromeet/fairer/Application.java b/fairer-batch/src/main/java/com/depromeet/fairer/Application.java new file mode 100644 index 00000000..a16fa55d --- /dev/null +++ b/fairer-batch/src/main/java/com/depromeet/fairer/Application.java @@ -0,0 +1,15 @@ +package com.depromeet.fairer; + +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; + +@SpringBootApplication +@EnableBatchProcessing +@EnableScheduling +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/fairer-batch/src/main/java/com/depromeet/fairer/config/InduceAddHouseworkJobConfig.java b/fairer-batch/src/main/java/com/depromeet/fairer/config/InduceAddHouseworkJobConfig.java new file mode 100644 index 00000000..f2875127 --- /dev/null +++ b/fairer-batch/src/main/java/com/depromeet/fairer/config/InduceAddHouseworkJobConfig.java @@ -0,0 +1,91 @@ +package com.depromeet.fairer.config; + +import com.depromeet.fairer.domain.command.FCMMessageRequest; +import com.depromeet.fairer.domain.command.FCMMessageResponse; +import com.depromeet.fairer.domain.command.FCMMessageTemplate; +import com.depromeet.fairer.domain.command.InduceAddHouseworkCommand; +import com.depromeet.fairer.domain.config.DomainConfigurationProperties; +import com.depromeet.fairer.domain.config.RestTemplateFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.Step; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.JobScope; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepScope; +import org.springframework.batch.item.ItemWriter; +import org.springframework.batch.item.database.JdbcCursorItemReader; +import org.springframework.batch.item.database.builder.JdbcCursorItemReaderBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import javax.sql.DataSource; + +@Slf4j +@Configuration +@RequiredArgsConstructor +public class InduceAddHouseworkJobConfig { + private final JobBuilderFactory jobBuilderFactory; + private final StepBuilderFactory stepBuilderFactory; + private final DataSource dataSource; + private final DomainConfigurationProperties properties; + private static final RestTemplate restTemplate = RestTemplateFactory.getRestTemplate(); + + @Bean + public Job induceAddHouseworkJob() { + return jobBuilderFactory.get("InduceAddHouseworkJob") + .start(induceAddHouseworkStep()) + .preventRestart() + .build(); + } + + @Bean + @JobScope + public Step induceAddHouseworkStep() { + return stepBuilderFactory.get("InduceAddHouseworkStep") + .chunk(1) + .reader(induceAddHouseworkReader()) + .writer(induceAddHouseworkWriter()) + .build(); + } + + @Bean + @StepScope + public JdbcCursorItemReader induceAddHouseworkReader() { + return new JdbcCursorItemReaderBuilder() + .name("InduceAddHouseworkReader") + .fetchSize(1) + .dataSource(dataSource) + .rowMapper(new BeanPropertyRowMapper<>(InduceAddHouseworkCommand.class)) + .sql("SELECT member_id, team_name\n" + + "FROM member INNER JOIN team ON team.team_id=member.team_id\n" + + "WHERE member.fcm_token IS NOT NULL") + .saveState(false) + .build(); + } + + @Bean + @StepScope + public ItemWriter induceAddHouseworkWriter() { + return items -> { + for(InduceAddHouseworkCommand item : items) { + String uri = UriComponentsBuilder.fromHttpUrl(properties.getApiUrl()) + .path("/api/fcm/message") + .encode().build().toString(); + + FCMMessageResponse response = restTemplate.postForObject(uri, getFCMMessageRequest(item), FCMMessageResponse.class); + } + }; + } + + private FCMMessageRequest getFCMMessageRequest(InduceAddHouseworkCommand command) { + Long memberId = command.getMemberId(); + String title = FCMMessageTemplate.INDUCE_ADD_HOUSEWORK.getTitle(); + String body = String.format(FCMMessageTemplate.INDUCE_ADD_HOUSEWORK.getBody(), command.getTeamName()); + return FCMMessageRequest.of(memberId, title, body); + } +} diff --git a/fairer-batch/src/main/java/com/depromeet/fairer/config/NotCompleteHouseworkRemindJobConfig.java b/fairer-batch/src/main/java/com/depromeet/fairer/config/NotCompleteHouseworkRemindJobConfig.java new file mode 100644 index 00000000..d30063f3 --- /dev/null +++ b/fairer-batch/src/main/java/com/depromeet/fairer/config/NotCompleteHouseworkRemindJobConfig.java @@ -0,0 +1,91 @@ +package com.depromeet.fairer.config; + +import com.depromeet.fairer.domain.command.FCMMessageRequest; +import com.depromeet.fairer.domain.command.FCMMessageResponse; +import com.depromeet.fairer.domain.command.FCMMessageTemplate; +import com.depromeet.fairer.domain.command.NotCompleteHouseworkRemindCommand; +import com.depromeet.fairer.domain.config.DomainConfigurationProperties; +import com.depromeet.fairer.domain.config.RestTemplateFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.Step; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.JobScope; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepScope; +import org.springframework.batch.item.ItemWriter; +import org.springframework.batch.item.database.JdbcCursorItemReader; +import org.springframework.batch.item.database.builder.JdbcCursorItemReaderBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import javax.sql.DataSource; + +@Slf4j +@Configuration +@RequiredArgsConstructor +public class NotCompleteHouseworkRemindJobConfig { + private final JobBuilderFactory jobBuilderFactory; + private final StepBuilderFactory stepBuilderFactory; + private final DataSource dataSource; + private final DomainConfigurationProperties properties; + private static final RestTemplate restTemplate = RestTemplateFactory.getRestTemplate(); + + @Bean + public Job notCompleteHouseworkRemindJob() { + return jobBuilderFactory.get("NotCompleteHouseworkRemindJob") + .start(notCompleteHouseworkRemindStep()) + .preventRestart() + .build(); + } + + @Bean + @JobScope + public Step notCompleteHouseworkRemindStep() { + return stepBuilderFactory.get("NotCompleteHouseworkRemindStep") + .chunk(1) + .reader(notCompleteHouseworkRemindReader()) + .writer(notCompleteHouseworkRemindWriter()) + .build(); + } + + @Bean + @StepScope + public JdbcCursorItemReader notCompleteHouseworkRemindReader() { + return new JdbcCursorItemReaderBuilder() + .name("InduceAddHouseworkReader") + .fetchSize(1) + .dataSource(dataSource) + .rowMapper(new BeanPropertyRowMapper<>(NotCompleteHouseworkRemindCommand.class)) + .sql("SELECT member_id as memberId,count(*) as totalCount, housework_name as houseworkName\n" + + "FROM assignment INNER JOIN housework ON assignment.housework_id=housework.housework_id\n" + + "WHERE success=0 and scheduled_date=curdate() GROUP BY member_id") + .saveState(false) + .build(); + } + + @Bean + @StepScope + public ItemWriter notCompleteHouseworkRemindWriter() { + return items -> { + for(NotCompleteHouseworkRemindCommand item : items) { + String uri = UriComponentsBuilder.fromHttpUrl(properties.getApiUrl()) + .path("/api/fcm/message") + .encode().build().toString(); + + FCMMessageResponse response = restTemplate.postForObject(uri, getFCMMessageRequest(item), FCMMessageResponse.class); + } + }; + } + + private FCMMessageRequest getFCMMessageRequest(NotCompleteHouseworkRemindCommand command) { + Long memberId = command.getMemberId(); + String title = String.format(FCMMessageTemplate.NOT_COMPLETE_HOUSEWORK.getTitle(), command.getTotalCount()); + String body = String.format(FCMMessageTemplate.NOT_COMPLETE_HOUSEWORK.getBody(), command.getHouseworkName()); + return FCMMessageRequest.of(memberId, title, body); + } +} diff --git a/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/FCMMessageRequest.java b/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/FCMMessageRequest.java new file mode 100644 index 00000000..0b70f1e7 --- /dev/null +++ b/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/FCMMessageRequest.java @@ -0,0 +1,20 @@ +package com.depromeet.fairer.domain.command; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class FCMMessageRequest { + private Long memberId; + private String title; + private String body; + + public static FCMMessageRequest of(Long memberId, String title, String body) { + return FCMMessageRequest.builder() + .memberId(memberId) + .title(title) + .body(body) + .build(); + } +} diff --git a/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/FCMMessageResponse.java b/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/FCMMessageResponse.java new file mode 100644 index 00000000..ecf33c11 --- /dev/null +++ b/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/FCMMessageResponse.java @@ -0,0 +1,10 @@ +package com.depromeet.fairer.domain.command; + +import lombok.Data; + +@Data +public class FCMMessageResponse { + private String title; + private String body; + private Long memberId; +} diff --git a/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/FCMMessageTemplate.java b/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/FCMMessageTemplate.java new file mode 100644 index 00000000..1bf96e80 --- /dev/null +++ b/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/FCMMessageTemplate.java @@ -0,0 +1,14 @@ +package com.depromeet.fairer.domain.command; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum FCMMessageTemplate { + NOT_COMPLETE_HOUSEWORK("아직 끝내지 못한 집안일 %s개", "'%s'이 남아있어요!\uD83D\uDE22"), + INDUCE_ADD_HOUSEWORK("오늘 할 집안일을 추가해보세요!", "오늘도 평화롭고 깨끗한 %s 만들어봐요!"); + + private final String title; + private final String body; +} diff --git a/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/InduceAddHouseworkCommand.java b/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/InduceAddHouseworkCommand.java new file mode 100644 index 00000000..41c1cf0f --- /dev/null +++ b/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/InduceAddHouseworkCommand.java @@ -0,0 +1,9 @@ +package com.depromeet.fairer.domain.command; + +import lombok.Data; + +@Data +public class InduceAddHouseworkCommand { + private Long memberId; + private String teamName; +} diff --git a/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/NotCompleteHouseworkRemindCommand.java b/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/NotCompleteHouseworkRemindCommand.java new file mode 100644 index 00000000..202a7033 --- /dev/null +++ b/fairer-batch/src/main/java/com/depromeet/fairer/domain/command/NotCompleteHouseworkRemindCommand.java @@ -0,0 +1,10 @@ +package com.depromeet.fairer.domain.command; + +import lombok.Data; + +@Data +public class NotCompleteHouseworkRemindCommand { + private Long memberId; + private Long totalCount; + private String houseworkName; +} diff --git a/fairer-batch/src/main/java/com/depromeet/fairer/domain/config/DomainConfigurationProperties.java b/fairer-batch/src/main/java/com/depromeet/fairer/domain/config/DomainConfigurationProperties.java new file mode 100644 index 00000000..cde8e85a --- /dev/null +++ b/fairer-batch/src/main/java/com/depromeet/fairer/domain/config/DomainConfigurationProperties.java @@ -0,0 +1,14 @@ +package com.depromeet.fairer.domain.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Setter +@Getter +@Component +@ConfigurationProperties(prefix = "domain") +public class DomainConfigurationProperties { + private String apiUrl; +} diff --git a/fairer-batch/src/main/java/com/depromeet/fairer/domain/config/RestTemplateFactory.java b/fairer-batch/src/main/java/com/depromeet/fairer/domain/config/RestTemplateFactory.java new file mode 100644 index 00000000..9e76b773 --- /dev/null +++ b/fairer-batch/src/main/java/com/depromeet/fairer/domain/config/RestTemplateFactory.java @@ -0,0 +1,13 @@ +package com.depromeet.fairer.domain.config; + +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTemplateFactory { + public static RestTemplate getRestTemplate() { + return new RestTemplateBuilder() + .build(); + } +} diff --git a/fairer-batch/src/main/java/com/depromeet/fairer/scheduler/InduceAddHouseworkJobScheduler.java b/fairer-batch/src/main/java/com/depromeet/fairer/scheduler/InduceAddHouseworkJobScheduler.java new file mode 100644 index 00000000..5f3bc0c4 --- /dev/null +++ b/fairer-batch/src/main/java/com/depromeet/fairer/scheduler/InduceAddHouseworkJobScheduler.java @@ -0,0 +1,33 @@ +package com.depromeet.fairer.scheduler; + +import com.depromeet.fairer.config.InduceAddHouseworkJobConfig; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.batch.core.*; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@Configuration +@RequiredArgsConstructor +public class InduceAddHouseworkJobScheduler { + private final JobLauncher jobLauncher; + private final InduceAddHouseworkJobConfig induceAddHouseworkJobConfig; + + @Scheduled(cron = "0 0 9 * * *") + public void induceAddHouseworkJobScheduler() { + Map confMap = new HashMap<>(); + confMap.put("time", new JobParameter(System.currentTimeMillis())); + JobParameters jobParameters = new JobParameters(confMap); + + try { + jobLauncher.run(induceAddHouseworkJobConfig.induceAddHouseworkJob(), jobParameters); + } catch (Exception e) { + log.error("[{}] Error.", induceAddHouseworkJobConfig.induceAddHouseworkJob().getName(), e.getMessage()); + } + } +} diff --git a/fairer-batch/src/main/java/com/depromeet/fairer/scheduler/NotCompleteHouseworkRemindJobScheduler.java b/fairer-batch/src/main/java/com/depromeet/fairer/scheduler/NotCompleteHouseworkRemindJobScheduler.java new file mode 100644 index 00000000..5f397302 --- /dev/null +++ b/fairer-batch/src/main/java/com/depromeet/fairer/scheduler/NotCompleteHouseworkRemindJobScheduler.java @@ -0,0 +1,34 @@ +package com.depromeet.fairer.scheduler; + +import com.depromeet.fairer.config.NotCompleteHouseworkRemindJobConfig; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.batch.core.JobParameter; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@Configuration +@RequiredArgsConstructor +public class NotCompleteHouseworkRemindJobScheduler { + private final JobLauncher jobLauncher; + private final NotCompleteHouseworkRemindJobConfig notCompleteHouseworkRemindJobConfig; + + @Scheduled(cron = "0 0 21 * * *") + public void notCompleteHouseworkRemindJobScheduler() { + Map confMap = new HashMap<>(); + confMap.put("time", new JobParameter(System.currentTimeMillis())); + JobParameters jobParameters = new JobParameters(confMap); + + try { + jobLauncher.run(notCompleteHouseworkRemindJobConfig.notCompleteHouseworkRemindJob(), jobParameters); + } catch (Exception e) { + log.error("[{}] Error.", notCompleteHouseworkRemindJobConfig.notCompleteHouseworkRemindJob().getName(), e.getMessage()); + } + } +} diff --git a/fairer-batch/src/main/resources/application.yml b/fairer-batch/src/main/resources/application.yml new file mode 100644 index 00000000..281f76ea --- /dev/null +++ b/fairer-batch/src/main/resources/application.yml @@ -0,0 +1,72 @@ +server: + port: 8081 + +spring: + profiles: + active: "local" + batch: + job: + enabled: false + jdbc: + initialize-schema: never + main: + allow-bean-definition-overriding: true + +logging: + level: + root: info + file: + name: spring-batch.log + +# spring actuator endpoints 기본으로 disable 적용 +management: + endpoints: + enabled-by-default: false + +--- + +spring: + config: + activate: + on-profile: ["local"] + + datasource: + url: jdbc:mysql://fairer-db.crfymtbz3gz1.ap-northeast-2.rds.amazonaws.com:3306/fairer_dev + driverClassName: com.mysql.cj.jdbc.Driver + username: 'fairer' + password: '>BRLtas~%j2>(\6#eC2M' + +domain: + apiUrl: http://localhost:8080 + +--- + +spring: + config: + activate: + on-profile: ["dev"] + + datasource: + url: jdbc:mysql://fairer-db.crfymtbz3gz1.ap-northeast-2.rds.amazonaws.com:3306/fairer_dev + driverClassName: com.mysql.cj.jdbc.Driver + username: 'fairer' + password: '>BRLtas~%j2>(\6#eC2M' + +domain: + apiUrl: http://ec2-3-39-60-64.ap-northeast-2.compute.amazonaws.com:8080 + +--- + +spring: + config: + activate: + on-profile: "real" + + datasource: + url: jdbc:mysql://fairer-db.crfymtbz3gz1.ap-northeast-2.rds.amazonaws.com:3306/fairer + driverClassName: com.mysql.cj.jdbc.Driver + username: 'fairer' + password: '>BRLtas~%j2>(\6#eC2M' + +domain: + apiUrl: https://fairer-env.eba-synb99hd.ap-northeast-2.elasticbeanstalk.com \ No newline at end of file diff --git a/fairer-batch/src/main/resources/logback-spring.xml b/fairer-batch/src/main/resources/logback-spring.xml new file mode 100644 index 00000000..c3cb3c15 --- /dev/null +++ b/fairer-batch/src/main/resources/logback-spring.xml @@ -0,0 +1,41 @@ + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%t] %-10contextName %logger{36} - %msg%n + utf8 + + + + + logs/spring-batch.log + + + ${LOG_PATH_NAME}/%d{yyyy-MM-dd}.%i.log + + + 50MB + + + 7 + + + %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%t] %-10contextName %logger{36} - %msg%n + + + + + + + + + + + + + + + diff --git a/logs/spring.log b/logs/spring.log deleted file mode 100644 index e69de29b..00000000 diff --git a/settings.gradle b/settings.gradle index 96fb72e0..4b087005 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,3 @@ rootProject.name = 'fairer' +include 'fairer-api' +include 'fairer-batch' diff --git a/src/main/java/com/depromeet/fairer/domain/preset/Preset.java b/src/main/java/com/depromeet/fairer/domain/preset/Preset.java deleted file mode 100644 index 8f79a6b8..00000000 --- a/src/main/java/com/depromeet/fairer/domain/preset/Preset.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.depromeet.fairer.domain.preset; - -import com.depromeet.fairer.domain.base.BaseTimeEntity; -import lombok.*; - -import javax.persistence.*; - - -@Entity -@Table(name = "preset") -@Getter -@Setter -@Builder -@NoArgsConstructor @AllArgsConstructor -public class Preset extends BaseTimeEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "preset_id", columnDefinition = "BIGINT", nullable = false, unique = true) - private Long presetId; - - @Column(name = "space_name", columnDefinition = "VARCHAR(50)", nullable = false) - private String presetSpaceName; - - @Column(name = "housework_name", columnDefinition = "VARCHAR(50)", nullable = false) - private String presetHouseWorkName; -} diff --git a/src/main/java/com/depromeet/fairer/dto/preset/response/HouseWorkPresetListResponseDto.java b/src/main/java/com/depromeet/fairer/dto/preset/response/HouseWorkPresetListResponseDto.java deleted file mode 100644 index f52027a0..00000000 --- a/src/main/java/com/depromeet/fairer/dto/preset/response/HouseWorkPresetListResponseDto.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.depromeet.fairer.dto.preset.response; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.util.List; - -@NoArgsConstructor -@AllArgsConstructor -@Getter -public class HouseWorkPresetListResponseDto { - private List preset; -} diff --git a/src/main/java/com/depromeet/fairer/global/util/DateTimeUtils.java b/src/main/java/com/depromeet/fairer/global/util/DateTimeUtils.java deleted file mode 100644 index c21b9806..00000000 --- a/src/main/java/com/depromeet/fairer/global/util/DateTimeUtils.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.depromeet.fairer.global.util; - -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Date; - -public class DateTimeUtils { - public static LocalDateTime convertToLocalDateTime(Date date) { - return date.toInstant() - .atZone(ZoneId.systemDefault()) - .toLocalDateTime(); - } -} diff --git a/src/main/java/com/depromeet/fairer/repository/preset/PresetRepository.java b/src/main/java/com/depromeet/fairer/repository/preset/PresetRepository.java deleted file mode 100644 index dc3ff5e0..00000000 --- a/src/main/java/com/depromeet/fairer/repository/preset/PresetRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.depromeet.fairer.repository.preset; - -import com.depromeet.fairer.domain.preset.Preset; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public interface PresetRepository extends JpaRepository { - List findByPresetSpaceName(String presetSpaceName); -} diff --git a/src/main/java/com/depromeet/fairer/repository/team/TeamCustomRepository.java b/src/main/java/com/depromeet/fairer/repository/team/TeamCustomRepository.java deleted file mode 100644 index e1c91658..00000000 --- a/src/main/java/com/depromeet/fairer/repository/team/TeamCustomRepository.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.depromeet.fairer.repository.team; - -public interface TeamCustomRepository { -} diff --git a/src/main/java/com/depromeet/fairer/repository/team/TeamCustomRepositoryImpl.java b/src/main/java/com/depromeet/fairer/repository/team/TeamCustomRepositoryImpl.java deleted file mode 100644 index 2d00bab6..00000000 --- a/src/main/java/com/depromeet/fairer/repository/team/TeamCustomRepositoryImpl.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.depromeet.fairer.repository.team; - -public class TeamCustomRepositoryImpl implements TeamCustomRepository { - -} diff --git a/src/main/java/com/depromeet/fairer/service/PresetService.java b/src/main/java/com/depromeet/fairer/service/PresetService.java deleted file mode 100644 index 38888360..00000000 --- a/src/main/java/com/depromeet/fairer/service/PresetService.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.depromeet.fairer.service; - -import com.depromeet.fairer.domain.preset.Preset; -import com.depromeet.fairer.domain.preset.constant.Space; -import com.depromeet.fairer.dto.preset.response.HouseWorkPresetListResponseDto; -import com.depromeet.fairer.dto.preset.response.HouseWorkPresetResponseDto; -import com.depromeet.fairer.repository.preset.PresetRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -@Service -@RequiredArgsConstructor -public class PresetService { - private final PresetRepository presetRepository; - - /** - * 공간 -> 집안일 프리셋 조회 - * @param space 공간 - * @return 집안일 이름 list - */ - @Transactional - public HouseWorkPresetResponseDto getHouseWorkPreset(Space space){ - List houseWorks = presetRepository.findByPresetSpaceName(space.name()) - .stream().map(Preset::getPresetHouseWorkName) - .collect(Collectors.toList()); - return new HouseWorkPresetResponseDto(space.name(), houseWorks); - } - - public HouseWorkPresetListResponseDto getPreset() { - List preset = new ArrayList<>(); - for (Space space : Space.values()) { - if (space.equals(Space.ETC)) { - continue; - } - - List houseWorks = presetRepository.findByPresetSpaceName(space.name()) - .stream().map(Preset::getPresetHouseWorkName) - .collect(Collectors.toList()); - - preset.add(new HouseWorkPresetResponseDto(space.name(), houseWorks)); - } - return new HouseWorkPresetListResponseDto(preset); - } -}