From b91a85fe8498c89104067ef3821a64f0d4036e73 Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Sun, 4 Aug 2024 18:06:58 +0900 Subject: [PATCH 01/39] =?UTF-8?q?infra:=20=EB=B9=8C=EB=93=9C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20yml=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/test_deploy.yml diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml new file mode 100644 index 00000000..711c1574 --- /dev/null +++ b/.github/workflows/test_deploy.yml @@ -0,0 +1,28 @@ +name: CI/CD test + +on: + pull_request: + branches: "feature/33" + +jobs: + build: + environment: aws + runs-on: ubuntu-latest + + permissions: + id-token: write + contents: read + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'oracle' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v3 + + - name: Build with Gradle Wrapper + run: ./gradlew build \ No newline at end of file From 4c6ae6251984a9b63bf1cf45607d537470b19d06 Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Mon, 5 Aug 2024 14:10:00 +0900 Subject: [PATCH 02/39] =?UTF-8?q?infra:=20DB=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml index 711c1574..4347560d 100644 --- a/.github/workflows/test_deploy.yml +++ b/.github/workflows/test_deploy.yml @@ -21,6 +21,19 @@ jobs: java-version: '17' distribution: 'oracle' + - name: Setup SSH + uses: webfactory/ssh-agent@v0.5.3 + with: + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + + - name: Create SSH Tunnel + run: | + ${{ secrets.TUNNEL_SCRIPT }} + + - name: Run Database Tests + run: | + mysql -h 127.0.0.1 -u ${{ secrets.DB_USERNAME }} -p ${{ secrets.DB_PASSWORD }} -e "SHOW DATABASES;" + - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 From ad7d92edbe0d69d45169df35f6170c29e0109306 Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Mon, 5 Aug 2024 18:17:28 +0900 Subject: [PATCH 03/39] =?UTF-8?q?infra:=20ssh-agent=20=EB=B2=84=EC=A0=84?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml index 4347560d..14612e8f 100644 --- a/.github/workflows/test_deploy.yml +++ b/.github/workflows/test_deploy.yml @@ -22,7 +22,7 @@ jobs: distribution: 'oracle' - name: Setup SSH - uses: webfactory/ssh-agent@v0.5.3 + uses: webfactory/ssh-agent@v0.9.0 with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} From 14d18873795c67304cdb81550627c418f9ced8ce Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Mon, 5 Aug 2024 18:37:09 +0900 Subject: [PATCH 04/39] =?UTF-8?q?infra:=20known=5Fhosts=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml index 14612e8f..d07b533e 100644 --- a/.github/workflows/test_deploy.yml +++ b/.github/workflows/test_deploy.yml @@ -26,6 +26,11 @@ jobs: with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + - name: Add SSH Host to known_hosts + run: | + mkdir -p ~/.ssh + ssh-keyscan -H ${{ secrets.EC2_PUBLIC_IP }} >> ~/.ssh/known_hosts + - name: Create SSH Tunnel run: | ${{ secrets.TUNNEL_SCRIPT }} From 31f31a8e4113219fecf2462c3c1b5adc3400e0c2 Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Mon, 5 Aug 2024 18:40:31 +0900 Subject: [PATCH 05/39] =?UTF-8?q?infra:=20db=20port=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml index d07b533e..39b8e71d 100644 --- a/.github/workflows/test_deploy.yml +++ b/.github/workflows/test_deploy.yml @@ -37,7 +37,7 @@ jobs: - name: Run Database Tests run: | - mysql -h 127.0.0.1 -u ${{ secrets.DB_USERNAME }} -p ${{ secrets.DB_PASSWORD }} -e "SHOW DATABASES;" + mysql -h 127.0.0.1:3307 -u ${{ secrets.DB_USERNAME }} -p ${{ secrets.DB_PASSWORD }} -e "SHOW DATABASES;" - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 From da5c7dc0b38a65559d139946bdb5e644eff0baa6 Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Mon, 5 Aug 2024 18:47:26 +0900 Subject: [PATCH 06/39] =?UTF-8?q?infra:=20database=20test=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml index 39b8e71d..b9e0aff6 100644 --- a/.github/workflows/test_deploy.yml +++ b/.github/workflows/test_deploy.yml @@ -36,8 +36,10 @@ jobs: ${{ secrets.TUNNEL_SCRIPT }} - name: Run Database Tests + env: + MYSQL_PWD: ${{ secrets.DB_PASSWORD }} run: | - mysql -h 127.0.0.1:3307 -u ${{ secrets.DB_USERNAME }} -p ${{ secrets.DB_PASSWORD }} -e "SHOW DATABASES;" + mysql -h 127.0.0.1 -P 3307 -u ${{ secrets.DB_USERNAME }} -e "SHOW DATABASES;" - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 From 05054abc783f72696f80ae0fc05f8f6eabcd047d Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Mon, 5 Aug 2024 22:42:27 +0900 Subject: [PATCH 07/39] =?UTF-8?q?infra:=20DB=20=ED=99=98=EA=B2=BD=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EC=84=A4=EC=A0=95=20=EB=B0=8F=20application.yml=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml index b9e0aff6..a3b0b72a 100644 --- a/.github/workflows/test_deploy.yml +++ b/.github/workflows/test_deploy.yml @@ -41,6 +41,17 @@ jobs: run: | mysql -h 127.0.0.1 -P 3307 -u ${{ secrets.DB_USERNAME }} -e "SHOW DATABASES;" + - name: Set environment variables + run: | + echo "DB_URL=${{ secrets.DB_URL }}" >> $GITHUB_ENV + echo "DB_USERNAME=${{ secrets.DB_USERNAME }}" >> $GITHUB_ENV + echo "DB_PASSWORD=${{ secrets.DB_PASSWORD }}" >> $GITHUB_ENV + + - name: Create application.yml + run: | + mkdir -p ${{ secrets.APPLICATION_PATH }} + envsubst < src/main/resources/application-template.yml > ${{ secrets.APPLICATION_PATH }}/application.yml + - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 From 372f84cda2d311678f6d7e31f8b2b727c0439952 Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Mon, 5 Aug 2024 22:53:44 +0900 Subject: [PATCH 08/39] =?UTF-8?q?infra:=20application.yml=20=EB=8F=99?= =?UTF-8?q?=EC=A0=81=20=EC=83=9D=EC=84=B1=20=EC=8A=A4=ED=81=AC=EB=A6=BD?= =?UTF-8?q?=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml index a3b0b72a..f74c2816 100644 --- a/.github/workflows/test_deploy.yml +++ b/.github/workflows/test_deploy.yml @@ -49,8 +49,9 @@ jobs: - name: Create application.yml run: | - mkdir -p ${{ secrets.APPLICATION_PATH }} - envsubst < src/main/resources/application-template.yml > ${{ secrets.APPLICATION_PATH }}/application.yml + echo "${{ secrets.APPLICATION_YML }}" | envsubst > application.yml + env: + APPLICATION_TEMPLATE_YML: ${{ secrets.APPLICATION_YML }} - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 From 57b7bd1e40bcc6d97265d9bef3bb6ef39ce2975f Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Tue, 6 Aug 2024 10:19:44 +0900 Subject: [PATCH 09/39] =?UTF-8?q?infra:=20=EB=A0=88=EB=94=94=EC=8A=A4=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 5 +++++ .../softeer/backend/fo_domain/draw/service/DrawService.java | 2 +- .../backend/global/common/exception/ExceptionAdvice.java | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml index f74c2816..b3f92ab1 100644 --- a/.github/workflows/test_deploy.yml +++ b/.github/workflows/test_deploy.yml @@ -41,6 +41,11 @@ jobs: run: | mysql -h 127.0.0.1 -P 3307 -u ${{ secrets.DB_USERNAME }} -e "SHOW DATABASES;" + - name: Start Redis + uses: supercharge/redis-github-action@1.7.0 + with: + redis-version: 7 + - name: Set environment variables run: | echo "DB_URL=${{ secrets.DB_URL }}" >> $GITHUB_ENV diff --git a/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawService.java b/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawService.java index 9b14b3ab..84ad1a30 100644 --- a/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawService.java +++ b/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawService.java @@ -16,7 +16,7 @@ @Service @RequiredArgsConstructor public class DrawService { - private final DrawRepository drawRepository; + // private final DrawRepository drawRepository; private final DrawParticipationInfoRepository drawParticipationInfoRepository; private final ShareInfoRepository shareInfoRepository; diff --git a/src/main/java/com/softeer/backend/global/common/exception/ExceptionAdvice.java b/src/main/java/com/softeer/backend/global/common/exception/ExceptionAdvice.java index 0ed9f453..58dc47e3 100644 --- a/src/main/java/com/softeer/backend/global/common/exception/ExceptionAdvice.java +++ b/src/main/java/com/softeer/backend/global/common/exception/ExceptionAdvice.java @@ -143,6 +143,9 @@ private ResponseEntity handleEventLockExceptionInternal(EventLockExcepti if(redissonKeyName.contains("FCFS")) body = ResponseDto.onSuccess(SuccessStatus._FCFS_SUCCESS, new FcfsFailResponse()); + else { + body = ResponseDto.onSuccess(SuccessStatus._FCFS_SUCCESS, new FcfsFailResponse()); + } //TODO // DRAW 관련 예외일 경우, body 구성하는 코드 필요 From efb92c9b48139b2c297d9a831da5e7698d5a3f11 Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Tue, 6 Aug 2024 10:43:41 +0900 Subject: [PATCH 10/39] =?UTF-8?q?infra:=20redis=20test=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml index b3f92ab1..af13e1f2 100644 --- a/.github/workflows/test_deploy.yml +++ b/.github/workflows/test_deploy.yml @@ -46,6 +46,10 @@ jobs: with: redis-version: 7 + - name: Check Redis status + run: | + redis-cli -h 127.0.0.1 -p 6379 ping + - name: Set environment variables run: | echo "DB_URL=${{ secrets.DB_URL }}" >> $GITHUB_ENV From babd1a85a30c2b71f4f04a06cb547dfb15229766 Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Tue, 6 Aug 2024 10:49:34 +0900 Subject: [PATCH 11/39] =?UTF-8?q?infra:=20redis=20=EB=B2=84=EC=A0=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml index af13e1f2..db860810 100644 --- a/.github/workflows/test_deploy.yml +++ b/.github/workflows/test_deploy.yml @@ -44,7 +44,7 @@ jobs: - name: Start Redis uses: supercharge/redis-github-action@1.7.0 with: - redis-version: 7 + redis-version: 6 - name: Check Redis status run: | From be93408d593193ae2be13fa7e506f8de3ebc376b Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Tue, 6 Aug 2024 10:54:09 +0900 Subject: [PATCH 12/39] =?UTF-8?q?infra:=20redis=20cli=20=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml index db860810..bb59b18e 100644 --- a/.github/workflows/test_deploy.yml +++ b/.github/workflows/test_deploy.yml @@ -46,6 +46,11 @@ jobs: with: redis-version: 6 + - name: Install Redis CLI + run: | + sudo apt-get update + sudo apt-get install -y redis-tools + - name: Check Redis status run: | redis-cli -h 127.0.0.1 -p 6379 ping From 212a34ceaf39cc6db4699b0543151e4f5a17bd23 Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Tue, 6 Aug 2024 11:02:24 +0900 Subject: [PATCH 13/39] =?UTF-8?q?infra:=20application.yml=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EB=B0=8F=20=EB=82=B4=EC=9A=A9=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml index bb59b18e..739c0570 100644 --- a/.github/workflows/test_deploy.yml +++ b/.github/workflows/test_deploy.yml @@ -67,6 +67,14 @@ jobs: env: APPLICATION_TEMPLATE_YML: ${{ secrets.APPLICATION_YML }} + - name: Display application.yml content + run: | + cat application.yml + + - name: Display application.yml file path + run: | + ls -l application.yml + - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 From db651844a512026d03c383059dab211c553c3a94 Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Tue, 6 Aug 2024 11:07:51 +0900 Subject: [PATCH 14/39] =?UTF-8?q?infra:=20Github=20Actions=20=ED=99=98?= =?UTF-8?q?=EA=B2=BD=EB=B3=80=EC=88=98=EC=97=90=20REDIS=5FHOST,=20REDIS=5F?= =?UTF-8?q?PORT=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml index 739c0570..10567c39 100644 --- a/.github/workflows/test_deploy.yml +++ b/.github/workflows/test_deploy.yml @@ -57,6 +57,8 @@ jobs: - name: Set environment variables run: | + echo "REDIS_HOST=${{ secrets.REDIS_HOST }}" >> $GITHUB_ENV + echo "REDIS_PORT=${{ secrets.REDIS_PORT }}" >> $GITHUB_ENV echo "DB_URL=${{ secrets.DB_URL }}" >> $GITHUB_ENV echo "DB_USERNAME=${{ secrets.DB_USERNAME }}" >> $GITHUB_ENV echo "DB_PASSWORD=${{ secrets.DB_PASSWORD }}" >> $GITHUB_ENV From 4658edd04801264ac561b75a63c91e558d45a765 Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Tue, 6 Aug 2024 11:15:10 +0900 Subject: [PATCH 15/39] =?UTF-8?q?infra:=20=ED=99=98=EA=B2=BD=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=ED=99=95=EC=9D=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test_deploy.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml index 10567c39..e561eaf5 100644 --- a/.github/workflows/test_deploy.yml +++ b/.github/workflows/test_deploy.yml @@ -63,6 +63,14 @@ jobs: echo "DB_USERNAME=${{ secrets.DB_USERNAME }}" >> $GITHUB_ENV echo "DB_PASSWORD=${{ secrets.DB_PASSWORD }}" >> $GITHUB_ENV + - name: Check environment variables + run: | + echo "REDIS_HOST=${REDIS_HOST}" + echo "REDIS_PORT=${REDIS_PORT}" + echo "DB_URL=${DB_URL}" + echo "DB_USERNAME=${DB_USERNAME}" + echo "DB_PASSWORD=${DB_PASSWORD}" + - name: Create application.yml run: | echo "${{ secrets.APPLICATION_YML }}" | envsubst > application.yml From 1706d79e97825af231cdaa0689cd28ed91c39224 Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Tue, 6 Aug 2024 20:50:46 +0900 Subject: [PATCH 16/39] =?UTF-8?q?feat:=20draw=5Frank=20column=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/softeer/backend/fo_domain/draw/domain/Draw.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/softeer/backend/fo_domain/draw/domain/Draw.java b/src/main/java/com/softeer/backend/fo_domain/draw/domain/Draw.java index 7f3e0ae6..86424c34 100644 --- a/src/main/java/com/softeer/backend/fo_domain/draw/domain/Draw.java +++ b/src/main/java/com/softeer/backend/fo_domain/draw/domain/Draw.java @@ -25,7 +25,7 @@ public class Draw { @JoinColumn(name = "user_id") private User user; - @Column(name = "drawRank") + @Column(name = "draw_rank") private Integer drawRank; @Column(name = "winning_date") From 55edd9c2d1c9b35e905303e02525921792e864ca Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Tue, 6 Aug 2024 22:27:10 +0900 Subject: [PATCH 17/39] =?UTF-8?q?infra:=20pull=5Frequest=EC=8B=9C=20Github?= =?UTF-8?q?=20Actions=20=EB=8F=99=EC=9E=91=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 4 +- .github/workflows/test_deploy.yml | 92 ------------------------------- 2 files changed, 2 insertions(+), 94 deletions(-) delete mode 100644 .github/workflows/test_deploy.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5c98bab7..0b78e8f2 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -2,12 +2,12 @@ name: CI/CD test on: pull_request: - types: [closed] + branches: "develop" jobs: build: environment: aws - if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'develop' + # if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'develop' runs-on: ubuntu-latest permissions: diff --git a/.github/workflows/test_deploy.yml b/.github/workflows/test_deploy.yml deleted file mode 100644 index e561eaf5..00000000 --- a/.github/workflows/test_deploy.yml +++ /dev/null @@ -1,92 +0,0 @@ -name: CI/CD test - -on: - pull_request: - branches: "feature/33" - -jobs: - build: - environment: aws - runs-on: ubuntu-latest - - permissions: - id-token: write - contents: read - - steps: - - uses: actions/checkout@v4 - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'oracle' - - - name: Setup SSH - uses: webfactory/ssh-agent@v0.9.0 - with: - ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - - - name: Add SSH Host to known_hosts - run: | - mkdir -p ~/.ssh - ssh-keyscan -H ${{ secrets.EC2_PUBLIC_IP }} >> ~/.ssh/known_hosts - - - name: Create SSH Tunnel - run: | - ${{ secrets.TUNNEL_SCRIPT }} - - - name: Run Database Tests - env: - MYSQL_PWD: ${{ secrets.DB_PASSWORD }} - run: | - mysql -h 127.0.0.1 -P 3307 -u ${{ secrets.DB_USERNAME }} -e "SHOW DATABASES;" - - - name: Start Redis - uses: supercharge/redis-github-action@1.7.0 - with: - redis-version: 6 - - - name: Install Redis CLI - run: | - sudo apt-get update - sudo apt-get install -y redis-tools - - - name: Check Redis status - run: | - redis-cli -h 127.0.0.1 -p 6379 ping - - - name: Set environment variables - run: | - echo "REDIS_HOST=${{ secrets.REDIS_HOST }}" >> $GITHUB_ENV - echo "REDIS_PORT=${{ secrets.REDIS_PORT }}" >> $GITHUB_ENV - echo "DB_URL=${{ secrets.DB_URL }}" >> $GITHUB_ENV - echo "DB_USERNAME=${{ secrets.DB_USERNAME }}" >> $GITHUB_ENV - echo "DB_PASSWORD=${{ secrets.DB_PASSWORD }}" >> $GITHUB_ENV - - - name: Check environment variables - run: | - echo "REDIS_HOST=${REDIS_HOST}" - echo "REDIS_PORT=${REDIS_PORT}" - echo "DB_URL=${DB_URL}" - echo "DB_USERNAME=${DB_USERNAME}" - echo "DB_PASSWORD=${DB_PASSWORD}" - - - name: Create application.yml - run: | - echo "${{ secrets.APPLICATION_YML }}" | envsubst > application.yml - env: - APPLICATION_TEMPLATE_YML: ${{ secrets.APPLICATION_YML }} - - - name: Display application.yml content - run: | - cat application.yml - - - name: Display application.yml file path - run: | - ls -l application.yml - - - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 - - - name: Build with Gradle Wrapper - run: ./gradlew build \ No newline at end of file From 89b5c0f6dac59bb96f4e69fce5d536ddfef68947 Mon Sep 17 00:00:00 2001 From: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Date: Wed, 7 Aug 2024 01:42:16 +0900 Subject: [PATCH 18/39] cicd test (#54) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test --------- Co-authored-by: hyeokson --- .github/workflows/deploy.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index faf09552..46935e39 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,12 +1,13 @@ name: CI/CD test on: - pull_request: - branches: "develop" + pull_request_target: + types: [closed] jobs: build: - if: github.event_name == 'push' + environment: aws + if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'develop' runs-on: ubuntu-latest permissions: @@ -20,12 +21,11 @@ jobs: with: java-version: '17' distribution: 'oracle' - + - name: echo test run: | echo "EC2_PUBLIC_IP: ${{ secrets.EC2_PUBLIC_IP }}" echo "DB_USERNAME: ${{ secrets.DB_USERNAME }}" - - name: Setup SSH uses: webfactory/ssh-agent@v0.9.0 with: From 409fcd17df48f6fec845b976057a0649db86acba Mon Sep 17 00:00:00 2001 From: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Date: Thu, 8 Aug 2024 20:04:49 +0900 Subject: [PATCH 19/39] =?UTF-8?q?[Feat]=20=EA=B8=B0=EB=8C=80=ED=8F=89=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20(#57)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson --- build.gradle | 2 + .../comment/constant/CommentNickname.java | 43 ++++++++++ .../comment/constant/ExpectationComment.java | 40 +++++++++ .../comment/controller/CommentController.java | 41 +++++++++ .../ExpectationCommentConverter.java | 33 +++++++ .../fo_domain/comment/domain/Comment.java | 56 ++++++++++++ .../comment/dto/CommentsResponse.java | 86 +++++++++++++++++++ .../comment/exception/CommentException.java | 11 +++ .../comment/repository/CommentRepository.java | 13 +++ .../comment/service/CommentService.java | 55 ++++++++++++ .../comment/util/ScrollPaginationUtil.java | 43 ++++++++++ .../backend/fo_domain/fcfs/domain/Fcfs.java | 6 +- .../fo_domain/fcfs/service/FcfsService.java | 1 - .../user/controller/LoginController.java | 4 +- .../fo_domain/user/dto/LoginRequest.java | 7 +- .../fo_domain/user/dto/UserTokenResponse.java | 2 +- .../fo_domain/user/service/LoginService.java | 6 +- .../AuthInfoArgumentResolver.java | 3 + .../common/code/status/ErrorStatus.java | 5 +- .../common/code/status/SuccessStatus.java | 7 +- .../common/constant/RedisLockPrefix.java | 2 +- .../global/common/entity/BaseEntity.java | 33 ------- .../filter/JwtAuthenticationFilter.java | 21 ++++- .../softeer/backend/global/util/JwtUtil.java | 2 +- 24 files changed, 473 insertions(+), 49 deletions(-) create mode 100644 src/main/java/com/softeer/backend/fo_domain/comment/constant/CommentNickname.java create mode 100644 src/main/java/com/softeer/backend/fo_domain/comment/constant/ExpectationComment.java create mode 100644 src/main/java/com/softeer/backend/fo_domain/comment/controller/CommentController.java create mode 100644 src/main/java/com/softeer/backend/fo_domain/comment/converter/ExpectationCommentConverter.java create mode 100644 src/main/java/com/softeer/backend/fo_domain/comment/domain/Comment.java create mode 100644 src/main/java/com/softeer/backend/fo_domain/comment/dto/CommentsResponse.java create mode 100644 src/main/java/com/softeer/backend/fo_domain/comment/exception/CommentException.java create mode 100644 src/main/java/com/softeer/backend/fo_domain/comment/repository/CommentRepository.java create mode 100644 src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java create mode 100644 src/main/java/com/softeer/backend/fo_domain/comment/util/ScrollPaginationUtil.java delete mode 100644 src/main/java/com/softeer/backend/global/common/entity/BaseEntity.java diff --git a/build.gradle b/build.gradle index 819c8434..de2269ad 100644 --- a/build.gradle +++ b/build.gradle @@ -36,6 +36,8 @@ dependencies { // JWT 설정 implementation 'io.jsonwebtoken:jjwt:0.9.1' + implementation "com.googlecode.json-simple:json-simple:1.1.1" // Google Simple JSON + implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' //DatatypeConverter // JPA 설정 implementation 'org.springframework.boot:spring-boot-starter-data-jpa' diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/constant/CommentNickname.java b/src/main/java/com/softeer/backend/fo_domain/comment/constant/CommentNickname.java new file mode 100644 index 00000000..ce16de49 --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/comment/constant/CommentNickname.java @@ -0,0 +1,43 @@ +package com.softeer.backend.fo_domain.comment.constant; + +import lombok.Getter; + +/** + * 기대평 닉네임을 관리하는 Enum 클래스 + */ +@Getter +public enum CommentNickname { + NICKNAME_1("곰"), + NICKNAME_2("코끼리"), + NICKNAME_3("토끼"), + NICKNAME_4("기린"), + NICKNAME_5("돌고래"), + NICKNAME_6("개구리"), + NICKNAME_7("고양이"), + NICKNAME_8("악어"), + NICKNAME_9("판다"), + NICKNAME_10("호랑이"); + + public static final String NICKNAME_PREFIX = "익명의 "; + public static final String MY_NICKNAME_SUFFIX = "(나)"; + + private final String nickname; + + CommentNickname(String nickname) { + this.nickname = nickname; + } + + // 인증 하지 않은 유저의 닉네임 생성 메서드 + public static String getRandomNickname() { + CommentNickname[] nicknames = values(); + int index = (int) (Math.random() * nicknames.length); + return NICKNAME_PREFIX + nicknames[index].getNickname(); + } + + // 인증한 유저의 닉네임 생성 메서드 + public static String getMyRandomNickname(int userId) { + CommentNickname[] nicknames = values(); + int index = userId % nicknames.length; + return NICKNAME_PREFIX + nicknames[index].getNickname(); + } +} diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/constant/ExpectationComment.java b/src/main/java/com/softeer/backend/fo_domain/comment/constant/ExpectationComment.java new file mode 100644 index 00000000..4e58d0ef --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/comment/constant/ExpectationComment.java @@ -0,0 +1,40 @@ +package com.softeer.backend.fo_domain.comment.constant; + +import com.softeer.backend.fo_domain.comment.exception.CommentException; +import com.softeer.backend.global.common.code.status.ErrorStatus; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +/** + * 기대평을 관리하는 Enum 클래스 + */ +@Slf4j +@Getter +public enum ExpectationComment { + COMMENT_1("기대돼요!"), + COMMENT_2("경품 당첨되고 싶어요"), + COMMENT_3("재밌을 것 같아요"), + COMMENT_4("The new IONIQ 5 최고"), + COMMENT_5("좋은 이벤트에요"); + + private final String comment; + + ExpectationComment(String comment) { + this.comment = comment; + } + + public int getCommentOrder() { + return this.ordinal() + 1; + } + + public static ExpectationComment of(int commentNum) { + for (ExpectationComment comment : values()) { + if (comment.getCommentOrder() == commentNum) { + return comment; + } + } + + log.error("Invalid comment number: " + commentNum); + throw new CommentException(ErrorStatus._COMMENT_NUM_INVALID); + } +} diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/controller/CommentController.java b/src/main/java/com/softeer/backend/fo_domain/comment/controller/CommentController.java new file mode 100644 index 00000000..a0c0f253 --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/comment/controller/CommentController.java @@ -0,0 +1,41 @@ +package com.softeer.backend.fo_domain.comment.controller; + +import com.softeer.backend.fo_domain.comment.dto.CommentsResponse; +import com.softeer.backend.fo_domain.comment.service.CommentService; +import com.softeer.backend.global.annotation.AuthInfo; +import com.softeer.backend.global.common.code.status.SuccessStatus; +import com.softeer.backend.global.common.response.ResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +@RequiredArgsConstructor +@RestController +public class CommentController { + + private final CommentService commentService; + + @GetMapping("/comment") + ResponseDto getComment(@RequestParam(name = "cursor", required = false) Integer cursor, + @AuthInfo Integer userId){ + if (cursor == null) { + cursor = Integer.MAX_VALUE; + } + + CommentsResponse commentsResponse = commentService.getComments(userId, cursor); + + if(commentsResponse.getNextCursor() != CommentsResponse.LAST_CURSOR) + return ResponseDto.onSuccess(SuccessStatus._COMMENT_GET_SUCCESS, commentsResponse); + + return ResponseDto.onSuccess(SuccessStatus._COMMENT_GET_FINAL_SUCCESS, commentsResponse); + } + + @PostMapping("/comment") + ResponseDto saveComment(@RequestParam(name = "commentNum") int commentNum, + @AuthInfo Integer userId){ + + commentService.saveComment(userId, commentNum); + + return ResponseDto.onSuccess(SuccessStatus._COMMENT_SAVE_SUCCESS); + + } +} diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/converter/ExpectationCommentConverter.java b/src/main/java/com/softeer/backend/fo_domain/comment/converter/ExpectationCommentConverter.java new file mode 100644 index 00000000..d1fc1fc2 --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/comment/converter/ExpectationCommentConverter.java @@ -0,0 +1,33 @@ +package com.softeer.backend.fo_domain.comment.converter; + +import com.softeer.backend.fo_domain.comment.constant.ExpectationComment; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +/** + * 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 클래스 + */ +@Converter(autoApply = true) +public class ExpectationCommentConverter implements AttributeConverter { + + @Override + public String convertToDatabaseColumn(ExpectationComment attribute) { + if (attribute == null) { + return null; + } + return attribute.getComment(); + } + + @Override + public ExpectationComment convertToEntityAttribute(String dbData) { + if (dbData == null || dbData.isEmpty()) { + return null; + } + for (ExpectationComment expectationComment : ExpectationComment.values()) { + if (expectationComment.getComment().equals(dbData)) { + return expectationComment; + } + } + throw new IllegalArgumentException("Unknown database value: " + dbData); + } +} \ No newline at end of file diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/domain/Comment.java b/src/main/java/com/softeer/backend/fo_domain/comment/domain/Comment.java new file mode 100644 index 00000000..96c7f822 --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/comment/domain/Comment.java @@ -0,0 +1,56 @@ +package com.softeer.backend.fo_domain.comment.domain; + + +import com.softeer.backend.fo_domain.comment.constant.CommentNickname; +import com.softeer.backend.fo_domain.comment.constant.ExpectationComment; +import com.softeer.backend.fo_domain.comment.converter.ExpectationCommentConverter; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; + +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Builder +@EntityListeners(AuditingEntityListener.class) +@Table(name = "comment") +public class Comment { + + @Id + @Column(name = "comment_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column(name = "nickname") + private String nickname; + + @Column(name = "comment") + @Convert(converter = ExpectationCommentConverter.class) + private ExpectationComment expectationComment; + + @CreatedDate + @Column(name = "upload_time", updatable = false) + private LocalDateTime uploadTime; + + @Column(name = "user_id", nullable = true) + private Integer userId; + + // + @PrePersist + public void assignRandomNickname() { + if(userId != null) { + this.nickname = CommentNickname.getMyRandomNickname(userId); + } + else{ + this.nickname = CommentNickname.getRandomNickname(); + } + } + +} diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/dto/CommentsResponse.java b/src/main/java/com/softeer/backend/fo_domain/comment/dto/CommentsResponse.java new file mode 100644 index 00000000..d3e49356 --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/comment/dto/CommentsResponse.java @@ -0,0 +1,86 @@ +package com.softeer.backend.fo_domain.comment.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.softeer.backend.fo_domain.comment.constant.CommentNickname; +import com.softeer.backend.fo_domain.comment.constant.ExpectationComment; +import com.softeer.backend.fo_domain.comment.domain.Comment; +import com.softeer.backend.fo_domain.comment.util.ScrollPaginationUtil; +import lombok.*; + +import java.util.List; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PUBLIC) +@Builder +@Getter +public class CommentsResponse { + public static final int LAST_CURSOR = -1; + + private int nextCursor; + + private int totalComments; + + private List comments; + + @Getter + @AllArgsConstructor + @Builder + public static class CommentResponse { + + private Boolean isMine; + + private String nickName; + + private String comment; + } + + public static CommentsResponse of(ScrollPaginationUtil commentsScroll, Integer userId) { + if (commentsScroll.isLastScroll()) { + return CommentsResponse.newLastScroll(commentsScroll.getCurrentScrollItems(), userId); + } + return CommentsResponse.newScrollHasNext(commentsScroll.getCurrentScrollItems(), commentsScroll.getNextCursor().getId(), + userId); + } + + // 마지막 스크롤일 때의 응답값을 구성하는 메서드 + // nextCursor 값을 -1로 설정한다. + private static CommentsResponse newLastScroll(List commentsScroll, Integer userId) { + return newScrollHasNext(commentsScroll, LAST_CURSOR, userId); + } + + // 마지막 스크롤이 아닐 때의 응답값을 구성하는 메서드 + private static CommentsResponse newScrollHasNext(List commentsScroll, int nextCursor, + Integer userId) { + return CommentsResponse.builder() + .nextCursor(nextCursor) + .totalComments(commentsScroll.size()) + .comments(getContents(commentsScroll, userId)) + .build(); + } + + // CommentResponse를 생성하여 반환하는 메서드 + // 유저가 로그인을 한 상태에서 자신의 댓글이 응답에 포함될 경우, + // isMine 변수값을 true로, nickname의 접미사에 '(나)'를 붙여서 응답을 구성한다. + private static List getContents(List commentsScroll, Integer userId) { + return commentsScroll.stream() + .map(_comment -> { + boolean isMine = false; + String nickname = _comment.getNickname(); + String comment = _comment.getExpectationComment().getComment(); + + if(userId != null && _comment.getUserId() != null && + _comment.getUserId().equals(userId)){ + isMine = true; + nickname = nickname + CommentNickname.MY_NICKNAME_SUFFIX; + } + + return CommentResponse.builder() + .isMine(isMine) + .nickName(nickname) + .comment(comment) + .build(); + }) + .toList(); + + } +} diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/exception/CommentException.java b/src/main/java/com/softeer/backend/fo_domain/comment/exception/CommentException.java new file mode 100644 index 00000000..7a80e5de --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/comment/exception/CommentException.java @@ -0,0 +1,11 @@ +package com.softeer.backend.fo_domain.comment.exception; + +import com.softeer.backend.global.common.code.BaseErrorCode; +import com.softeer.backend.global.common.exception.GeneralException; + +public class CommentException extends GeneralException { + + public CommentException(BaseErrorCode code) { + super(code); + } +} diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/repository/CommentRepository.java b/src/main/java/com/softeer/backend/fo_domain/comment/repository/CommentRepository.java new file mode 100644 index 00000000..3e560181 --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/comment/repository/CommentRepository.java @@ -0,0 +1,13 @@ +package com.softeer.backend.fo_domain.comment.repository; + +import com.softeer.backend.fo_domain.comment.domain.Comment; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CommentRepository extends JpaRepository { + + Page findAllByIdLessThanOrderByIdDesc(Integer id, Pageable pageable); +} diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java b/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java new file mode 100644 index 00000000..2b19b8d6 --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java @@ -0,0 +1,55 @@ +package com.softeer.backend.fo_domain.comment.service; + +import com.softeer.backend.fo_domain.comment.constant.CommentNickname; +import com.softeer.backend.fo_domain.comment.constant.ExpectationComment; +import com.softeer.backend.fo_domain.comment.domain.Comment; +import com.softeer.backend.fo_domain.comment.dto.CommentsResponse; +import com.softeer.backend.fo_domain.comment.repository.CommentRepository; +import com.softeer.backend.fo_domain.comment.util.ScrollPaginationUtil; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class CommentService { + private static final int SCROLL_SIZE = 30; + + private final CommentRepository commentRepository; + + /** + * SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 + * + * 커서 기반 무한 스크롤 기능을 사용하여 다음 cursor 값을 받아 해당 값보다 작으면서 정해진 개수 만큼의 기대평을 반환한다. + */ + public CommentsResponse getComments(Integer userId, Integer cursor){ + + PageRequest pageRequest = PageRequest.of(0, SCROLL_SIZE + 1); + Page page = commentRepository.findAllByIdLessThanOrderByIdDesc(cursor, pageRequest); + List comments = page.getContent(); + + ScrollPaginationUtil commentCursor = ScrollPaginationUtil.of(comments, SCROLL_SIZE); + return CommentsResponse.of(commentCursor, userId); + } + + /** + * 기대평을 저장하는 메서드 + */ + public void saveComment(Integer userId, int commentNum){ + + // 로그인 한 유저가 기대평을 등록했다면 User entity의 id값을 기반으로 닉네임을 설정한다. + // 로그인 하지 않았다면, 랜덤으로 닉네임을 설정한다. + String randomNickname = (userId != null ? + CommentNickname.getMyRandomNickname(userId) : CommentNickname.getRandomNickname()); + + commentRepository.save(Comment.builder() + .nickname(randomNickname) + .expectationComment(ExpectationComment.of(commentNum)) + .userId(userId) + .build() + ); + } +} diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/util/ScrollPaginationUtil.java b/src/main/java/com/softeer/backend/fo_domain/comment/util/ScrollPaginationUtil.java new file mode 100644 index 00000000..40546df1 --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/comment/util/ScrollPaginationUtil.java @@ -0,0 +1,43 @@ +package com.softeer.backend.fo_domain.comment.util; + +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +/** + * 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 + */ +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public class ScrollPaginationUtil { + + // 마지막 스크롤인지를 확인하기 위해서 size+1의 개수만큼 item을 저장한다. + private final List itemsWithNextCursor; + + // 한번 스크롤 할 때의 데이터 개수 + private final int countPerScroll; + + public static ScrollPaginationUtil of(List itemsWithNextCursor, int size) { + return new ScrollPaginationUtil<>(itemsWithNextCursor, size); + } + + // 마지막 스크롤인지를 확인하는 메서드 + public boolean isLastScroll() { + return this.itemsWithNextCursor.size() <= countPerScroll; + } + + // 마지막 스크롤일 경우, 그대로 데이터를 반환한다. + // 마지막 스크롤이 아닌 경우, 마지막 데이터를 제외하고 반환한다. + public List getCurrentScrollItems() { + if (isLastScroll()) { + return this.itemsWithNextCursor; + } + return this.itemsWithNextCursor.subList(0, countPerScroll); + } + + // 다음 커서 값을 갖고 있는 데이터를 반환하는 메서드 + public T getNextCursor() { + return itemsWithNextCursor.get(countPerScroll - 1); + } + +} \ No newline at end of file diff --git a/src/main/java/com/softeer/backend/fo_domain/fcfs/domain/Fcfs.java b/src/main/java/com/softeer/backend/fo_domain/fcfs/domain/Fcfs.java index 14cad583..d56a8ecc 100644 --- a/src/main/java/com/softeer/backend/fo_domain/fcfs/domain/Fcfs.java +++ b/src/main/java/com/softeer/backend/fo_domain/fcfs/domain/Fcfs.java @@ -6,6 +6,8 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; import java.time.LocalDateTime; @@ -14,6 +16,7 @@ @AllArgsConstructor @Getter @Builder +@EntityListeners(AuditingEntityListener.class) @Table(name = "fcfs") public class Fcfs { @@ -29,7 +32,8 @@ public class Fcfs { @Column(name = "round") private int round; - @Column(name = "winning_date") + @CreatedDate + @Column(name = "winning_date", nullable = false) private LocalDateTime winningDate; } diff --git a/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsService.java b/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsService.java index e7aaefe7..b4a9d3eb 100644 --- a/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsService.java +++ b/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsService.java @@ -59,7 +59,6 @@ private FcfsResponse saveFcfsWinners(int userId, int round) { Fcfs fcfs = Fcfs.builder() .user(user) .round(round) - .winningDate(LocalDateTime.now()) .build(); fcfsRepository.save(fcfs); diff --git a/src/main/java/com/softeer/backend/fo_domain/user/controller/LoginController.java b/src/main/java/com/softeer/backend/fo_domain/user/controller/LoginController.java index 28a394b6..c31a9f2b 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/controller/LoginController.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/controller/LoginController.java @@ -7,8 +7,8 @@ import com.softeer.backend.global.common.response.ResponseDto; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController @@ -18,7 +18,7 @@ public class LoginController { private final LoginService loginService; @PostMapping("/login") - ResponseDto handleLogin(@Valid @ModelAttribute LoginRequest loginRequest){ + ResponseDto handleLogin(@Valid @RequestBody LoginRequest loginRequest){ UserTokenResponse userTokenResponse = loginService.handleLogin(loginRequest); return ResponseDto.onSuccess(SuccessStatus._LOGIN_SUCCESS, userTokenResponse); diff --git a/src/main/java/com/softeer/backend/fo_domain/user/dto/LoginRequest.java b/src/main/java/com/softeer/backend/fo_domain/user/dto/LoginRequest.java index e6b08071..82c1f093 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/dto/LoginRequest.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/dto/LoginRequest.java @@ -1,5 +1,6 @@ package com.softeer.backend.fo_domain.user.dto; +import com.fasterxml.jackson.annotation.JsonProperty; import com.softeer.backend.global.common.constant.ValidationConstant; import jakarta.validation.constraints.Pattern; import lombok.AllArgsConstructor; @@ -19,9 +20,9 @@ public class LoginRequest { message = ValidationConstant.PHONE_NUMBER_MSG) private String phoneNumber; - private boolean isCodeVerified; + private Boolean hasCodeVerified; - private boolean privacyConsent; + private Boolean privacyConsent; - private boolean marketingConsent; + private Boolean marketingConsent; } diff --git a/src/main/java/com/softeer/backend/fo_domain/user/dto/UserTokenResponse.java b/src/main/java/com/softeer/backend/fo_domain/user/dto/UserTokenResponse.java index fbbdad4f..86a8614b 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/dto/UserTokenResponse.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/dto/UserTokenResponse.java @@ -18,7 +18,7 @@ public class UserTokenResponse { private String refreshToken; - @JsonFormat(pattern = "yyyy-MM-dd'T'hh:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss") private LocalDateTime expiredTime; } diff --git a/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java b/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java index abde08e4..14ff1507 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java @@ -30,7 +30,7 @@ public class LoginService { public UserTokenResponse handleLogin(LoginRequest loginRequest) { // 인증번호가 인증 되지 않은 경우, 예외 발생 - if(!loginRequest.isCodeVerified()) + if(!loginRequest.getHasCodeVerified()) throw new UserException(ErrorStatus._AUTH_CODE_NOT_VERIFIED); int userId; @@ -41,8 +41,8 @@ public UserTokenResponse handleLogin(LoginRequest loginRequest) { User user = User.builder() .name(loginRequest.getName()) .phoneNumber(loginRequest.getPhoneNumber()) - .privacyConsent(loginRequest.isPrivacyConsent()) - .marketingConsent(loginRequest.isMarketingConsent()) + .privacyConsent(loginRequest.getPrivacyConsent()) + .marketingConsent(loginRequest.getMarketingConsent()) .build(); User registeredUser = userRepository.save(user); diff --git a/src/main/java/com/softeer/backend/global/annotation/argumentresolver/AuthInfoArgumentResolver.java b/src/main/java/com/softeer/backend/global/annotation/argumentresolver/AuthInfoArgumentResolver.java index 63bf7a46..ef04e08d 100644 --- a/src/main/java/com/softeer/backend/global/annotation/argumentresolver/AuthInfoArgumentResolver.java +++ b/src/main/java/com/softeer/backend/global/annotation/argumentresolver/AuthInfoArgumentResolver.java @@ -22,6 +22,9 @@ public boolean supportsParameter(MethodParameter parameter) { public Object resolveArgument(@NonNull MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { HttpServletRequest req = (HttpServletRequest) webRequest.getNativeRequest(); JwtClaimsDto jwtClaimsDto = (JwtClaimsDto) req.getAttribute("jwtClaims"); + if(jwtClaimsDto == null){ + return null; + } return jwtClaimsDto.getId(); } } diff --git a/src/main/java/com/softeer/backend/global/common/code/status/ErrorStatus.java b/src/main/java/com/softeer/backend/global/common/code/status/ErrorStatus.java index cfdd84da..b8060112 100644 --- a/src/main/java/com/softeer/backend/global/common/code/status/ErrorStatus.java +++ b/src/main/java/com/softeer/backend/global/common/code/status/ErrorStatus.java @@ -55,7 +55,10 @@ public enum ErrorStatus implements BaseErrorCode { _SHARE_INFO_NOT_FOUND(HttpStatus.NOT_FOUND, "SHARE_INFO_NOT_FOUND", "공유 정보가 없습니다."), // Draw Error - _DRAW_PARTICIPATION_INFO_NOT_FOUND(HttpStatus.NOT_FOUND, "DRAW_PARTICIPATION_INFO_NOT_FOUND", "참여 정보가 없습니다."); + _DRAW_PARTICIPATION_INFO_NOT_FOUND(HttpStatus.NOT_FOUND, "DRAW_PARTICIPATION_INFO_NOT_FOUND", "참여 정보가 없습니다."), + + // Comment Error + _COMMENT_NUM_INVALID(HttpStatus.BAD_REQUEST, "COMMENT_NUM_INVALID", "기대평 순서값이 유효하지 않습니다.(1~5)"); // 예외의 Http 상태값 private final HttpStatus httpStatus; diff --git a/src/main/java/com/softeer/backend/global/common/code/status/SuccessStatus.java b/src/main/java/com/softeer/backend/global/common/code/status/SuccessStatus.java index 81686442..7c8d5e8f 100644 --- a/src/main/java/com/softeer/backend/global/common/code/status/SuccessStatus.java +++ b/src/main/java/com/softeer/backend/global/common/code/status/SuccessStatus.java @@ -24,7 +24,12 @@ public enum SuccessStatus implements BaseCode { _VERIFICATION_CONFIRM(HttpStatus.OK, "VERIFICATION_CONFIRM", "전화번호 인증 코드 검증 성공"), // 로그인 - _LOGIN_SUCCESS(HttpStatus.OK, "LOGIN_SUCCESS", "로그인 성공"); + _LOGIN_SUCCESS(HttpStatus.OK, "LOGIN_SUCCESS", "로그인 성공"), + + // 기대평 + _COMMENT_SAVE_SUCCESS(HttpStatus.OK, "COMMENT_SAVE_SUCCESS", "기대평 등록 성공"), + _COMMENT_GET_SUCCESS(HttpStatus.OK, "COMMENT_GET_SUCCESS", "기대평 조회 성공"), + _COMMENT_GET_FINAL_SUCCESS(HttpStatus.OK, "COMMENT_GET_FINAL_SUCCESS", "마지막 기대평 조회 성공"); // 예외의 Http 상태값 private final HttpStatus httpStatus; diff --git a/src/main/java/com/softeer/backend/global/common/constant/RedisLockPrefix.java b/src/main/java/com/softeer/backend/global/common/constant/RedisLockPrefix.java index 0b3e1767..caef9ac9 100644 --- a/src/main/java/com/softeer/backend/global/common/constant/RedisLockPrefix.java +++ b/src/main/java/com/softeer/backend/global/common/constant/RedisLockPrefix.java @@ -4,7 +4,7 @@ @Getter public enum RedisLockPrefix { - FCFS_LOCK_PREFIX("LOCK:FCFS_WINNER"), + FCFS_LOCK_PREFIX("LOCK:FCFS_WINNER_"), DRAW_LOCK_PREFIX("LOCK:DRAW_WINNER"), FCFS_PARTICIPANT_COUNT_PREFIX("FCFS_PARTICIPANT_COUNT_"); diff --git a/src/main/java/com/softeer/backend/global/common/entity/BaseEntity.java b/src/main/java/com/softeer/backend/global/common/entity/BaseEntity.java deleted file mode 100644 index a7e84847..00000000 --- a/src/main/java/com/softeer/backend/global/common/entity/BaseEntity.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.softeer.backend.global.common.entity; - -import jakarta.persistence.Column; -import jakarta.persistence.EntityListeners; -import jakarta.persistence.MappedSuperclass; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; - -import java.time.LocalDateTime; - - -/** - * Entity의 생성 날짜, 수정 날짜를 명시하는 클래스 - */ -@Getter -@MappedSuperclass -@NoArgsConstructor -@EntityListeners(AuditingEntityListener.class) -public abstract class BaseEntity { - - // 생성 날짜 - @CreatedDate - @Column(name = "created_at", updatable = false) - private LocalDateTime createdAt; - - // 수정 날짜 - @LastModifiedDate - @Column(name = "updated_at") - private LocalDateTime updatedAt; -} diff --git a/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java b/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java index 569ff8b7..11b71c58 100644 --- a/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java +++ b/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java @@ -35,7 +35,13 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { // 인증검사를 하지 않는 url 설정 private final String[] whiteListUrls = { "/swagger-ui/**", "/swagger", "/error/**", - "/verification/send", "/verification/confirm" + "/verification/send", "/verification/confirm", + "/login" + }; + + // Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 + private final String[] optionalAuthUrls = { + "/comment" }; private final JwtUtil jwtUtil; @@ -51,6 +57,14 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse return; } + // optionalAuthUrls에 등록된 url 중, access token이 header에 없으면 인증 x + if(isUriInOptionalAuthList(request.getRequestURI()) && + jwtUtil.extractAccessToken(request).isEmpty()){ + + filterChain.doFilter(request, response); + return; + } + // Case 01) Access Token 재발급인 경우(Authorization Header Access Token 유효성 x) if (request.getRequestURI().contains("/reissue")) { @@ -78,6 +92,10 @@ private boolean isUriInWhiteList(String url) { return PatternMatchUtils.simpleMatch(whiteListUrls, url); } + private boolean isUriInOptionalAuthList(String url) { + return PatternMatchUtils.simpleMatch(optionalAuthUrls, url); + } + private void reissueAccessTokenAndRefreshToken(HttpServletResponse response, String accessToken, String refreshToken) throws IOException { /** @@ -178,4 +196,5 @@ private void checkAccessToken(HttpServletRequest request) { request.setAttribute("jwtClaims", jwtClaimsDto); } + } diff --git a/src/main/java/com/softeer/backend/global/util/JwtUtil.java b/src/main/java/com/softeer/backend/global/util/JwtUtil.java index 463aaf13..a6cc02da 100644 --- a/src/main/java/com/softeer/backend/global/util/JwtUtil.java +++ b/src/main/java/com/softeer/backend/global/util/JwtUtil.java @@ -77,7 +77,7 @@ private JwtClaimsDto getAuthInfoFromToken(String token){ .parseClaimsJws(token) .getBody(); - int id = Integer.parseInt(claims.get("id", String.class)); + int id = claims.get("id", Integer.class); RoleType roleType = RoleType.valueOf(claims.get("roleType", String.class)); return JwtClaimsDto.builder() From d42d60526586f763e9067afa3642de501881ab8b Mon Sep 17 00:00:00 2001 From: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Date: Fri, 9 Aug 2024 10:05:32 +0900 Subject: [PATCH 20/39] cicd test (#58) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * chore: ci/cd를 위한 커밋 --------- Co-authored-by: hyeokson --- .../softeer/backend/fo_domain/draw/exception/DrawException.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/softeer/backend/fo_domain/draw/exception/DrawException.java b/src/main/java/com/softeer/backend/fo_domain/draw/exception/DrawException.java index 8b3245d6..7df828ca 100644 --- a/src/main/java/com/softeer/backend/fo_domain/draw/exception/DrawException.java +++ b/src/main/java/com/softeer/backend/fo_domain/draw/exception/DrawException.java @@ -4,6 +4,7 @@ import com.softeer.backend.global.common.exception.GeneralException; public class DrawException extends GeneralException { + public DrawException(BaseErrorCode code) { super(code); } From 0e2f44d7d0575ea6c143e030d7ae0c70dd5a2236 Mon Sep 17 00:00:00 2001 From: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Date: Sat, 10 Aug 2024 16:35:46 +0900 Subject: [PATCH 21/39] =?UTF-8?q?[Feat]=20=EC=84=B1=EA=B3=B5,=20=EC=8B=A4?= =?UTF-8?q?=ED=8C=A8=20=EC=83=81=ED=83=9C=20=EC=BD=94=EB=93=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=ED=95=98=EA=B8=B0=20(#65)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: cors 도메인 설정 * refactor: 커스텀 코드 형식 수정 및 에러코드 수정 - '(에러를 구분하는 알파벳)3자리 숫자' 형태로 커스텀 에러 코드 관리 - 클라이언트에서 에러 코드에 의해 분기되지 않으면 하나의 에러로 관리하도록 변경 * refactor: 하나의 성공 코드로 관리하도록 변경 * rebase: 원본 develop 브랜치와 rebase * rebase: 원본 develop 브랜치 rebase * feat: cors 설정에 localhost 추가 * refactor: 함수명 변경 * refactor: 예외 코드 변경 --------- Co-authored-by: hyeokson --- .../softeer/backend/BackendApplication.java | 6 +-- .../comment/constant/ExpectationComment.java | 2 +- .../comment/controller/CommentController.java | 19 ++++--- .../fo_domain/comment/domain/Comment.java | 5 +- ...Response.java => CommentsResponseDto.java} | 22 ++++----- .../comment/service/CommentService.java | 10 ++-- .../fo_domain/draw/service/DrawService.java | 6 +-- .../draw/service/DrawSettingManager.java | 2 +- .../fcfs/controller/FcfsController.java | 17 +++---- ...ponse.java => FcfsFailResponseDtoDto.java} | 2 +- ...FcfsResponse.java => FcfsResponseDto.java} | 2 +- ...ponse.java => FcfsSuccessResponseDto.java} | 2 +- .../fo_domain/fcfs/service/FcfsService.java | 40 ++++++++------- .../fcfs/service/FcfsSettingManager.java | 11 ++--- .../user/constatnt/VerificationProperty.java | 2 +- .../user/controller/LoginController.java | 11 ++--- .../controller/VerificationController.java | 21 ++++---- .../backend/fo_domain/user/domain/User.java | 2 +- ...LoginRequest.java => LoginRequestDto.java} | 3 +- ...esponse.java => UserTokenResponseDto.java} | 2 +- ...equest.java => ConfirmCodeRequestDto.java} | 6 +-- ...t.java => VerificationCodeRequestDto.java} | 2 +- ....java => VerificationCodeResponseDto.java} | 2 +- .../fo_domain/user/service/LoginService.java | 26 +++++----- .../user/service/VerificationService.java | 33 ++++++++----- .../global/annotation/aop/EventLockAop.java | 4 +- .../AuthInfoArgumentResolver.java | 6 +-- .../common/code/status/ErrorStatus.java | 49 +++++-------------- .../common/code/status/SuccessStatus.java | 22 ++------- .../global/common/constant/RoleType.java | 2 +- .../common/constant/ValidationConstant.java | 4 +- .../common/exception/ExceptionAdvice.java | 31 ++++++------ .../exception/JwtAuthenticationException.java | 2 +- .../global/common/response/ResponseDto.java | 29 ++++++----- .../global/config/docs/SwaggerConfig.java | 4 +- .../config/properties/JwtProperties.java | 4 +- .../config/properties/RedisProperties.java | 4 +- .../global/config/redis/RedisConfig.java | 2 +- .../global/config/web/WebMvcConfig.java | 2 +- .../filter/ExceptionHandlingFilter.java | 8 +-- .../filter/JwtAuthenticationFilter.java | 48 +++++++++++------- .../global/filter/JwtAuthorizationFilter.java | 9 +++- .../softeer/backend/global/util/JwtUtil.java | 26 +++++----- 43 files changed, 248 insertions(+), 264 deletions(-) rename src/main/java/com/softeer/backend/fo_domain/comment/dto/{CommentsResponse.java => CommentsResponseDto.java} (73%) rename src/main/java/com/softeer/backend/fo_domain/fcfs/dto/{FcfsFailResponse.java => FcfsFailResponseDtoDto.java} (75%) rename src/main/java/com/softeer/backend/fo_domain/fcfs/dto/{FcfsResponse.java => FcfsResponseDto.java} (59%) rename src/main/java/com/softeer/backend/fo_domain/fcfs/dto/{FcfsSuccessResponse.java => FcfsSuccessResponseDto.java} (75%) rename src/main/java/com/softeer/backend/fo_domain/user/dto/{LoginRequest.java => LoginRequestDto.java} (88%) rename src/main/java/com/softeer/backend/fo_domain/user/dto/{UserTokenResponse.java => UserTokenResponseDto.java} (92%) rename src/main/java/com/softeer/backend/fo_domain/user/dto/verification/{ConfirmCodeRequest.java => ConfirmCodeRequestDto.java} (76%) rename src/main/java/com/softeer/backend/fo_domain/user/dto/verification/{VerificationCodeRequest.java => VerificationCodeRequestDto.java} (91%) rename src/main/java/com/softeer/backend/fo_domain/user/dto/verification/{VerificationCodeResponse.java => VerificationCodeResponseDto.java} (83%) diff --git a/src/main/java/com/softeer/backend/BackendApplication.java b/src/main/java/com/softeer/backend/BackendApplication.java index 776ddf83..cd93086e 100644 --- a/src/main/java/com/softeer/backend/BackendApplication.java +++ b/src/main/java/com/softeer/backend/BackendApplication.java @@ -12,8 +12,8 @@ @ConfigurationPropertiesScan public class BackendApplication { - public static void main(String[] args) { - SpringApplication.run(BackendApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(BackendApplication.class, args); + } } diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/constant/ExpectationComment.java b/src/main/java/com/softeer/backend/fo_domain/comment/constant/ExpectationComment.java index 4e58d0ef..d407cfb5 100644 --- a/src/main/java/com/softeer/backend/fo_domain/comment/constant/ExpectationComment.java +++ b/src/main/java/com/softeer/backend/fo_domain/comment/constant/ExpectationComment.java @@ -35,6 +35,6 @@ public static ExpectationComment of(int commentNum) { } log.error("Invalid comment number: " + commentNum); - throw new CommentException(ErrorStatus._COMMENT_NUM_INVALID); + throw new CommentException(ErrorStatus._NOT_FOUND); } } diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/controller/CommentController.java b/src/main/java/com/softeer/backend/fo_domain/comment/controller/CommentController.java index a0c0f253..2f94d3b5 100644 --- a/src/main/java/com/softeer/backend/fo_domain/comment/controller/CommentController.java +++ b/src/main/java/com/softeer/backend/fo_domain/comment/controller/CommentController.java @@ -1,9 +1,8 @@ package com.softeer.backend.fo_domain.comment.controller; -import com.softeer.backend.fo_domain.comment.dto.CommentsResponse; +import com.softeer.backend.fo_domain.comment.dto.CommentsResponseDto; import com.softeer.backend.fo_domain.comment.service.CommentService; import com.softeer.backend.global.annotation.AuthInfo; -import com.softeer.backend.global.common.code.status.SuccessStatus; import com.softeer.backend.global.common.response.ResponseDto; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -15,27 +14,27 @@ public class CommentController { private final CommentService commentService; @GetMapping("/comment") - ResponseDto getComment(@RequestParam(name = "cursor", required = false) Integer cursor, - @AuthInfo Integer userId){ + ResponseDto getComment(@RequestParam(name = "cursor", required = false) Integer cursor, + @AuthInfo Integer userId) { if (cursor == null) { cursor = Integer.MAX_VALUE; } - CommentsResponse commentsResponse = commentService.getComments(userId, cursor); + CommentsResponseDto commentsResponseDto = commentService.getComments(userId, cursor); - if(commentsResponse.getNextCursor() != CommentsResponse.LAST_CURSOR) - return ResponseDto.onSuccess(SuccessStatus._COMMENT_GET_SUCCESS, commentsResponse); + if (commentsResponseDto.getNextCursor() != CommentsResponseDto.LAST_CURSOR) + return ResponseDto.onSuccess(commentsResponseDto); - return ResponseDto.onSuccess(SuccessStatus._COMMENT_GET_FINAL_SUCCESS, commentsResponse); + return ResponseDto.onSuccess(commentsResponseDto); } @PostMapping("/comment") ResponseDto saveComment(@RequestParam(name = "commentNum") int commentNum, - @AuthInfo Integer userId){ + @AuthInfo Integer userId) { commentService.saveComment(userId, commentNum); - return ResponseDto.onSuccess(SuccessStatus._COMMENT_SAVE_SUCCESS); + return ResponseDto.onSuccess(); } } diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/domain/Comment.java b/src/main/java/com/softeer/backend/fo_domain/comment/domain/Comment.java index 96c7f822..fab8e285 100644 --- a/src/main/java/com/softeer/backend/fo_domain/comment/domain/Comment.java +++ b/src/main/java/com/softeer/backend/fo_domain/comment/domain/Comment.java @@ -45,10 +45,9 @@ public class Comment { // @PrePersist public void assignRandomNickname() { - if(userId != null) { + if (userId != null) { this.nickname = CommentNickname.getMyRandomNickname(userId); - } - else{ + } else { this.nickname = CommentNickname.getRandomNickname(); } } diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/dto/CommentsResponse.java b/src/main/java/com/softeer/backend/fo_domain/comment/dto/CommentsResponseDto.java similarity index 73% rename from src/main/java/com/softeer/backend/fo_domain/comment/dto/CommentsResponse.java rename to src/main/java/com/softeer/backend/fo_domain/comment/dto/CommentsResponseDto.java index d3e49356..ec7fb46c 100644 --- a/src/main/java/com/softeer/backend/fo_domain/comment/dto/CommentsResponse.java +++ b/src/main/java/com/softeer/backend/fo_domain/comment/dto/CommentsResponseDto.java @@ -1,8 +1,6 @@ package com.softeer.backend.fo_domain.comment.dto; -import com.fasterxml.jackson.annotation.JsonProperty; import com.softeer.backend.fo_domain.comment.constant.CommentNickname; -import com.softeer.backend.fo_domain.comment.constant.ExpectationComment; import com.softeer.backend.fo_domain.comment.domain.Comment; import com.softeer.backend.fo_domain.comment.util.ScrollPaginationUtil; import lombok.*; @@ -13,7 +11,7 @@ @AllArgsConstructor(access = AccessLevel.PUBLIC) @Builder @Getter -public class CommentsResponse { +public class CommentsResponseDto { public static final int LAST_CURSOR = -1; private int nextCursor; @@ -34,24 +32,24 @@ public static class CommentResponse { private String comment; } - public static CommentsResponse of(ScrollPaginationUtil commentsScroll, Integer userId) { + public static CommentsResponseDto of(ScrollPaginationUtil commentsScroll, Integer userId) { if (commentsScroll.isLastScroll()) { - return CommentsResponse.newLastScroll(commentsScroll.getCurrentScrollItems(), userId); + return CommentsResponseDto.newLastScroll(commentsScroll.getCurrentScrollItems(), userId); } - return CommentsResponse.newScrollHasNext(commentsScroll.getCurrentScrollItems(), commentsScroll.getNextCursor().getId(), + return CommentsResponseDto.newScrollHasNext(commentsScroll.getCurrentScrollItems(), commentsScroll.getNextCursor().getId(), userId); } // 마지막 스크롤일 때의 응답값을 구성하는 메서드 // nextCursor 값을 -1로 설정한다. - private static CommentsResponse newLastScroll(List commentsScroll, Integer userId) { + private static CommentsResponseDto newLastScroll(List commentsScroll, Integer userId) { return newScrollHasNext(commentsScroll, LAST_CURSOR, userId); } // 마지막 스크롤이 아닐 때의 응답값을 구성하는 메서드 - private static CommentsResponse newScrollHasNext(List commentsScroll, int nextCursor, - Integer userId) { - return CommentsResponse.builder() + private static CommentsResponseDto newScrollHasNext(List commentsScroll, int nextCursor, + Integer userId) { + return CommentsResponseDto.builder() .nextCursor(nextCursor) .totalComments(commentsScroll.size()) .comments(getContents(commentsScroll, userId)) @@ -68,8 +66,8 @@ private static List getContents(List commentsScroll, I String nickname = _comment.getNickname(); String comment = _comment.getExpectationComment().getComment(); - if(userId != null && _comment.getUserId() != null && - _comment.getUserId().equals(userId)){ + if (userId != null && _comment.getUserId() != null && + _comment.getUserId().equals(userId)) { isMine = true; nickname = nickname + CommentNickname.MY_NICKNAME_SUFFIX; } diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java b/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java index 2b19b8d6..f4333322 100644 --- a/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java +++ b/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java @@ -3,7 +3,7 @@ import com.softeer.backend.fo_domain.comment.constant.CommentNickname; import com.softeer.backend.fo_domain.comment.constant.ExpectationComment; import com.softeer.backend.fo_domain.comment.domain.Comment; -import com.softeer.backend.fo_domain.comment.dto.CommentsResponse; +import com.softeer.backend.fo_domain.comment.dto.CommentsResponseDto; import com.softeer.backend.fo_domain.comment.repository.CommentRepository; import com.softeer.backend.fo_domain.comment.util.ScrollPaginationUtil; import lombok.RequiredArgsConstructor; @@ -22,23 +22,23 @@ public class CommentService { /** * SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 - * + *

* 커서 기반 무한 스크롤 기능을 사용하여 다음 cursor 값을 받아 해당 값보다 작으면서 정해진 개수 만큼의 기대평을 반환한다. */ - public CommentsResponse getComments(Integer userId, Integer cursor){ + public CommentsResponseDto getComments(Integer userId, Integer cursor) { PageRequest pageRequest = PageRequest.of(0, SCROLL_SIZE + 1); Page page = commentRepository.findAllByIdLessThanOrderByIdDesc(cursor, pageRequest); List comments = page.getContent(); ScrollPaginationUtil commentCursor = ScrollPaginationUtil.of(comments, SCROLL_SIZE); - return CommentsResponse.of(commentCursor, userId); + return CommentsResponseDto.of(commentCursor, userId); } /** * 기대평을 저장하는 메서드 */ - public void saveComment(Integer userId, int commentNum){ + public void saveComment(Integer userId, int commentNum) { // 로그인 한 유저가 기대평을 등록했다면 User entity의 id값을 기반으로 닉네임을 설정한다. // 로그인 하지 않았다면, 랜덤으로 닉네임을 설정한다. diff --git a/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawService.java b/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawService.java index f702fcb5..abb35f2b 100644 --- a/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawService.java +++ b/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawService.java @@ -44,11 +44,11 @@ public class DrawService { public ResponseDto getDrawMainPageInfo(Integer userId) { // 참여 정보 (연속참여일수) 조회 DrawParticipationInfo drawParticipationInfo = drawParticipationInfoRepository.findDrawParticipationInfoByUserId(userId) - .orElseThrow(() -> new DrawException(ErrorStatus._DRAW_PARTICIPATION_INFO_NOT_FOUND)); + .orElseThrow(() -> new DrawException(ErrorStatus._NOT_FOUND)); // 초대한 친구 수, 복권 기회 조회 ShareInfo shareInfo = shareInfoRepository.findShareInfoByUserId(userId) - .orElseThrow(() -> new ShareInfoException(ErrorStatus._SHARE_INFO_NOT_FOUND)); + .orElseThrow(() -> new ShareInfoException(ErrorStatus._NOT_FOUND)); int drawParticipationCount = drawParticipationInfo.getDrawParticipationCount(); int invitedNum = shareInfo.getInvitedNum(); @@ -96,7 +96,7 @@ public ResponseDto getDrawMainPageInfo(Integer userId) { .build()); } else { // 낙첨자일 경우 String shareUrl = shareUrlInfoRepository.findShareUrlByUserId(userId) - .orElseThrow(() -> new ShareUrlInfoException(ErrorStatus._SHARE_URL_NOT_FOUND)); + .orElseThrow(() -> new ShareUrlInfoException(ErrorStatus._NOT_FOUND)); return ResponseDto.onSuccess(DrawLoseResponseDto.builder() .invitedNum(invitedNum) diff --git a/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawSettingManager.java b/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawSettingManager.java index 58b6bbc7..0077e1ca 100644 --- a/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawSettingManager.java +++ b/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawSettingManager.java @@ -35,7 +35,7 @@ public class DrawSettingManager { @PostConstruct public void initializeDrawSettingManager() { DrawSetting drawSetting = drawSettingRepository.findById(1) - .orElseThrow(() -> new DrawException(ErrorStatus._DRAW_PARTICIPATION_INFO_NOT_FOUND)); + .orElseThrow(() -> new DrawException(ErrorStatus._NOT_FOUND)); startTime = drawSetting.getStartTime(); endTime = drawSetting.getEndTime(); diff --git a/src/main/java/com/softeer/backend/fo_domain/fcfs/controller/FcfsController.java b/src/main/java/com/softeer/backend/fo_domain/fcfs/controller/FcfsController.java index cf4744aa..0cdf6489 100644 --- a/src/main/java/com/softeer/backend/fo_domain/fcfs/controller/FcfsController.java +++ b/src/main/java/com/softeer/backend/fo_domain/fcfs/controller/FcfsController.java @@ -1,12 +1,9 @@ package com.softeer.backend.fo_domain.fcfs.controller; -import com.softeer.backend.fo_domain.fcfs.domain.Fcfs; -import com.softeer.backend.fo_domain.fcfs.dto.FcfsFailResponse; -import com.softeer.backend.fo_domain.fcfs.dto.FcfsResponse; -import com.softeer.backend.fo_domain.fcfs.dto.FcfsSuccessResponse; +import com.softeer.backend.fo_domain.fcfs.dto.FcfsResponseDto; +import com.softeer.backend.fo_domain.fcfs.dto.FcfsSuccessResponseDto; import com.softeer.backend.fo_domain.fcfs.service.FcfsService; import com.softeer.backend.global.annotation.AuthInfo; -import com.softeer.backend.global.common.code.status.SuccessStatus; import com.softeer.backend.global.common.response.ResponseDto; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -21,13 +18,13 @@ public class FcfsController { private final FcfsService fcfsService; @PostMapping("/fcfs") - public ResponseDto handleFCFS(@Parameter(hidden = true) @AuthInfo Integer userId) { - FcfsResponse fcfsResponse = fcfsService.handleFcfsEvent(userId); + public ResponseDto handleFCFS(@Parameter(hidden = true) @AuthInfo Integer userId) { + FcfsResponseDto fcfsResponse = fcfsService.handleFcfsEvent(userId); - if(fcfsResponse instanceof FcfsSuccessResponse) - return ResponseDto.onSuccess(SuccessStatus._FCFS_SUCCESS, fcfsResponse); + if (fcfsResponse instanceof FcfsSuccessResponseDto) + return ResponseDto.onSuccess(fcfsResponse); - return ResponseDto.onSuccess(SuccessStatus._FCFS_FAIL, fcfsResponse); + return ResponseDto.onSuccess(fcfsResponse); } } diff --git a/src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsFailResponse.java b/src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsFailResponseDtoDto.java similarity index 75% rename from src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsFailResponse.java rename to src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsFailResponseDtoDto.java index 5bc73a0d..9e7cc2e6 100644 --- a/src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsFailResponse.java +++ b/src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsFailResponseDtoDto.java @@ -6,6 +6,6 @@ @AllArgsConstructor(access = AccessLevel.PUBLIC) @Builder @Getter -public class FcfsFailResponse implements FcfsResponse{ +public class FcfsFailResponseDtoDto implements FcfsResponseDto { private int a; } diff --git a/src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsResponse.java b/src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsResponseDto.java similarity index 59% rename from src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsResponse.java rename to src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsResponseDto.java index 9ef87505..7d9b2c09 100644 --- a/src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsResponse.java +++ b/src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsResponseDto.java @@ -1,4 +1,4 @@ package com.softeer.backend.fo_domain.fcfs.dto; -public interface FcfsResponse { +public interface FcfsResponseDto { } diff --git a/src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsSuccessResponse.java b/src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsSuccessResponseDto.java similarity index 75% rename from src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsSuccessResponse.java rename to src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsSuccessResponseDto.java index 975aa8c7..39e379b3 100644 --- a/src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsSuccessResponse.java +++ b/src/main/java/com/softeer/backend/fo_domain/fcfs/dto/FcfsSuccessResponseDto.java @@ -6,6 +6,6 @@ @AllArgsConstructor(access = AccessLevel.PUBLIC) @Builder @Getter -public class FcfsSuccessResponse implements FcfsResponse{ +public class FcfsSuccessResponseDto implements FcfsResponseDto { private int a; } diff --git a/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsService.java b/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsService.java index d7d205d6..b0dddc46 100644 --- a/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsService.java +++ b/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsService.java @@ -1,9 +1,9 @@ package com.softeer.backend.fo_domain.fcfs.service; import com.softeer.backend.fo_domain.fcfs.domain.Fcfs; -import com.softeer.backend.fo_domain.fcfs.dto.FcfsFailResponse; -import com.softeer.backend.fo_domain.fcfs.dto.FcfsResponse; -import com.softeer.backend.fo_domain.fcfs.dto.FcfsSuccessResponse; +import com.softeer.backend.fo_domain.fcfs.dto.FcfsFailResponseDtoDto; +import com.softeer.backend.fo_domain.fcfs.dto.FcfsResponseDto; +import com.softeer.backend.fo_domain.fcfs.dto.FcfsSuccessResponseDto; import com.softeer.backend.fo_domain.fcfs.repository.FcfsRepository; import com.softeer.backend.fo_domain.user.domain.User; import com.softeer.backend.fo_domain.user.exception.UserException; @@ -13,14 +13,15 @@ import com.softeer.backend.global.common.constant.RedisLockPrefix; import com.softeer.backend.global.util.EventLockRedisUtil; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.time.LocalDateTime; import java.util.Set; /** * 선착순 관련 이벤트를 처리하는 클래스 */ +@Slf4j @Service @RequiredArgsConstructor public class FcfsService { @@ -34,8 +35,8 @@ public class FcfsService { * 1. 선착순 당첨자가 아직 다 결정되지 않았으면, 선착순 당첨 응답 생성 및 반환 * 2. 선착순 당첨자가 다 결정됐다면, Redisson lock을 사용하지 않고 Redis에 저장된 선착순 이벤트 참여자 수를 1명씩 더한다. */ - public FcfsResponse handleFcfsEvent(int userId){ - if(fcfsSettingManager.isFcfsClosed()) + public FcfsResponseDto handleFcfsEvent(int userId) { + if (fcfsSettingManager.isFcfsClosed()) return countFcfsParticipant(fcfsSettingManager.getRound()); return saveFcfsWinners(userId, fcfsSettingManager.getRound()); @@ -43,18 +44,21 @@ public FcfsResponse handleFcfsEvent(int userId){ /** * 1. Redisson lock을 걸고 선착순 이벤트 참여자 수가 지정된 수보다 적다면, 선착순 당첨 정보를 DB에 저장하고 - * Redis에 저장된 선착순 이벤트 참여자 수를 1만큼 증가시키도 선착순 당첨 응답을 생성하여 반환한다. - * 만약, 참여자 수가 총 당첨자 수와 같아졌으면, fcfsSettingManager의 setFcfsClosed를 true로 변환한다. + * Redis에 저장된 선착순 이벤트 참여자 수를 1만큼 증가시키도 선착순 당첨 응답을 생성하여 반환한다. + * 만약, 참여자 수가 총 당첨자 수와 같아졌으면, fcfsSettingManager의 setFcfsClosed를 true로 변환한다. * 2. setFcfsClosed가 true로 바뀌게 전에 요청이 들어왔다면, 선착순 실패 응답을 생성하여 반환한다. */ @EventLock(key = "FCFS_WINNER_#{#round}") - private FcfsResponse saveFcfsWinners(int userId, int round) { - Set participantIds= eventLockRedisUtil.getAllDataAsSet(RedisLockPrefix.FCFS_LOCK_PREFIX.getPrefix() + round); + private FcfsResponseDto saveFcfsWinners(int userId, int round) { + Set participantIds = eventLockRedisUtil.getAllDataAsSet(RedisLockPrefix.FCFS_LOCK_PREFIX.getPrefix() + round); - if(participantIds.size() < fcfsSettingManager.getWinnerNum() && - !eventLockRedisUtil.isParticipantExists(RedisLockPrefix.FCFS_LOCK_PREFIX.getPrefix() + round, userId)){ + if (participantIds.size() < fcfsSettingManager.getWinnerNum() && + !eventLockRedisUtil.isParticipantExists(RedisLockPrefix.FCFS_LOCK_PREFIX.getPrefix() + round, userId)) { User user = userRepository.findById(userId) - .orElseThrow(() -> new UserException(ErrorStatus._USER_NOT_FOUND)); + .orElseThrow(() -> { + log.error("user not found in saveFcfsWinners method."); + return new UserException(ErrorStatus._NOT_FOUND); + }); Fcfs fcfs = Fcfs.builder() .user(user) @@ -63,20 +67,20 @@ private FcfsResponse saveFcfsWinners(int userId, int round) { fcfsRepository.save(fcfs); eventLockRedisUtil.incrementParticipantCount(RedisLockPrefix.FCFS_PARTICIPANT_COUNT_PREFIX.getPrefix() + round); - if(participantIds.size() + 1 == fcfsSettingManager.getWinnerNum()){ + if (participantIds.size() + 1 == fcfsSettingManager.getWinnerNum()) { fcfsSettingManager.setFcfsClosed(true); } - return new FcfsSuccessResponse(1); + return new FcfsSuccessResponseDto(1); } - return new FcfsFailResponse(1); + return new FcfsFailResponseDtoDto(1); } - private FcfsFailResponse countFcfsParticipant(int round){ + private FcfsFailResponseDtoDto countFcfsParticipant(int round) { eventLockRedisUtil.incrementParticipantCount(RedisLockPrefix.FCFS_PARTICIPANT_COUNT_PREFIX.getPrefix() + round); - return new FcfsFailResponse(1); + return new FcfsFailResponseDtoDto(1); } } diff --git a/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsSettingManager.java b/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsSettingManager.java index 04dd27cb..4e58eb6b 100644 --- a/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsSettingManager.java +++ b/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsSettingManager.java @@ -47,7 +47,7 @@ public class FcfsSettingManager { private ScheduledFuture scheduledFuture; @PostConstruct - public void init(){ + public void init() { loadInitialData(); scheduleTask(); } @@ -56,7 +56,7 @@ public void init(){ * round 1에 해당하는 선착순 이벤트 속성으로 초기화 */ public void loadInitialData() { - try{ + try { FcfsSetting fcfsSetting = fcfsSettingRepository.findByRound(1) .orElseThrow(IllegalStateException::new); @@ -66,8 +66,7 @@ public void loadInitialData() { this.winnerNum = fcfsSetting.getWinnerNum(); this.isFcfsClosed = false; - } - catch(Exception e){ + } catch (Exception e) { log.error("FcfsSetting not found by round {}", round); } } @@ -102,7 +101,7 @@ protected void updateFcfsSetting() { eventParticipation.addFcfsParticipantCount(participantCount); eventLockRedisUtil.deleteParticipantCount(RedisLockPrefix.FCFS_PARTICIPANT_COUNT_PREFIX.getPrefix() + round); - eventLockRedisUtil.deleteParticipantIds(RedisLockPrefix.FCFS_LOCK_PREFIX.getPrefix() + (round-1)); + eventLockRedisUtil.deleteParticipantIds(RedisLockPrefix.FCFS_LOCK_PREFIX.getPrefix() + (round - 1)); } catch (Exception e) { log.info("Updating FcfsSetting is final"); @@ -124,7 +123,7 @@ public void stopScheduler() { * Admin 기능으로 현재 round의 선착순 이벤트 정보를 변경했을 때, 변경 사항을 적용하기 위해 사용하는 메서드 */ public void setFcfsSetting(FcfsSetting fcfsSetting) { - if(fcfsSetting.getRound() == this.round){ + if (fcfsSetting.getRound() == this.round) { this.startTime = fcfsSetting.getStartTime(); this.endTime = fcfsSetting.getEndTime(); this.winnerNum = fcfsSetting.getWinnerNum(); diff --git a/src/main/java/com/softeer/backend/fo_domain/user/constatnt/VerificationProperty.java b/src/main/java/com/softeer/backend/fo_domain/user/constatnt/VerificationProperty.java index 8bc43492..e58b79b5 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/constatnt/VerificationProperty.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/constatnt/VerificationProperty.java @@ -13,7 +13,7 @@ public enum VerificationProperty { private final int value; - VerificationProperty(int value){ + VerificationProperty(int value) { this.value = value; } diff --git a/src/main/java/com/softeer/backend/fo_domain/user/controller/LoginController.java b/src/main/java/com/softeer/backend/fo_domain/user/controller/LoginController.java index c31a9f2b..14922d5f 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/controller/LoginController.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/controller/LoginController.java @@ -1,9 +1,8 @@ package com.softeer.backend.fo_domain.user.controller; -import com.softeer.backend.fo_domain.user.dto.LoginRequest; -import com.softeer.backend.fo_domain.user.dto.UserTokenResponse; +import com.softeer.backend.fo_domain.user.dto.LoginRequestDto; +import com.softeer.backend.fo_domain.user.dto.UserTokenResponseDto; import com.softeer.backend.fo_domain.user.service.LoginService; -import com.softeer.backend.global.common.code.status.SuccessStatus; import com.softeer.backend.global.common.response.ResponseDto; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -18,10 +17,10 @@ public class LoginController { private final LoginService loginService; @PostMapping("/login") - ResponseDto handleLogin(@Valid @RequestBody LoginRequest loginRequest){ - UserTokenResponse userTokenResponse = loginService.handleLogin(loginRequest); + ResponseDto handleLogin(@Valid @RequestBody LoginRequestDto loginRequestDto) { + UserTokenResponseDto userTokenResponseDto = loginService.handleLogin(loginRequestDto); - return ResponseDto.onSuccess(SuccessStatus._LOGIN_SUCCESS, userTokenResponse); + return ResponseDto.onSuccess(userTokenResponseDto); } } diff --git a/src/main/java/com/softeer/backend/fo_domain/user/controller/VerificationController.java b/src/main/java/com/softeer/backend/fo_domain/user/controller/VerificationController.java index aa575cea..8edc8c30 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/controller/VerificationController.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/controller/VerificationController.java @@ -1,15 +1,12 @@ package com.softeer.backend.fo_domain.user.controller; -import com.softeer.backend.fo_domain.user.dto.verification.ConfirmCodeRequest; -import com.softeer.backend.fo_domain.user.dto.verification.VerificationCodeRequest; -import com.softeer.backend.fo_domain.user.dto.verification.VerificationCodeResponse; +import com.softeer.backend.fo_domain.user.dto.verification.ConfirmCodeRequestDto; +import com.softeer.backend.fo_domain.user.dto.verification.VerificationCodeRequestDto; +import com.softeer.backend.fo_domain.user.dto.verification.VerificationCodeResponseDto; import com.softeer.backend.fo_domain.user.service.VerificationService; -import com.softeer.backend.global.common.code.status.SuccessStatus; import com.softeer.backend.global.common.response.ResponseDto; -import com.sun.net.httpserver.Authenticator; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -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; @@ -22,19 +19,19 @@ public class VerificationController { private final VerificationService verificationService; @PostMapping("/send") - public ResponseDto sendVerificationCode(@Valid @RequestBody VerificationCodeRequest verificationCodeRequest){ + public ResponseDto sendVerificationCode(@Valid @RequestBody VerificationCodeRequestDto verificationCodeRequestDto) { - VerificationCodeResponse response = verificationService.sendVerificationCode(verificationCodeRequest.getPhoneNumber()); + VerificationCodeResponseDto response = verificationService.sendVerificationCode(verificationCodeRequestDto.getPhoneNumber()); - return ResponseDto.onSuccess(SuccessStatus._VERIFICATION_SEND, response); + return ResponseDto.onSuccess(response); } @PostMapping("/confirm") - public ResponseDto confirmVerificationCode(@Valid @RequestBody ConfirmCodeRequest confirmCodeRequest){ + public ResponseDto confirmVerificationCode(@Valid @RequestBody ConfirmCodeRequestDto confirmCodeRequestDto) { - verificationService.confirmVerificationCode(confirmCodeRequest.getPhoneNumber(), confirmCodeRequest.getVerificationCode()); + verificationService.confirmVerificationCode(confirmCodeRequestDto.getPhoneNumber(), confirmCodeRequestDto.getVerificationCode()); - return ResponseDto.onSuccess(SuccessStatus._VERIFICATION_CONFIRM); + return ResponseDto.onSuccess(); } } diff --git a/src/main/java/com/softeer/backend/fo_domain/user/domain/User.java b/src/main/java/com/softeer/backend/fo_domain/user/domain/User.java index 08190156..1a8146ec 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/domain/User.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/domain/User.java @@ -13,7 +13,7 @@ @Builder @Table(name = "users", indexes = { - @Index(name = "idx_users_phone_number", columnList = "phoneNumber") + @Index(name = "idx_users_phone_number", columnList = "phoneNumber") }) public class User { @Id diff --git a/src/main/java/com/softeer/backend/fo_domain/user/dto/LoginRequest.java b/src/main/java/com/softeer/backend/fo_domain/user/dto/LoginRequestDto.java similarity index 88% rename from src/main/java/com/softeer/backend/fo_domain/user/dto/LoginRequest.java rename to src/main/java/com/softeer/backend/fo_domain/user/dto/LoginRequestDto.java index 82c1f093..e8f334d4 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/dto/LoginRequest.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/dto/LoginRequestDto.java @@ -1,6 +1,5 @@ package com.softeer.backend.fo_domain.user.dto; -import com.fasterxml.jackson.annotation.JsonProperty; import com.softeer.backend.global.common.constant.ValidationConstant; import jakarta.validation.constraints.Pattern; import lombok.AllArgsConstructor; @@ -12,7 +11,7 @@ @Setter @Builder @AllArgsConstructor -public class LoginRequest { +public class LoginRequestDto { private String name; diff --git a/src/main/java/com/softeer/backend/fo_domain/user/dto/UserTokenResponse.java b/src/main/java/com/softeer/backend/fo_domain/user/dto/UserTokenResponseDto.java similarity index 92% rename from src/main/java/com/softeer/backend/fo_domain/user/dto/UserTokenResponse.java rename to src/main/java/com/softeer/backend/fo_domain/user/dto/UserTokenResponseDto.java index 86a8614b..6f68a6db 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/dto/UserTokenResponse.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/dto/UserTokenResponseDto.java @@ -12,7 +12,7 @@ @Setter @Builder @AllArgsConstructor -public class UserTokenResponse { +public class UserTokenResponseDto { private String accessToken; diff --git a/src/main/java/com/softeer/backend/fo_domain/user/dto/verification/ConfirmCodeRequest.java b/src/main/java/com/softeer/backend/fo_domain/user/dto/verification/ConfirmCodeRequestDto.java similarity index 76% rename from src/main/java/com/softeer/backend/fo_domain/user/dto/verification/ConfirmCodeRequest.java rename to src/main/java/com/softeer/backend/fo_domain/user/dto/verification/ConfirmCodeRequestDto.java index eea411df..0268673f 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/dto/verification/ConfirmCodeRequest.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/dto/verification/ConfirmCodeRequestDto.java @@ -8,13 +8,13 @@ @AllArgsConstructor(access = AccessLevel.PUBLIC) @Builder @Getter -public class ConfirmCodeRequest { +public class ConfirmCodeRequestDto { @Pattern(regexp = ValidationConstant.PHONE_NUMBER_REGEX, - message = ValidationConstant.PHONE_NUMBER_MSG) + message = ValidationConstant.PHONE_NUMBER_MSG) private String phoneNumber; @Pattern(regexp = ValidationConstant.VERIFICATION_CODE_REGEX, - message = ValidationConstant.VERIFICATION_CODE_MSG) + message = ValidationConstant.VERIFICATION_CODE_MSG) private String verificationCode; } diff --git a/src/main/java/com/softeer/backend/fo_domain/user/dto/verification/VerificationCodeRequest.java b/src/main/java/com/softeer/backend/fo_domain/user/dto/verification/VerificationCodeRequestDto.java similarity index 91% rename from src/main/java/com/softeer/backend/fo_domain/user/dto/verification/VerificationCodeRequest.java rename to src/main/java/com/softeer/backend/fo_domain/user/dto/verification/VerificationCodeRequestDto.java index a14a7ce6..23bd49b8 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/dto/verification/VerificationCodeRequest.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/dto/verification/VerificationCodeRequestDto.java @@ -8,7 +8,7 @@ @AllArgsConstructor(access = AccessLevel.PUBLIC) @Builder @Getter -public class VerificationCodeRequest { +public class VerificationCodeRequestDto { @Pattern(regexp = ValidationConstant.PHONE_NUMBER_REGEX, message = ValidationConstant.PHONE_NUMBER_MSG) diff --git a/src/main/java/com/softeer/backend/fo_domain/user/dto/verification/VerificationCodeResponse.java b/src/main/java/com/softeer/backend/fo_domain/user/dto/verification/VerificationCodeResponseDto.java similarity index 83% rename from src/main/java/com/softeer/backend/fo_domain/user/dto/verification/VerificationCodeResponse.java rename to src/main/java/com/softeer/backend/fo_domain/user/dto/verification/VerificationCodeResponseDto.java index 5d298794..0889c69c 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/dto/verification/VerificationCodeResponse.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/dto/verification/VerificationCodeResponseDto.java @@ -6,7 +6,7 @@ @AllArgsConstructor(access = AccessLevel.PUBLIC) @Builder @Getter -public class VerificationCodeResponse { +public class VerificationCodeResponseDto { private int timeLimit; } diff --git a/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java b/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java index 14ff1507..875f4673 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java @@ -1,8 +1,8 @@ package com.softeer.backend.fo_domain.user.service; import com.softeer.backend.fo_domain.user.domain.User; -import com.softeer.backend.fo_domain.user.dto.LoginRequest; -import com.softeer.backend.fo_domain.user.dto.UserTokenResponse; +import com.softeer.backend.fo_domain.user.dto.LoginRequestDto; +import com.softeer.backend.fo_domain.user.dto.UserTokenResponseDto; import com.softeer.backend.fo_domain.user.exception.UserException; import com.softeer.backend.fo_domain.user.repository.UserRepository; import com.softeer.backend.global.common.code.status.ErrorStatus; @@ -10,9 +10,11 @@ import com.softeer.backend.global.common.entity.JwtClaimsDto; import com.softeer.backend.global.util.JwtUtil; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +@Slf4j @Service @RequiredArgsConstructor public class LoginService { @@ -27,22 +29,24 @@ public class LoginService { * 4. User 객체의 id를 얻은 후에, access & refresh token을 client에게 전달한다. */ @Transactional - public UserTokenResponse handleLogin(LoginRequest loginRequest) { + public UserTokenResponseDto handleLogin(LoginRequestDto loginRequestDto) { // 인증번호가 인증 되지 않은 경우, 예외 발생 - if(!loginRequest.getHasCodeVerified()) + if (!loginRequestDto.getHasCodeVerified()) { + log.error("hasCodeVerified is false in loginRequest."); throw new UserException(ErrorStatus._AUTH_CODE_NOT_VERIFIED); + } int userId; // 전화번호가 User DB에 등록되어 있지 않은 경우 // User를 DB에 등록 - if(!userRepository.existsByPhoneNumber(loginRequest.getPhoneNumber())){ + if (!userRepository.existsByPhoneNumber(loginRequestDto.getPhoneNumber())) { User user = User.builder() - .name(loginRequest.getName()) - .phoneNumber(loginRequest.getPhoneNumber()) - .privacyConsent(loginRequest.getPrivacyConsent()) - .marketingConsent(loginRequest.getMarketingConsent()) + .name(loginRequestDto.getName()) + .phoneNumber(loginRequestDto.getPhoneNumber()) + .privacyConsent(loginRequestDto.getPrivacyConsent()) + .marketingConsent(loginRequestDto.getMarketingConsent()) .build(); User registeredUser = userRepository.save(user); @@ -50,8 +54,8 @@ public UserTokenResponse handleLogin(LoginRequest loginRequest) { } // 전화번호가 이미 User DB에 등록되어 있는 경우 // 전화번호로 User 객체 조회 - else{ - User user = userRepository.findByPhoneNumber(loginRequest.getPhoneNumber()); + else { + User user = userRepository.findByPhoneNumber(loginRequestDto.getPhoneNumber()); userId = user.getId(); } diff --git a/src/main/java/com/softeer/backend/fo_domain/user/service/VerificationService.java b/src/main/java/com/softeer/backend/fo_domain/user/service/VerificationService.java index bf4ebea6..8038fa7e 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/service/VerificationService.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/service/VerificationService.java @@ -2,7 +2,7 @@ import com.softeer.backend.fo_domain.user.constatnt.RedisVerificationPrefix; import com.softeer.backend.fo_domain.user.constatnt.VerificationProperty; -import com.softeer.backend.fo_domain.user.dto.verification.VerificationCodeResponse; +import com.softeer.backend.fo_domain.user.dto.verification.VerificationCodeResponseDto; import com.softeer.backend.fo_domain.user.exception.UserException; import com.softeer.backend.fo_domain.user.properties.SmsProperties; import com.softeer.backend.global.common.code.status.ErrorStatus; @@ -39,19 +39,21 @@ public VerificationService(SmsProperties smsProperties, StringRedisUtil stringRe * 1. CoolSms를 사용하여 인증코드를 발급하고 인증 제한시간을 응답에 담아 반환한다. * 2. 인증 코드 발급 제한 횟수를 초과하면 내일 다시 인증하라는 응답을 전송한다. */ - public VerificationCodeResponse sendVerificationCode(String phoneNumber){ + public VerificationCodeResponseDto sendVerificationCode(String phoneNumber) { // 인증코드 발급이 처음이면 redis에 발급 횟수를 저장(유효 기간: 밤 12시 전까지) - if(!stringRedisUtil.hasKey(RedisVerificationPrefix.VERIFICATION_ISSUE_COUNT.getPrefix() + phoneNumber)){ + if (!stringRedisUtil.hasKey(RedisVerificationPrefix.VERIFICATION_ISSUE_COUNT.getPrefix() + phoneNumber)) { stringRedisUtil.setDataExpireAt(RedisVerificationPrefix.VERIFICATION_ISSUE_COUNT.getPrefix(), String.valueOf(1), LocalDateTime.now().toLocalDate().atStartOfDay().plusDays(1)); } // 인증코드 발급 제한 횟수를 초과하면 예외 발생 - else{ + else { long issueCount = stringRedisUtil.incrementData(RedisVerificationPrefix.VERIFICATION_ISSUE_COUNT.getPrefix() + phoneNumber); - if(issueCount > VerificationProperty.CODE_ISSUE_ATTEMPTS.getValue()) + if (issueCount > VerificationProperty.CODE_ISSUE_ATTEMPTS.getValue()) { + log.error("Exceeded the number of code issuance attempts."); throw new UserException(ErrorStatus._AUTH_CODE_ISSUE_LIMIT_EXCEEDED); + } } // 인증코드의 인증 횟수 삭제 (초기화 기능) @@ -63,7 +65,7 @@ public VerificationCodeResponse sendVerificationCode(String phoneNumber){ String verificationCode = randomCodeUtil.generateRandomCode( VerificationProperty.CODE_LENGTH.getValue()); - message.setText("[Hyundai] 본인 확인 인증번호는 ["+verificationCode+"] 입니다."); + message.setText("[Hyundai] 본인 확인 인증번호는 (" + verificationCode + ") 입니다."); SingleMessageSentResponse response = this.messageService.sendOne(new SingleMessageSendingRequest(message)); log.info("Verification code sent to {} {}", phoneNumber, response); @@ -72,7 +74,7 @@ public VerificationCodeResponse sendVerificationCode(String phoneNumber){ stringRedisUtil.setDataExpire(RedisVerificationPrefix.VERIFICATION_CODE.getPrefix() + phoneNumber, verificationCode, VerificationProperty.TIME_LIMIT.getValue()); - return VerificationCodeResponse.builder() + return VerificationCodeResponseDto.builder() .timeLimit(VerificationProperty.TIME_LIMIT.getValue()) .build(); } @@ -82,28 +84,33 @@ public VerificationCodeResponse sendVerificationCode(String phoneNumber){ * 1. 인증 코드를 검증하여 Redis에 있는 인증코도와 같은지를 검사한다. * 2. 제한시간이 지났거나 인증코드 불일치, 혹은 인증 제한 횟수를 초과한 경우 예외를 던진다. */ - public void confirmVerificationCode(String phoneNumber, String verificationCode){ + public void confirmVerificationCode(String phoneNumber, String verificationCode) { // 인증코드의 인증 제한 횟수를 초과하면 예외 발생 - if(stringRedisUtil.hasKey(RedisVerificationPrefix.VERIFICATION_ATTEMPTS.getPrefix() + phoneNumber)){ + if (stringRedisUtil.hasKey(RedisVerificationPrefix.VERIFICATION_ATTEMPTS.getPrefix() + phoneNumber)) { long attemptCount = stringRedisUtil.incrementData(RedisVerificationPrefix.VERIFICATION_ATTEMPTS.getPrefix() + phoneNumber); - if(attemptCount > VerificationProperty.MAX_ATTEMPTS.getValue()){ + if (attemptCount > VerificationProperty.MAX_ATTEMPTS.getValue()) { + log.error("Verification code attempts exceeded."); throw new UserException(ErrorStatus._AUTH_CODE_ATTEMPTS_EXCEEDED); } } // 인증코드의 인증 횟수 설정(유효 기간: 밤 12시 전까지) - else{ + else { stringRedisUtil.setDataExpireAt(RedisVerificationPrefix.VERIFICATION_ATTEMPTS.getPrefix() + phoneNumber, String.valueOf(1), LocalDateTime.now().toLocalDate().atStartOfDay().plusDays(1)); } String originalVerificationCode = stringRedisUtil.getData(RedisVerificationPrefix.VERIFICATION_CODE.getPrefix() + phoneNumber); - if(originalVerificationCode == null) + if (originalVerificationCode == null) { + log.error("Verification code has expired."); throw new UserException(ErrorStatus._AUTH_CODE_NOT_EXIST); + } - if(!originalVerificationCode.equals(verificationCode)) + if (!originalVerificationCode.equals(verificationCode)) { + log.error("Verification code does not match."); throw new UserException(ErrorStatus._AUTH_CODE_NOT_MATCH); + } // 인증 성공 // 인증 관련한 모든 데이터를 삭제 diff --git a/src/main/java/com/softeer/backend/global/annotation/aop/EventLockAop.java b/src/main/java/com/softeer/backend/global/annotation/aop/EventLockAop.java index 041cb7d4..b96dc575 100644 --- a/src/main/java/com/softeer/backend/global/annotation/aop/EventLockAop.java +++ b/src/main/java/com/softeer/backend/global/annotation/aop/EventLockAop.java @@ -23,7 +23,7 @@ @Aspect @Component @RequiredArgsConstructor -public class EventLockAop{ +public class EventLockAop { private static final String REDISSON_LOCK_PREFIX = "LOCK:"; private final RedissonClient redissonClient; @@ -33,7 +33,7 @@ public class EventLockAop{ public Object lock(final ProceedingJoinPoint joinPoint) throws Throwable { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); - EventLock eventLock= method.getAnnotation(EventLock.class); + EventLock eventLock = method.getAnnotation(EventLock.class); String key = REDISSON_LOCK_PREFIX + SpringELParser.getDynamicValue(signature.getParameterNames(), joinPoint.getArgs(), eventLock.key()); RLock rLock = redissonClient.getLock(key); diff --git a/src/main/java/com/softeer/backend/global/annotation/argumentresolver/AuthInfoArgumentResolver.java b/src/main/java/com/softeer/backend/global/annotation/argumentresolver/AuthInfoArgumentResolver.java index ef04e08d..7cab9d86 100644 --- a/src/main/java/com/softeer/backend/global/annotation/argumentresolver/AuthInfoArgumentResolver.java +++ b/src/main/java/com/softeer/backend/global/annotation/argumentresolver/AuthInfoArgumentResolver.java @@ -14,15 +14,15 @@ public class AuthInfoArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { - return parameter.getParameterAnnotation(AuthInfo.class) !=null + return parameter.getParameterAnnotation(AuthInfo.class) != null && parameter.getParameterType().equals(Integer.class); } @Override - public Object resolveArgument(@NonNull MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { + public Object resolveArgument(@NonNull MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { HttpServletRequest req = (HttpServletRequest) webRequest.getNativeRequest(); JwtClaimsDto jwtClaimsDto = (JwtClaimsDto) req.getAttribute("jwtClaims"); - if(jwtClaimsDto == null){ + if (jwtClaimsDto == null) { return null; } return jwtClaimsDto.getId(); diff --git a/src/main/java/com/softeer/backend/global/common/code/status/ErrorStatus.java b/src/main/java/com/softeer/backend/global/common/code/status/ErrorStatus.java index b8060112..c4ebf39d 100644 --- a/src/main/java/com/softeer/backend/global/common/code/status/ErrorStatus.java +++ b/src/main/java/com/softeer/backend/global/common/code/status/ErrorStatus.java @@ -15,50 +15,27 @@ public enum ErrorStatus implements BaseErrorCode { // Common Error & Global Error - _BAD_REQUEST(HttpStatus.BAD_REQUEST, "BAD_REQUEST", "잘못된 요청입니다."), - _UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "UNAUTHORIZED", "인증 과정에서 오류가 발생했습니다."), - _FORBIDDEN(HttpStatus.FORBIDDEN, "FORBIDDEN", "금지된 요청입니다."), - _NOT_FOUND(HttpStatus.NOT_FOUND, "NOT_FOUND", "찾지 못했습니다."), - _METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "METHOD_NOT_ALLOWED", "지원하지 않는 Http Method 입니다."), - _INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "INTERNAL_SERVER_ERROR", "서버 에러가 발생했습니다."), - _METHOD_ARGUMENT_ERROR(HttpStatus.BAD_REQUEST, "METHOD_ARGUMENT_ERROR", - "올바르지 않은 클라이언트 요청값입니다."), + _BAD_REQUEST(HttpStatus.BAD_REQUEST, "G400", "잘못된 요청입니다."), + _FORBIDDEN(HttpStatus.FORBIDDEN, "G401", "해당 요청에 대한 권한이 없습니다."), + _NOT_FOUND(HttpStatus.NOT_FOUND, "G402", "데이터를 찾지 못했습니다."), + _METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "G403", "지원하지 않는 Http Method 입니다."), + _INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "G500", "서버 에러가 발생했습니다."), // Validation Error - _VALIDATION_ERROR(HttpStatus.BAD_REQUEST, "VALIDATION_ERROR", "요청 필드에 대한 검증 예외가 발생했습니다."), + _VALIDATION_ERROR(HttpStatus.BAD_REQUEST, "V400", "요청 필드에 대한 검증 예외가 발생했습니다."), // JWT Error - _JWT_ACCESS_TOKEN_IS_NOT_EXIST(HttpStatus.UNAUTHORIZED, - "JWT_ACCESS_TOKEN_IS_NOT_EXIST", "Authorization 헤더에 Access Token 정보가 존재하지 않습니다."), - _JWT_REFRESH_TOKEN_IS_NOT_EXIST(HttpStatus.UNAUTHORIZED, - "JWT_REFRESH_TOKEN_IS_NOT_EXIST", "Authorization-Refresh 헤더에 JWT 정보가 존재하지 않습니다."), - _JWT_ACCESS_TOKEN_IS_NOT_VALID(HttpStatus.UNAUTHORIZED, "JWT_ACCESS_TOKEN_IS_NOT_VALID", "Access Token 이 유효하지 않습니다."), - _JWT_REFRESH_TOKEN_IS_NOT_VALID(HttpStatus.UNAUTHORIZED, "JWT_REFRESH_TOKEN_IS_NOT_VALID", - "Refresh Token 이 유효하지 않습니다."), - _JWT_ACCESS_TOKEN_IS_VALID(HttpStatus.UNAUTHORIZED, "JWT_ACCESS_TOKEN_IS_VALID", "Access Token 이 유효합니다."), - _JWT_REFRESH_TOKEN_IS_NOT_MATCH(HttpStatus.UNAUTHORIZED, "JWT_REFRESH_TOKEN_IS_NOT_MATCH", - "Refresh Token 이 일치하지 않습니다."), + _UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "J400", "인증 과정에서 예외가 발생했습니다. JWT Token 재발급이 필요합니다."), + _REISSUE_ERROR(HttpStatus.UNAUTHORIZED, "J401", "JWT Token 재발급에서 예외가 발생했습니다. 로그인 요청이 필요합니다."), // User & Auth Error - _USER_NOT_FOUND(HttpStatus.NOT_FOUND, "USER_NOT_FOUND", "유저가 존재하지 않습니다."), - _ACCESS_DENIED(HttpStatus.FORBIDDEN, "ACCESS_DENIED", "해당 요청에 대한 권한이 없습니다."), - _AUTH_CODE_NOT_EXIST(HttpStatus.BAD_REQUEST, "AUTH_CODE_NOT_EXIST", "인증 코드가 존재하지 않습니다. 인증 코드 발급 API를 호출하세요."), - _AUTH_CODE_NOT_MATCH(HttpStatus.BAD_REQUEST, "AUTH_CODE_NOT_MATCH", "인증 코드가 일치하지 않습니다."), - _AUTH_CODE_ATTEMPTS_EXCEEDED(HttpStatus.BAD_REQUEST, "AUTH_CODE_ATTEMPTS_EXCEEDED", + _AUTH_CODE_NOT_EXIST(HttpStatus.BAD_REQUEST, "A400", "인증 코드 제한시간이 초과되었습니다. 인증 코드 발급 API를 호출하세요."), + _AUTH_CODE_NOT_MATCH(HttpStatus.BAD_REQUEST, "A401", "인증 코드가 일치하지 않습니다."), + _AUTH_CODE_ATTEMPTS_EXCEEDED(HttpStatus.BAD_REQUEST, "A402", "인증 코드의 인증 횟수를 초과하였습니다. 인증 코드 발급 API를 호출하세요."), - _AUTH_CODE_ISSUE_LIMIT_EXCEEDED(HttpStatus.BAD_REQUEST, "AUTH_CODE_ISSUE_LIMIT_EXCEEDED", + _AUTH_CODE_ISSUE_LIMIT_EXCEEDED(HttpStatus.BAD_REQUEST, "A403", "인증 코드 발급 횟수를 초과하였습니다. 나중에 다시 시도하세요."), - _AUTH_CODE_NOT_VERIFIED(HttpStatus.BAD_REQUEST, "_AUTH_CODE_NOT_VERIFIED", "인증되지 않은 상태에서 로그인 할 수 없습니다."), - - // Share Error - _SHARE_URL_NOT_FOUND(HttpStatus.NOT_FOUND, "SHARE_URL_NOT_FOUND", "공유 url이 없습니다."), - _SHARE_INFO_NOT_FOUND(HttpStatus.NOT_FOUND, "SHARE_INFO_NOT_FOUND", "공유 정보가 없습니다."), - - // Draw Error - _DRAW_PARTICIPATION_INFO_NOT_FOUND(HttpStatus.NOT_FOUND, "DRAW_PARTICIPATION_INFO_NOT_FOUND", "참여 정보가 없습니다."), - - // Comment Error - _COMMENT_NUM_INVALID(HttpStatus.BAD_REQUEST, "COMMENT_NUM_INVALID", "기대평 순서값이 유효하지 않습니다.(1~5)"); + _AUTH_CODE_NOT_VERIFIED(HttpStatus.BAD_REQUEST, "A404", "인증되지 않은 상태에서 로그인 할 수 없습니다."); // 예외의 Http 상태값 private final HttpStatus httpStatus; diff --git a/src/main/java/com/softeer/backend/global/common/code/status/SuccessStatus.java b/src/main/java/com/softeer/backend/global/common/code/status/SuccessStatus.java index 7c8d5e8f..1525c63e 100644 --- a/src/main/java/com/softeer/backend/global/common/code/status/SuccessStatus.java +++ b/src/main/java/com/softeer/backend/global/common/code/status/SuccessStatus.java @@ -13,23 +13,7 @@ @RequiredArgsConstructor public enum SuccessStatus implements BaseCode { // Success - _OK(HttpStatus.OK, "SUCCESS_200", "OK"), - - // 선착순 - _FCFS_SUCCESS(HttpStatus.OK, "FCFS_SUCCESS", "선착순 당첨 성공 응답"), - _FCFS_FAIL(HttpStatus.OK, "FCFS_FAIL", "선착순 당첨 실패 응답"), - - // 전화번호 인증 - _VERIFICATION_SEND(HttpStatus.OK, "VERIFICATION_SEND", "전화번호 인증 코드 전송 성공"), - _VERIFICATION_CONFIRM(HttpStatus.OK, "VERIFICATION_CONFIRM", "전화번호 인증 코드 검증 성공"), - - // 로그인 - _LOGIN_SUCCESS(HttpStatus.OK, "LOGIN_SUCCESS", "로그인 성공"), - - // 기대평 - _COMMENT_SAVE_SUCCESS(HttpStatus.OK, "COMMENT_SAVE_SUCCESS", "기대평 등록 성공"), - _COMMENT_GET_SUCCESS(HttpStatus.OK, "COMMENT_GET_SUCCESS", "기대평 조회 성공"), - _COMMENT_GET_FINAL_SUCCESS(HttpStatus.OK, "COMMENT_GET_FINAL_SUCCESS", "마지막 기대평 조회 성공"); + _OK(HttpStatus.OK, "S-200", "요청 처리 성공"); // 예외의 Http 상태값 private final HttpStatus httpStatus; @@ -62,7 +46,7 @@ public ResponseDto.ReasonDto getReason() { * @return 커스텀 코드값 */ @Override - public String getCode(){ + public String getCode() { return this.code; } @@ -72,7 +56,7 @@ public String getCode(){ * @return 예외 메시지 */ @Override - public String getMsg(){ + public String getMsg() { return this.message; } } diff --git a/src/main/java/com/softeer/backend/global/common/constant/RoleType.java b/src/main/java/com/softeer/backend/global/common/constant/RoleType.java index 36627cfe..f10febe0 100644 --- a/src/main/java/com/softeer/backend/global/common/constant/RoleType.java +++ b/src/main/java/com/softeer/backend/global/common/constant/RoleType.java @@ -15,7 +15,7 @@ public enum RoleType { String redisKeyPrefix; - RoleType(String redisKeyPrefix){ + RoleType(String redisKeyPrefix) { this.redisKeyPrefix = redisKeyPrefix; } diff --git a/src/main/java/com/softeer/backend/global/common/constant/ValidationConstant.java b/src/main/java/com/softeer/backend/global/common/constant/ValidationConstant.java index 4e6ee3bd..b44ff9d6 100644 --- a/src/main/java/com/softeer/backend/global/common/constant/ValidationConstant.java +++ b/src/main/java/com/softeer/backend/global/common/constant/ValidationConstant.java @@ -3,8 +3,8 @@ import lombok.Getter; public class ValidationConstant { - public static final String PHONE_NUMBER_REGEX ="^01[016789]\\d{8}$"; - public static final String PHONE_NUMBER_MSG ="잘못된 전화번호 형식입니다."; + public static final String PHONE_NUMBER_REGEX = "^01[016789]\\d{8}$"; + public static final String PHONE_NUMBER_MSG = "잘못된 전화번호 형식입니다."; public static final String VERIFICATION_CODE_REGEX = "^[a-zA-Z0-9]{6}$"; public static final String VERIFICATION_CODE_MSG = "잘못된 인증코드 형식입니다."; diff --git a/src/main/java/com/softeer/backend/global/common/exception/ExceptionAdvice.java b/src/main/java/com/softeer/backend/global/common/exception/ExceptionAdvice.java index dee73f47..279a4061 100644 --- a/src/main/java/com/softeer/backend/global/common/exception/ExceptionAdvice.java +++ b/src/main/java/com/softeer/backend/global/common/exception/ExceptionAdvice.java @@ -1,8 +1,7 @@ package com.softeer.backend.global.common.exception; -import com.softeer.backend.fo_domain.fcfs.dto.FcfsFailResponse; +import com.softeer.backend.fo_domain.fcfs.dto.FcfsFailResponseDtoDto; import com.softeer.backend.global.common.code.status.ErrorStatus; -import com.softeer.backend.global.common.code.status.SuccessStatus; import com.softeer.backend.global.common.response.ResponseDto; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; @@ -34,7 +33,7 @@ public class ExceptionAdvice extends ResponseEntityExceptionHandler { * GeneralException을 처리하는 메서드 * * @param generalException 커스텀 예외의 최고 조상 클래스 - * @param webRequest client 요청 객체 + * @param webRequest client 요청 객체 * @return client 응답 객체 */ @ExceptionHandler @@ -52,7 +51,7 @@ public ResponseEntity handleEventLockException(EventLockException eventL * ConstraintViolationException을 처리하는 메서드 * * @param constraintViolationException 검증 예외 - * @param request client 요청 객체 + * @param request client 요청 객체 * @return client 응답 객체 */ @ExceptionHandler @@ -67,13 +66,13 @@ public ResponseEntity handleValidationException(ConstraintViolationExcep /** * MethodArgumentNotValidException을 처리하는 메서드 - * + *

* ResponseEntityExceptionHandler의 메서드를 오버라이딩하여 사용한다. * * @param methodArgumentNotValidException 컨트롤러 메서드의 파라미터 객체에 대한 검증 예외 - * @param headers 헤더 객체 - * @param status HttpStatusCode 값 - * @param request client 요청 객체 + * @param headers 헤더 객체 + * @param status HttpStatusCode 값 + * @param request client 요청 객체 * @return client 응답 객체 */ @Override @@ -91,13 +90,13 @@ public ResponseEntity handleMethodArgumentNotValid( -> existingErrorMessage + ", " + newErrorMessage); }); - return handleArgsExceptionInternal(methodArgumentNotValidException, HttpHeaders.EMPTY, ErrorStatus._BAD_REQUEST, request,errors); + return handleArgsExceptionInternal(methodArgumentNotValidException, HttpHeaders.EMPTY, ErrorStatus._VALIDATION_ERROR, request, errors); } /** * 나머지 모든 예외들을 처리하는 메서드 * - * @param e Exception을 상속한 예외 객체 + * @param e Exception을 상속한 예외 객체 * @param request client 요청 객체 * @return client 응답 객체 */ @@ -117,11 +116,11 @@ public void handleDataAccessException(DataAccessException e) { // GeneralException에 대한 client 응답 객체를 생성하는 메서드 private ResponseEntity handleGeneralExceptionInternal(Exception e, ResponseDto.ErrorReasonDto reason, - HttpHeaders headers, WebRequest webRequest) { + HttpHeaders headers, WebRequest webRequest) { log.error("GeneralException captured in ExceptionAdvice", e); - ResponseDto body = ResponseDto.onFailure(reason.getCode(),reason.getMessage(),null); + ResponseDto body = ResponseDto.onFailure(reason.getCode(), reason.getMessage(), null); return super.handleExceptionInternal( e, @@ -141,8 +140,8 @@ private ResponseEntity handleEventLockExceptionInternal(EventLockExcepti ResponseDto body = null; - if(redissonKeyName.contains("FCFS")) - body = ResponseDto.onSuccess(SuccessStatus._FCFS_FAIL, new FcfsFailResponse(1)); + if (redissonKeyName.contains("FCFS")) + body = ResponseDto.onSuccess(new FcfsFailResponseDtoDto(1)); //TODO // DRAW 관련 예외일 경우, body 구성하는 코드 필요 @@ -188,10 +187,10 @@ private ResponseEntity handleArgsExceptionInternal(Exception e, HttpHead // 나머지 모든 예외에 대한 client 응답 객체를 생성하는 메서드 private ResponseEntity handleGlobalExceptionInternal(Exception e, ErrorStatus errorCommonStatus, - HttpHeaders headers, HttpStatus status, WebRequest request, String errorPoint) { + HttpHeaders headers, HttpStatus status, WebRequest request, String errorPoint) { log.error("Exception captured in ExceptionAdvice", e); - ResponseDto body = ResponseDto.onFailure(errorCommonStatus.getCode(),errorCommonStatus.getMessage(),errorPoint); + ResponseDto body = ResponseDto.onFailure(errorCommonStatus.getCode(), errorCommonStatus.getMessage(), errorPoint); return super.handleExceptionInternal( e, body, diff --git a/src/main/java/com/softeer/backend/global/common/exception/JwtAuthenticationException.java b/src/main/java/com/softeer/backend/global/common/exception/JwtAuthenticationException.java index e9e4bf15..e6e7341e 100644 --- a/src/main/java/com/softeer/backend/global/common/exception/JwtAuthenticationException.java +++ b/src/main/java/com/softeer/backend/global/common/exception/JwtAuthenticationException.java @@ -8,7 +8,7 @@ */ public class JwtAuthenticationException extends GeneralException { - public JwtAuthenticationException(BaseErrorCode code){ + public JwtAuthenticationException(BaseErrorCode code) { super(code); } } diff --git a/src/main/java/com/softeer/backend/global/common/response/ResponseDto.java b/src/main/java/com/softeer/backend/global/common/response/ResponseDto.java index e948f241..1ba9145c 100644 --- a/src/main/java/com/softeer/backend/global/common/response/ResponseDto.java +++ b/src/main/java/com/softeer/backend/global/common/response/ResponseDto.java @@ -33,16 +33,19 @@ public class ResponseDto { @JsonInclude(JsonInclude.Include.NON_NULL) private final T result; - public static ResponseDto onSuccess(BaseCode code) { - return new ResponseDto<>(true, code.getCode(), code.getMsg(), null); + /** + * 요청 처리에는 성공했지만, 보낼 데이터가 없을 경우 사용하는 메서드 + */ + public static ResponseDto onSuccess() { + return new ResponseDto<>(true, SuccessStatus._OK.getCode(), SuccessStatus._OK.getMessage(), null); } /** * client 요청 처리 성공 시의 응답값을 생성하는 메서드 * * @param result client 응답에 넣을 객체 + * @param 응답에 담을 객체 타입 * @return client 응답 객체 - * @param 응답에 담을 객체 타입 */ public static ResponseDto onSuccess(T result) { return new ResponseDto<>(true, SuccessStatus._OK.getCode(), SuccessStatus._OK.getMessage(), result); @@ -51,36 +54,36 @@ public static ResponseDto onSuccess(T result) { /** * client 요청 처리 성공 시의 응답값을 생성하는 메서드 * - * @param code 성공 응답 코드 + * @param code 성공 응답 코드 * @param result client 응답에 넣을 객체 + * @param 응답에 담을 객체 타입 * @return client 응답 객체 - * @param 응답에 담을 객체 타입 */ - public static ResponseDto onSuccess(BaseCode code, T result){ - return new ResponseDto<>(true, code.getCode() , code.getMsg(), result); + public static ResponseDto onSuccess(BaseCode code, T result) { + return new ResponseDto<>(true, code.getCode(), code.getMsg(), result); } /** * client 요청 처리 실패 시의 응답값을 생성하는 메서드 * * @param code 실패 응답 코드 + * @param 응답에 담을 객체 타입 * @return client 응답 객체 - * @param 응답에 담을 객체 타입 */ - public static ResponseDto onFailure(BaseErrorCode code){ + public static ResponseDto onFailure(BaseErrorCode code) { return new ResponseDto<>(false, code.getCode(), code.getErrorMsg(), null); } /** * client 요청 처리 실패 시의 응답값을 생성하는 메서드 * - * @param code code 실패 응답 코드 + * @param code code 실패 응답 코드 * @param message 실패 응답 메시지 - * @param result client 응답에 넣을 객체 + * @param result client 응답에 넣을 객체 + * @param 응답에 담을 객체 타입 * @return client 응답 객체 - * @param 응답에 담을 객체 타입 */ - public static ResponseDto onFailure(String code, String message, T result){ + public static ResponseDto onFailure(String code, String message, T result) { return new ResponseDto<>(false, code, message, result); } diff --git a/src/main/java/com/softeer/backend/global/config/docs/SwaggerConfig.java b/src/main/java/com/softeer/backend/global/config/docs/SwaggerConfig.java index 2ba4cb38..98676316 100644 --- a/src/main/java/com/softeer/backend/global/config/docs/SwaggerConfig.java +++ b/src/main/java/com/softeer/backend/global/config/docs/SwaggerConfig.java @@ -54,11 +54,13 @@ public OpenAPI getOpenApi() { .components(components) .addSecurityItem(securityItem); } + private SecurityScheme getJwtSecurityScheme() { return new SecurityScheme() .type(SecurityScheme.Type.APIKEY) .in(SecurityScheme.In.HEADER) - .name(jwtProperties.getAccessHeader());} + .name(jwtProperties.getAccessHeader()); + } private SecurityScheme getJwtRefreshSecurityScheme() { return new SecurityScheme() diff --git a/src/main/java/com/softeer/backend/global/config/properties/JwtProperties.java b/src/main/java/com/softeer/backend/global/config/properties/JwtProperties.java index 6f9f9e49..2c122436 100644 --- a/src/main/java/com/softeer/backend/global/config/properties/JwtProperties.java +++ b/src/main/java/com/softeer/backend/global/config/properties/JwtProperties.java @@ -6,7 +6,7 @@ /** * JWT 속성 관리 클래스 - * + *

* bearer: JWT 토큰 타입 * secret: JWT 비밀 키 * accessHeader: Access Token 헤더 이름 @@ -26,7 +26,7 @@ public class JwtProperties { @ConstructorBinding public JwtProperties(String bearer, String secret, String accessHeader, String refreshHeader, - Long accessExpiration, Long refreshExpiration){ + Long accessExpiration, Long refreshExpiration) { this.bearer = bearer; this.secret = secret; this.accessHeader = accessHeader; diff --git a/src/main/java/com/softeer/backend/global/config/properties/RedisProperties.java b/src/main/java/com/softeer/backend/global/config/properties/RedisProperties.java index f9849409..c1faf2b7 100644 --- a/src/main/java/com/softeer/backend/global/config/properties/RedisProperties.java +++ b/src/main/java/com/softeer/backend/global/config/properties/RedisProperties.java @@ -6,7 +6,7 @@ /** * Redis 속성 관리 클래스 - * + *

* host: Redis host 정보 * port: Redis 포트 정보 */ @@ -17,7 +17,7 @@ public class RedisProperties { private final Integer port; @ConstructorBinding - public RedisProperties(String host, Integer port){ + public RedisProperties(String host, Integer port) { this.host = host; this.port = port; } diff --git a/src/main/java/com/softeer/backend/global/config/redis/RedisConfig.java b/src/main/java/com/softeer/backend/global/config/redis/RedisConfig.java index ad604605..1b053a8c 100644 --- a/src/main/java/com/softeer/backend/global/config/redis/RedisConfig.java +++ b/src/main/java/com/softeer/backend/global/config/redis/RedisConfig.java @@ -25,7 +25,7 @@ public class RedisConfig { private final RedisProperties redisProperties; @Bean - public RedisConnectionFactory redisConnectionFactory(){ + public RedisConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory(redisProperties.getHost(), redisProperties.getPort()); } diff --git a/src/main/java/com/softeer/backend/global/config/web/WebMvcConfig.java b/src/main/java/com/softeer/backend/global/config/web/WebMvcConfig.java index 6742992e..aebbbd41 100644 --- a/src/main/java/com/softeer/backend/global/config/web/WebMvcConfig.java +++ b/src/main/java/com/softeer/backend/global/config/web/WebMvcConfig.java @@ -48,7 +48,7 @@ public void addArgumentResolvers(List resolvers) public void addCorsMappings(CorsRegistry registry) { // TODO: Origin 도메인 수정 및 헤더값 설정 registry.addMapping("/**") - .allowedOrigins("http://localhost:5000") // 허용할 도메인 설정 + .allowedOrigins("https://softeer.site", "http://localhost:5173") // 허용할 도메인 설정 .allowedMethods("OPTIONS", "GET", "POST", "PUT", "DELETE") // 허용할 HTTP 메서드 설정 .allowedHeaders("Content-Type", "Authorization", "Authorization-Refresh") // 허용할 헤더 설정 .exposedHeaders("Authorization", "Authorization-Refresh") // 클라이언트에 노출할 헤더 설정 diff --git a/src/main/java/com/softeer/backend/global/filter/ExceptionHandlingFilter.java b/src/main/java/com/softeer/backend/global/filter/ExceptionHandlingFilter.java index 6a7ce6e2..af936a4e 100644 --- a/src/main/java/com/softeer/backend/global/filter/ExceptionHandlingFilter.java +++ b/src/main/java/com/softeer/backend/global/filter/ExceptionHandlingFilter.java @@ -25,11 +25,11 @@ public class ExceptionHandlingFilter extends OncePerRequestFilter { private final ObjectMapper objectMapper; @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain){ + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) { try { filterChain.doFilter(request, response); // Jwt 인증 예외 처리 - } catch (JwtAuthenticationException jwtAuthenticationException){ + } catch (JwtAuthenticationException jwtAuthenticationException) { log.error("JwtAuthenticationException occurs in ExceptionHandlingFilter", jwtAuthenticationException); @@ -37,7 +37,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse setErrorResponse(response, jwtAuthenticationException.getCode()); // 나머지 예외 처리 - } catch(Exception e){ + } catch (Exception e) { log.error("Exception occurs in ExceptionHandlingFilter", e); @@ -47,7 +47,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse // 인증 예외 처리 메서드 private void setErrorResponse(HttpServletResponse response, - BaseErrorCode errorCode){ + BaseErrorCode errorCode) { response.setStatus(errorCode.getHttpStatus().value()); diff --git a/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java b/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java index 11b71c58..5dc46d21 100644 --- a/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java +++ b/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java @@ -9,7 +9,7 @@ import com.softeer.backend.global.config.properties.JwtProperties; import com.softeer.backend.global.util.JwtUtil; import com.softeer.backend.global.util.StringRedisUtil; -import com.softeer.backend.fo_domain.user.dto.UserTokenResponse; +import com.softeer.backend.fo_domain.user.dto.UserTokenResponseDto; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -52,14 +52,14 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // preflight 요청 또는 whitelist에 있는 요청은 인증 검사 x - if(CorsUtils.isPreFlightRequest(request) || isUriInWhiteList(request.getRequestURI())){ + if (CorsUtils.isPreFlightRequest(request) || isUriInWhiteList(request.getRequestURI())) { filterChain.doFilter(request, response); return; } // optionalAuthUrls에 등록된 url 중, access token이 header에 없으면 인증 x - if(isUriInOptionalAuthList(request.getRequestURI()) && - jwtUtil.extractAccessToken(request).isEmpty()){ + if (isUriInOptionalAuthList(request.getRequestURI()) && + jwtUtil.extractAccessToken(request).isEmpty()) { filterChain.doFilter(request, response); return; @@ -68,12 +68,14 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse // Case 01) Access Token 재발급인 경우(Authorization Header Access Token 유효성 x) if (request.getRequestURI().contains("/reissue")) { - String accessToken = jwtUtil.extractAccessToken(request).orElseThrow( - () -> new JwtAuthenticationException(ErrorStatus._JWT_ACCESS_TOKEN_IS_NOT_EXIST) - ); - String refreshToken = jwtUtil.extractRefreshToken(request).orElseThrow( - () -> new JwtAuthenticationException(ErrorStatus._JWT_REFRESH_TOKEN_IS_NOT_EXIST) - ); + String accessToken = jwtUtil.extractAccessToken(request).orElseThrow(() -> { + log.error("Access Token is missing in the Authorization header during the '/reissue' process."); + return new JwtAuthenticationException(ErrorStatus._REISSUE_ERROR); + }); + String refreshToken = jwtUtil.extractRefreshToken(request).orElseThrow(() -> { + log.error("Refresh Token is missing in the Authorization header during the '/reissue' process."); + return new JwtAuthenticationException(ErrorStatus._REISSUE_ERROR); + }); this.reissueAccessTokenAndRefreshToken(response, accessToken, refreshToken); } @@ -123,21 +125,26 @@ private void checkAllConditions(String accessToken, String refreshToken) { private void validateAccessToken(String accessToken) { if (jwtUtil.validateToken(accessToken)) { - throw new JwtAuthenticationException(ErrorStatus._JWT_ACCESS_TOKEN_IS_NOT_VALID); + log.error("JWT Access Token is valid during the '/reissue' process."); + throw new JwtAuthenticationException(ErrorStatus._REISSUE_ERROR); } } private void validateRefreshToken(String refreshToken) { if (!this.jwtUtil.validateToken(refreshToken)) { - throw new JwtAuthenticationException(ErrorStatus._JWT_REFRESH_TOKEN_IS_NOT_VALID); + log.error("JWT Refresh Token is invalid during the '/reissue' process."); + throw new JwtAuthenticationException(ErrorStatus._REISSUE_ERROR); } } private void isRefreshTokenMatch(String refreshToken) { JwtClaimsDto jwtClaimsDto = jwtUtil.getJwtClaimsFromRefreshToken(refreshToken); - if (!refreshToken.equals(stringRedisUtil.getData(stringRedisUtil.getRedisKeyForJwt(jwtClaimsDto)))) { - throw new JwtAuthenticationException(ErrorStatus._JWT_REFRESH_TOKEN_IS_NOT_EXIST); + if (stringRedisUtil.getData(stringRedisUtil.getRedisKeyForJwt(jwtClaimsDto)) == null || + !refreshToken.equals(stringRedisUtil.getData(stringRedisUtil.getRedisKeyForJwt(jwtClaimsDto)))) { + + log.error("WT Refresh Token is either missing in Redis or does not match the token in Redis."); + throw new JwtAuthenticationException(ErrorStatus._REISSUE_ERROR); } } @@ -165,23 +172,23 @@ private void makeAndSendAccessTokenAndRefreshToken(HttpServletResponse response, String refreshToken) throws IOException { LocalDateTime expireTime = LocalDateTime.now().plusSeconds(this.jwtProperties.getAccessExpiration() / 1000); // refresh token, access token 을 응답 본문에 넣어 응답 - UserTokenResponse userTokenResponse = UserTokenResponse.builder() + UserTokenResponseDto userTokenResponseDto = UserTokenResponseDto.builder() .accessToken(accessToken) .refreshToken(refreshToken) .expiredTime(expireTime) .build(); - makeResultResponse(response, userTokenResponse); + makeResultResponse(response, userTokenResponseDto); } private void makeResultResponse(HttpServletResponse response, - UserTokenResponse userTokenResponse) throws IOException { + UserTokenResponseDto userTokenResponseDto) throws IOException { response.setStatus(HttpStatus.OK.value()); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); try (OutputStream os = response.getOutputStream()) { ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()); - ResponseDto responseDto = ResponseDto.onSuccess(userTokenResponse); + ResponseDto responseDto = ResponseDto.onSuccess(userTokenResponseDto); objectMapper.writeValue(os, responseDto); os.flush(); } @@ -190,7 +197,10 @@ private void makeResultResponse(HttpServletResponse response, private void checkAccessToken(HttpServletRequest request) { String accessToken = jwtUtil.extractAccessToken(request) - .orElseThrow(() -> new JwtAuthenticationException(ErrorStatus._JWT_ACCESS_TOKEN_IS_NOT_EXIST)); + .orElseThrow(() -> { + log.error("Access Token is missing in the Authorization header."); + return new JwtAuthenticationException(ErrorStatus._UNAUTHORIZED); + }); JwtClaimsDto jwtClaimsDto = jwtUtil.getJwtClaimsFromAccessToken(accessToken); diff --git a/src/main/java/com/softeer/backend/global/filter/JwtAuthorizationFilter.java b/src/main/java/com/softeer/backend/global/filter/JwtAuthorizationFilter.java index ac75f516..36c1e11f 100644 --- a/src/main/java/com/softeer/backend/global/filter/JwtAuthorizationFilter.java +++ b/src/main/java/com/softeer/backend/global/filter/JwtAuthorizationFilter.java @@ -9,6 +9,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.web.filter.OncePerRequestFilter; import java.io.IOException; @@ -16,6 +17,7 @@ /** * 유저의 권한을 검증하는 필터 클래스 */ +@Slf4j @NoArgsConstructor public class JwtAuthorizationFilter extends OncePerRequestFilter { @Override @@ -23,8 +25,11 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse JwtClaimsDto jwtClaimsDto = (JwtClaimsDto) request.getAttribute("jwtClaims"); - if(jwtClaimsDto == null || jwtClaimsDto.getRoleType()!= RoleType.ROLE_ADMIN) - throw new JwtAuthorizationException(ErrorStatus._ACCESS_DENIED); + if (jwtClaimsDto == null || jwtClaimsDto.getRoleType() != RoleType.ROLE_ADMIN) { + + log.error("JwtAuthorizationException has occurred"); + throw new JwtAuthorizationException(ErrorStatus._FORBIDDEN); + } filterChain.doFilter(request, response); } diff --git a/src/main/java/com/softeer/backend/global/util/JwtUtil.java b/src/main/java/com/softeer/backend/global/util/JwtUtil.java index a6cc02da..77cc1e1b 100644 --- a/src/main/java/com/softeer/backend/global/util/JwtUtil.java +++ b/src/main/java/com/softeer/backend/global/util/JwtUtil.java @@ -5,7 +5,7 @@ import com.softeer.backend.global.common.entity.JwtClaimsDto; import com.softeer.backend.global.common.exception.JwtAuthenticationException; import com.softeer.backend.global.config.properties.JwtProperties; -import com.softeer.backend.fo_domain.user.dto.UserTokenResponse; +import com.softeer.backend.fo_domain.user.dto.UserTokenResponseDto; import io.jsonwebtoken.*; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; @@ -29,7 +29,7 @@ public Optional extractAccessToken(HttpServletRequest request) { return Optional.ofNullable(request.getHeader(jwtProperties.getAccessHeader())) .filter(StringUtils::hasText) .filter(accessToken -> accessToken.startsWith(jwtProperties.getBearer())) - .map(accessToken -> accessToken.substring(jwtProperties.getBearer().length()+1)); + .map(accessToken -> accessToken.substring(jwtProperties.getBearer().length() + 1)); } // HttpServletRequest 부터 Refresh Token 추출 @@ -55,7 +55,8 @@ public JwtClaimsDto getJwtClaimsFromAccessToken(String token) { return getAuthInfoFromToken(token); } catch (Exception exception) { - throw new JwtAuthenticationException(ErrorStatus._JWT_ACCESS_TOKEN_IS_NOT_VALID); + log.error("Access Token is invalid."); + throw new JwtAuthenticationException(ErrorStatus._UNAUTHORIZED); } } @@ -66,12 +67,13 @@ public JwtClaimsDto getJwtClaimsFromRefreshToken(String token) { return getAuthInfoFromToken(token); } catch (Exception exception) { - throw new JwtAuthenticationException(ErrorStatus._JWT_REFRESH_TOKEN_IS_NOT_VALID); + log.error("JWT Refresh Token is invalid during the '/reissue' process."); + throw new JwtAuthenticationException(ErrorStatus._REISSUE_ERROR); } } // Jwt Token 에서 claim 정보를 파싱하여 반환하는 메서드 - private JwtClaimsDto getAuthInfoFromToken(String token){ + private JwtClaimsDto getAuthInfoFromToken(String token) { Claims claims = Jwts.parser() .setSigningKey(jwtProperties.getSecret()) .parseClaimsJws(token) @@ -87,13 +89,13 @@ private JwtClaimsDto getAuthInfoFromToken(String token){ } // 전화번호 로그인 및 admin 로그인 시 jwt 응답 생성 + redis refresh 저장 - public UserTokenResponse createServiceToken(JwtClaimsDto jwtClaimsDto) { + public UserTokenResponseDto createServiceToken(JwtClaimsDto jwtClaimsDto) { stringRedisUtil.deleteData(stringRedisUtil.getRedisKeyForJwt(jwtClaimsDto)); String accessToken = createAccessToken(jwtClaimsDto); String refreshToken = createRefreshToken(jwtClaimsDto); // 서비스 토큰 생성 - UserTokenResponse userTokenResponse = UserTokenResponse.builder() + UserTokenResponseDto userTokenResponseDto = UserTokenResponseDto.builder() .accessToken(accessToken) .refreshToken(refreshToken) .expiredTime(LocalDateTime.now().plusSeconds(jwtProperties.getAccessExpiration() / 1000)) @@ -101,9 +103,9 @@ public UserTokenResponse createServiceToken(JwtClaimsDto jwtClaimsDto) { // redis refresh token 저장 stringRedisUtil.setDataExpire(stringRedisUtil.getRedisKeyForJwt(jwtClaimsDto), - userTokenResponse.getRefreshToken(), jwtProperties.getRefreshExpiration()); + userTokenResponseDto.getRefreshToken(), jwtProperties.getRefreshExpiration()); - return userTokenResponse; + return userTokenResponseDto; } // token 유효성 검증 @@ -119,16 +121,16 @@ public boolean validateToken(String token) { log.warn("지원되지 않는 jwt 입니다."); } catch (IllegalArgumentException exception) { log.warn("token에 값이 없습니다."); - } catch(SignatureException exception){ + } catch (SignatureException exception) { log.warn("signature에 오류가 존재합니다."); - } catch(MalformedJwtException exception){ + } catch (MalformedJwtException exception) { log.warn("jwt가 유효하지 않습니다."); } return false; } // 실제 token 생성 로직 - private String createToken(JwtClaimsDto jwtClaimsDto, Long tokenExpiration) { + private String createToken(JwtClaimsDto jwtClaimsDto, Long tokenExpiration) { Claims claims = Jwts.claims(); claims.put("id", jwtClaimsDto.getId()); claims.put("roleType", jwtClaimsDto.getRoleType().name()); From d27eb9d8bdd7841b43e91e916288621d71edb73a Mon Sep 17 00:00:00 2001 From: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Date: Sun, 11 Aug 2024 03:18:14 +0900 Subject: [PATCH 22/39] =?UTF-8?q?[Feat]Admin=20Api=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?(#67)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: Admin entity 클래스 생성 * feat: Admin exception 클래스 생성 * feat: Admin 로그인 컨트롤러 구현 * feat: Admin 로그인 요청 dto 구현 * feat: Admin 로그인 서비스 클래스 구현 * feat: Admin repository 구현 * feat: 추첨 이벤트 시간 설정 요청 dto 구현 * feat: 추첨 시간 검증 클래스 구현 * feat: 추첨 당첨자 응답 dto 구현 * feat: 추첨 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 응답 dto 구현 * feat: 이벤트 페이지 컨트롤러 구현 * feat: 이벤트 페이지 service 클래스 구현 * feat: 선착순 날짜 검증 클래스 구현 * feat: 선착순 날짜 등록 요청 dto 구현 * feat: 선착순 시간 검증 클래스 구현 * feat: 선착순 당첨자 응답 dto 구현 * feat: 선착순 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 컨트롤러 클래스 구현 * feat: 이벤트 지표 service 클래스 구현 * feat: 메인 페이지 관련 컨트롤러 클래스 구현 * feat: 메인 페이지 응답 dto 구현 * feat: 메인 페이지 service 클래스 구현 * feat: password encoder 구현 * feat: 확률값을 %형태로 바꿔주는 serializer 구현 * feat: 전화번호에 '-'를 붙여주는 serializer 구현 * feat: 추첨 시간 검증 애노테이션 구현 * feat: 선착순 날짜 검증 애노테이션 구현 * feat: 선착순 시간 검증 애노테이션 구현 * feat: 당첨 관리 페이지 컨트롤러 클래스 구현 * feat: 당첨 관리 페이지 service 클래스 구현 * config: Bcrypt 의존성 설정 * refactor: winningDate 변수의 자료형 변경 * feat: Draw, User를 조회하는 메서드 구현 * refactor: 변수명 변경 * feat: Transactional 애노테이션 추가 * refactor: 자료형 변경 및 시간 관련 변수 분리 * refactor: 자료형 변경 * feat: eventDate 변수 추가 * feat: EventParticipation 조회 메서드 구현 * feat: round값으로 Fcfs 조회하는 메서드 구현 * feat: @setter 애노테이션 추가 * docs: TODO 추가 * refactor: 클래스명 변경 * refactor: 패키지 변경 * refactor: 패키지 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 변경 * refactor: Refresh Token을 삭제하는 메서드 구현 * refactor: 커스텀 코드값 변경 * refactor: 검증 관련 상수 추가 * style: 코드 형식 맞추기 --------- Co-authored-by: hyeokson --- build.gradle | 11 +- .../controller/AdminLoginController.java | 37 ++++++ .../admin/controller/EventPageController.java | 35 +++++ .../controller/IndicatorPageController.java | 25 ++++ .../admin/controller/MainPageController.java | 23 ++++ .../controller/WinnerPageController.java | 52 ++++++++ .../backend/bo_domain/admin/domain/Admin.java | 28 ++++ .../dto/event/DrawEventTimeRequestDto.java | 22 ++++ .../dto/event/FcfsEventTimeRequestDto.java | 29 +++++ .../indicator/EventIndicatorResponseDto.java | 89 +++++++++++++ .../admin/dto/login/AdminLoginRequestDto.java | 20 +++ .../admin/dto/main/MainPageResponseDto.java | 123 ++++++++++++++++++ .../dto/winner/DrawWinnerListResponseDto.java | 48 +++++++ .../winner/DrawWinnerUpdateRequestDto.java | 16 +++ .../dto/winner/FcfsWinnerListResponseDto.java | 47 +++++++ .../winner/FcfsWinnerUpdateRequestDto.java | 14 ++ .../admin/exception/AdminException.java | 11 ++ .../admin/repository/AdminRepository.java | 12 ++ .../serializer/PercentageSerializer.java | 19 +++ .../serializer/PhoneNumberSerializer.java | 17 +++ .../admin/service/AdminLoginService.java | 57 ++++++++ .../admin/service/EventPageService.java | 78 +++++++++++ .../admin/service/IndicatorPageService.java | 32 +++++ .../admin/service/MainPageService.java | 29 +++++ .../admin/service/WinnerPageService.java | 69 ++++++++++ .../bo_domain/admin/util/PasswordEncoder.java | 18 +++ .../validator/DrawTimeRangeValidator.java | 39 ++++++ .../validator/FcfsDateRangeValidator.java | 41 ++++++ .../validator/FcfsTimeRangeValidator.java | 34 +++++ .../annotation/ValidDrawTimeRange.java | 22 ++++ .../annotation/ValidFcfsDateRange.java | 21 +++ .../annotation/ValidFcfsTimeRange.java | 21 +++ .../domain/EventParticipation.java | 9 +- .../EventParticipationRepository.java | 6 + .../comment/service/CommentService.java | 3 + .../backend/fo_domain/draw/domain/Draw.java | 3 +- .../fo_domain/draw/domain/DrawSetting.java | 17 ++- .../draw/repository/DrawRepository.java | 7 + .../draw/service/DrawSettingManager.java | 12 +- .../fo_domain/fcfs/domain/FcfsSetting.java | 6 +- .../fcfs/repository/FcfsRepository.java | 7 + .../fcfs/service/FcfsSettingManager.java | 1 + .../user/controller/LoginController.java | 8 +- .../fo_domain/user/service/LoginService.java | 8 +- .../AuthInfoArgumentResolver.java | 2 +- .../common/code/status/SuccessStatus.java | 2 +- .../common/constant/ValidationConstant.java | 11 ++ .../common/{entity => dto}/JwtClaimsDto.java | 2 +- .../common/dto/JwtTokenResponseDto.java} | 4 +- .../filter/JwtAuthenticationFilter.java | 12 +- .../global/filter/JwtAuthorizationFilter.java | 2 +- .../softeer/backend/global/util/JwtUtil.java | 12 +- .../backend/global/util/StringRedisUtil.java | 8 +- 53 files changed, 1239 insertions(+), 42 deletions(-) create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminLoginController.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/controller/EventPageController.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/controller/IndicatorPageController.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/controller/MainPageController.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/controller/WinnerPageController.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/domain/Admin.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/dto/event/DrawEventTimeRequestDto.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/dto/event/FcfsEventTimeRequestDto.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/dto/indicator/EventIndicatorResponseDto.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/dto/login/AdminLoginRequestDto.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/dto/main/MainPageResponseDto.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/DrawWinnerListResponseDto.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/DrawWinnerUpdateRequestDto.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/FcfsWinnerListResponseDto.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/FcfsWinnerUpdateRequestDto.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/exception/AdminException.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/repository/AdminRepository.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/serializer/PercentageSerializer.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/serializer/PhoneNumberSerializer.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/service/AdminLoginService.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/service/EventPageService.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/service/IndicatorPageService.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/service/MainPageService.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/service/WinnerPageService.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/util/PasswordEncoder.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/validator/DrawTimeRangeValidator.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/validator/FcfsDateRangeValidator.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/validator/FcfsTimeRangeValidator.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/validator/annotation/ValidDrawTimeRange.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/validator/annotation/ValidFcfsDateRange.java create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/validator/annotation/ValidFcfsTimeRange.java rename src/main/java/com/softeer/backend/global/common/{entity => dto}/JwtClaimsDto.java (86%) rename src/main/java/com/softeer/backend/{fo_domain/user/dto/UserTokenResponseDto.java => global/common/dto/JwtTokenResponseDto.java} (82%) diff --git a/build.gradle b/build.gradle index de2269ad..cfc40bd7 100644 --- a/build.gradle +++ b/build.gradle @@ -36,8 +36,12 @@ dependencies { // JWT 설정 implementation 'io.jsonwebtoken:jjwt:0.9.1' - implementation "com.googlecode.json-simple:json-simple:1.1.1" // Google Simple JSON - implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' //DatatypeConverter + + // Google Simple JSON + implementation "com.googlecode.json-simple:json-simple:1.1.1" + + //DatatypeConverter + implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' // JPA 설정 implementation 'org.springframework.boot:spring-boot-starter-data-jpa' @@ -55,6 +59,9 @@ dependencies { // cool sms 설정 implementation 'net.nurigo:sdk:4.3.0' + // Bcrypt 설정 + implementation 'org.mindrot:jbcrypt:0.4' + compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminLoginController.java b/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminLoginController.java new file mode 100644 index 00000000..08d04de1 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminLoginController.java @@ -0,0 +1,37 @@ +package com.softeer.backend.bo_domain.admin.controller; + +import com.softeer.backend.bo_domain.admin.dto.login.AdminLoginRequestDto; +import com.softeer.backend.bo_domain.admin.service.AdminLoginService; +import com.softeer.backend.global.annotation.AuthInfo; +import com.softeer.backend.global.common.dto.JwtTokenResponseDto; +import com.softeer.backend.global.common.response.ResponseDto; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +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; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/admin") +public class AdminLoginController { + + private final AdminLoginService adminLoginService; + + @PostMapping("/login") + ResponseDto handleLogin(@Valid @RequestBody AdminLoginRequestDto adminLoginRequestDto) { + JwtTokenResponseDto jwtTokenResponseDto = adminLoginService.handleLogin(adminLoginRequestDto); + + return ResponseDto.onSuccess(jwtTokenResponseDto); + } + + @PostMapping("/logout") + ResponseDto handleLogout(@AuthInfo Integer adminId) { + adminLoginService.handleLogout(adminId); + + return ResponseDto.onSuccess(); + } + + +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/controller/EventPageController.java b/src/main/java/com/softeer/backend/bo_domain/admin/controller/EventPageController.java new file mode 100644 index 00000000..6b72e67f --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/controller/EventPageController.java @@ -0,0 +1,35 @@ +package com.softeer.backend.bo_domain.admin.controller; + +import com.softeer.backend.bo_domain.admin.dto.event.DrawEventTimeRequestDto; +import com.softeer.backend.bo_domain.admin.dto.event.FcfsEventTimeRequestDto; +import com.softeer.backend.bo_domain.admin.service.EventPageService; +import com.softeer.backend.global.common.response.ResponseDto; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +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; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/admin/event") +public class EventPageController { + + private final EventPageService eventPageService; + + @PostMapping("/fcfs") + public ResponseDto updateFcfsEventTime(@Valid @RequestBody FcfsEventTimeRequestDto fcfsEventTimeRequestDto) { + eventPageService.updateFcfsEventTime(fcfsEventTimeRequestDto); + + return ResponseDto.onSuccess(); + } + + @PostMapping("/draw") + public ResponseDto updateDrawEventTime(@Valid @RequestBody DrawEventTimeRequestDto drawEventTimeRequestDto) { + eventPageService.updateDrawEventTime(drawEventTimeRequestDto); + + return ResponseDto.onSuccess(); + } + +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/controller/IndicatorPageController.java b/src/main/java/com/softeer/backend/bo_domain/admin/controller/IndicatorPageController.java new file mode 100644 index 00000000..d9e94e43 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/controller/IndicatorPageController.java @@ -0,0 +1,25 @@ +package com.softeer.backend.bo_domain.admin.controller; + +import com.softeer.backend.bo_domain.admin.dto.indicator.EventIndicatorResponseDto; +import com.softeer.backend.bo_domain.admin.service.IndicatorPageService; +import com.softeer.backend.fo_domain.draw.repository.DrawSettingRepository; +import com.softeer.backend.global.common.response.ResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/admin") +public class IndicatorPageController { + + private final IndicatorPageService indicatorPageService; + + @GetMapping("/indicator") + public ResponseDto getEventIndicator() { + EventIndicatorResponseDto eventIndicatorResponseDto = indicatorPageService.getEventIndicator(); + + return ResponseDto.onSuccess(eventIndicatorResponseDto); + } +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/controller/MainPageController.java b/src/main/java/com/softeer/backend/bo_domain/admin/controller/MainPageController.java new file mode 100644 index 00000000..07303d34 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/controller/MainPageController.java @@ -0,0 +1,23 @@ +package com.softeer.backend.bo_domain.admin.controller; + +import com.softeer.backend.bo_domain.admin.dto.main.MainPageResponseDto; +import com.softeer.backend.bo_domain.admin.service.MainPageService; +import com.softeer.backend.global.common.response.ResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/admin") +public class MainPageController { + private final MainPageService mainPageService; + + @GetMapping("/main") + public ResponseDto getMainPage() { + MainPageResponseDto mainPageResponseDto = mainPageService.getMainPage(); + + return ResponseDto.onSuccess(mainPageResponseDto); + } +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/controller/WinnerPageController.java b/src/main/java/com/softeer/backend/bo_domain/admin/controller/WinnerPageController.java new file mode 100644 index 00000000..e7d5a902 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/controller/WinnerPageController.java @@ -0,0 +1,52 @@ +package com.softeer.backend.bo_domain.admin.controller; + +import com.softeer.backend.bo_domain.admin.dto.winner.DrawWinnerListResponseDto; +import com.softeer.backend.bo_domain.admin.dto.winner.DrawWinnerUpdateRequestDto; +import com.softeer.backend.bo_domain.admin.dto.winner.FcfsWinnerListResponseDto; +import com.softeer.backend.bo_domain.admin.dto.winner.FcfsWinnerUpdateRequestDto; +import com.softeer.backend.bo_domain.admin.service.WinnerPageService; +import com.softeer.backend.global.common.response.ResponseDto; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/admin/winner") +public class WinnerPageController { + private final WinnerPageService winnerPageService; + + @GetMapping("/fcfs/{round}") + public ResponseDto getFcfsWinnerList(@PathVariable int round) { + + FcfsWinnerListResponseDto fcfsWinnerListResponseDto = winnerPageService.getFcfsWinnerList(round); + + return ResponseDto.onSuccess(fcfsWinnerListResponseDto); + } + + @GetMapping("/draw/{rank}") + public ResponseDto getDrawWinnerList(@PathVariable int rank) { + + DrawWinnerListResponseDto drawWinnerListResponseDto = winnerPageService.getDrawWinnerList(rank); + + return ResponseDto.onSuccess(drawWinnerListResponseDto); + } + + @PostMapping("/fcfs") + public ResponseDto updateFcfsWinnerNum(@Valid @RequestBody FcfsWinnerUpdateRequestDto fcfsWinnerUpdateRequestDto) { + + winnerPageService.updateFcfsWinnerNum(fcfsWinnerUpdateRequestDto); + + return ResponseDto.onSuccess(); + } + + @PostMapping("/draw") + public ResponseDto updateFcfsWinnerNum(@Valid @RequestBody DrawWinnerUpdateRequestDto drawWinnerUpdateRequestDto) { + + winnerPageService.updateDrawWinnerNum(drawWinnerUpdateRequestDto); + + return ResponseDto.onSuccess(); + } + + +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/domain/Admin.java b/src/main/java/com/softeer/backend/bo_domain/admin/domain/Admin.java new file mode 100644 index 00000000..f3209078 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/domain/Admin.java @@ -0,0 +1,28 @@ +package com.softeer.backend.bo_domain.admin.domain; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Builder +@Table(name = "admin") +public class Admin { + + @Id + @Column(name = "admin_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column(name = "admin_account", nullable = false, unique = true) + private String account; + + @Column(name = "password", nullable = false) + private String password; + +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/dto/event/DrawEventTimeRequestDto.java b/src/main/java/com/softeer/backend/bo_domain/admin/dto/event/DrawEventTimeRequestDto.java new file mode 100644 index 00000000..ad4d4d9a --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/dto/event/DrawEventTimeRequestDto.java @@ -0,0 +1,22 @@ +package com.softeer.backend.bo_domain.admin.dto.event; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.softeer.backend.bo_domain.admin.validator.annotation.ValidDrawTimeRange; +import lombok.*; + +import java.time.LocalDateTime; +import java.time.LocalTime; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PUBLIC) +@Builder +@Getter +@ValidDrawTimeRange +public class DrawEventTimeRequestDto { + + @JsonFormat(pattern = "HH:mm:ss") + private LocalTime startTime; + + @JsonFormat(pattern = "HH:mm:ss") + private LocalTime endTime; +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/dto/event/FcfsEventTimeRequestDto.java b/src/main/java/com/softeer/backend/bo_domain/admin/dto/event/FcfsEventTimeRequestDto.java new file mode 100644 index 00000000..f4a004bd --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/dto/event/FcfsEventTimeRequestDto.java @@ -0,0 +1,29 @@ +package com.softeer.backend.bo_domain.admin.dto.event; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.softeer.backend.bo_domain.admin.validator.annotation.ValidFcfsDateRange; +import com.softeer.backend.bo_domain.admin.validator.annotation.ValidFcfsTimeRange; +import lombok.*; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PUBLIC) +@Builder +@Getter +@ValidFcfsDateRange +@ValidFcfsTimeRange +public class FcfsEventTimeRequestDto { + + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate startDate; + + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate endDate; + + @JsonFormat(pattern = "HH:mm:ss") + private LocalTime startTime; + +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/dto/indicator/EventIndicatorResponseDto.java b/src/main/java/com/softeer/backend/bo_domain/admin/dto/indicator/EventIndicatorResponseDto.java new file mode 100644 index 00000000..796f6e9e --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/dto/indicator/EventIndicatorResponseDto.java @@ -0,0 +1,89 @@ +package com.softeer.backend.bo_domain.admin.dto.indicator; + + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.softeer.backend.bo_domain.admin.serializer.PercentageSerializer; +import com.softeer.backend.bo_domain.admin.serializer.PhoneNumberSerializer; +import com.softeer.backend.bo_domain.eventparticipation.domain.EventParticipation; +import lombok.*; + +import java.time.LocalDate; +import java.util.List; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PUBLIC) +@Builder +@Getter +public class EventIndicatorResponseDto { + + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate startDate; + + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate endDate; + + private int totalVisitorCount; + + private int totalFcfsParticipantCount; + + private int totalDrawParticipantCount; + + @JsonSerialize(using = PercentageSerializer.class) + private double fcfsParticipantRate; + + @JsonSerialize(using = PercentageSerializer.class) + private double drawParticipantRate; + + private List visitorNumList; + + @Getter + @AllArgsConstructor + @Builder + public static class VisitorNum { + + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate visitDate; + + private int visitorNum; + } + + public static EventIndicatorResponseDto of(List eventParticipationList) { + LocalDate startDate = eventParticipationList.get(0).getEventDate(); + LocalDate endDate = eventParticipationList.get(eventParticipationList.size() - 1).getEventDate(); + + int totalVisitorCount = eventParticipationList.stream() + .mapToInt(EventParticipation::getVisitorCount) + .sum(); + + int totalFcfsParticipantCount = eventParticipationList.stream() + .mapToInt(EventParticipation::getFcfsParticipantCount) + .sum(); + + int totalDrawParticipantCount = eventParticipationList.stream() + .mapToInt(EventParticipation::getDrawParticipantCount) + .sum(); + + double fcfsParticipantRate = (double) totalFcfsParticipantCount / (double) totalVisitorCount; + double drawParticipantRate = (double) totalDrawParticipantCount / (double) totalVisitorCount; + + List visitorNumList = eventParticipationList.stream() + .map((eventParticipation) -> + VisitorNum.builder() + .visitDate(eventParticipation.getEventDate()) + .visitorNum(eventParticipation.getVisitorCount()) + .build()) + .toList(); + + return EventIndicatorResponseDto.builder() + .startDate(startDate) + .endDate(endDate) + .totalVisitorCount(totalVisitorCount) + .totalFcfsParticipantCount(totalFcfsParticipantCount) + .totalDrawParticipantCount(totalDrawParticipantCount) + .fcfsParticipantRate(fcfsParticipantRate) + .drawParticipantRate(drawParticipantRate) + .visitorNumList(visitorNumList) + .build(); + } +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/dto/login/AdminLoginRequestDto.java b/src/main/java/com/softeer/backend/bo_domain/admin/dto/login/AdminLoginRequestDto.java new file mode 100644 index 00000000..0f87a9f6 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/dto/login/AdminLoginRequestDto.java @@ -0,0 +1,20 @@ +package com.softeer.backend.bo_domain.admin.dto.login; + +import com.softeer.backend.global.common.constant.ValidationConstant; +import jakarta.validation.constraints.Pattern; +import lombok.*; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PUBLIC) +@Builder +@Getter +public class AdminLoginRequestDto { + + @Pattern(regexp = ValidationConstant.ADMIN_ACCOUNT_REGEX, + message = ValidationConstant.ADMIN_ACCOUNT_MSG) + private String account; + + @Pattern(regexp = ValidationConstant.ADMIN_PASSWORD_REGEX, + message = ValidationConstant.ADMIN_PASSWORD_MSG) + private String password; +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/dto/main/MainPageResponseDto.java b/src/main/java/com/softeer/backend/bo_domain/admin/dto/main/MainPageResponseDto.java new file mode 100644 index 00000000..5f6874c5 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/dto/main/MainPageResponseDto.java @@ -0,0 +1,123 @@ +package com.softeer.backend.bo_domain.admin.dto.main; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.softeer.backend.bo_domain.admin.serializer.PercentageSerializer; +import com.softeer.backend.fo_domain.draw.domain.DrawSetting; +import com.softeer.backend.fo_domain.fcfs.domain.FcfsSetting; +import lombok.*; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.Arrays; +import java.util.List; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PUBLIC) +@Builder +@Getter +public class MainPageResponseDto { + public static final int EXPECTED_PARTICIPANT_COUNT = 10000; + + private List fcfsEventList; + + private DrawEvent drawEvent; + + @Getter + @AllArgsConstructor + @Builder + public static class FcfsEvent { + + private int round; + + @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss") + private LocalDateTime startTime; + + @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss") + private LocalDateTime endTime; + + private int winnerNum; + } + + @Getter + @AllArgsConstructor + @Builder + public static class DrawEvent { + + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate startDate; + + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate endDate; + + @JsonFormat(pattern = "hh:mm:ss") + private LocalTime startTime; + + @JsonFormat(pattern = "hh:mm:ss") + private LocalTime endTime; + + private List drawInfoList; + } + + @Getter + @AllArgsConstructor + @Builder + public static class DrawInfo { + + private int rank; + + private int winnerNum; + + @JsonSerialize(using = PercentageSerializer.class) + private double probability; + } + + public static MainPageResponseDto of(List fcfsSettingList, List drawSettingList) { + List fcfsEventList = fcfsSettingList.stream() + .map((fcfsSetting) -> + FcfsEvent.builder() + .round(fcfsSetting.getRound()) + .startTime(fcfsSetting.getStartTime()) + .endTime(fcfsSetting.getEndTime()) + .winnerNum(fcfsSetting.getWinnerNum()) + .build()) + .toList(); + + DrawSetting drawSetting = drawSettingList.get(0); + DrawInfo drawInfoFirst = DrawInfo.builder() + .rank(1) + .winnerNum(drawSetting.getWinnerNum1()) + .probability(calculateWinningProbability(drawSetting.getWinnerNum1())) + .build(); + DrawInfo drawInfoSecond = DrawInfo.builder() + .rank(2) + .winnerNum(drawSetting.getWinnerNum2()) + .probability(calculateWinningProbability(drawSetting.getWinnerNum2())) + .build(); + DrawInfo drawInfoThird = DrawInfo.builder() + .rank(3) + .winnerNum(drawSetting.getWinnerNum3()) + .probability(calculateWinningProbability(drawSetting.getWinnerNum3())) + .build(); + + List drawInfoList = Arrays.asList(drawInfoFirst, drawInfoSecond, drawInfoThird); + DrawEvent drawEvent = DrawEvent.builder() + .startDate(drawSetting.getStartDate()) + .endDate(drawSetting.getEndDate()) + .startTime(drawSetting.getStartTime()) + .endTime(drawSetting.getEndTime()) + .drawInfoList(drawInfoList) + .build(); + + return MainPageResponseDto.builder() + .fcfsEventList(fcfsEventList) + .drawEvent(drawEvent) + .build(); + + } + + private static double calculateWinningProbability(int winnerNum) { + return (double) winnerNum / (double) EXPECTED_PARTICIPANT_COUNT; + } +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/DrawWinnerListResponseDto.java b/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/DrawWinnerListResponseDto.java new file mode 100644 index 00000000..67041a01 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/DrawWinnerListResponseDto.java @@ -0,0 +1,48 @@ +package com.softeer.backend.bo_domain.admin.dto.winner; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.softeer.backend.bo_domain.admin.serializer.PhoneNumberSerializer; +import com.softeer.backend.fo_domain.draw.domain.Draw; +import com.softeer.backend.fo_domain.fcfs.domain.Fcfs; +import lombok.*; + +import java.util.Comparator; +import java.util.List; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PUBLIC) +@Builder +@Getter +public class DrawWinnerListResponseDto { + + int rank; + + private List drawWinnerList; + + @Getter + @AllArgsConstructor + @Builder + public static class DrawWinner { + + private String name; + + @JsonSerialize(using = PhoneNumberSerializer.class) + private String phoneNumber; + } + + public static DrawWinnerListResponseDto of(List drawList, int rank) { + List drawWinnerList = drawList.stream() + .map((draw) -> DrawWinner.builder() + .name(draw.getUser().getName()) + .phoneNumber(draw.getUser().getPhoneNumber()) + .build()) + .sorted(Comparator.comparing(DrawWinnerListResponseDto.DrawWinner::getName)) + .toList(); + + return DrawWinnerListResponseDto.builder() + .rank(rank) + .drawWinnerList(drawWinnerList) + .build(); + } + +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/DrawWinnerUpdateRequestDto.java b/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/DrawWinnerUpdateRequestDto.java new file mode 100644 index 00000000..d141dff8 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/DrawWinnerUpdateRequestDto.java @@ -0,0 +1,16 @@ +package com.softeer.backend.bo_domain.admin.dto.winner; + +import lombok.*; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PUBLIC) +@Builder +@Getter +public class DrawWinnerUpdateRequestDto { + + private int firstWinnerNum; + + private int secondWinnerNum; + + private int thirdWinnerNum; +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/FcfsWinnerListResponseDto.java b/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/FcfsWinnerListResponseDto.java new file mode 100644 index 00000000..76a60d8b --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/FcfsWinnerListResponseDto.java @@ -0,0 +1,47 @@ +package com.softeer.backend.bo_domain.admin.dto.winner; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.softeer.backend.bo_domain.admin.serializer.PhoneNumberSerializer; +import com.softeer.backend.fo_domain.fcfs.domain.Fcfs; +import lombok.*; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PUBLIC) +@Builder +@Getter +public class FcfsWinnerListResponseDto { + + int round; + + private List fcfsWinnerList; + + @Getter + @AllArgsConstructor + @Builder + public static class FcfsWinner { + + private String name; + + @JsonSerialize(using = PhoneNumberSerializer.class) + private String phoneNumber; + } + + public static FcfsWinnerListResponseDto of(List fcfsList, int round) { + List fcfsWinnerList = fcfsList.stream() + .map((fcfs) -> FcfsWinner.builder() + .name(fcfs.getUser().getName()) + .phoneNumber(fcfs.getUser().getPhoneNumber()) + .build()) + .sorted(Comparator.comparing(FcfsWinner::getName)) + .toList(); + + return FcfsWinnerListResponseDto.builder() + .round(round) + .fcfsWinnerList(fcfsWinnerList) + .build(); + } +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/FcfsWinnerUpdateRequestDto.java b/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/FcfsWinnerUpdateRequestDto.java new file mode 100644 index 00000000..6553eda3 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/FcfsWinnerUpdateRequestDto.java @@ -0,0 +1,14 @@ +package com.softeer.backend.bo_domain.admin.dto.winner; + +import lombok.*; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PUBLIC) +@Builder +@Getter +public class FcfsWinnerUpdateRequestDto { + + private int round; + + private int fcfsWinnerNum; +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/exception/AdminException.java b/src/main/java/com/softeer/backend/bo_domain/admin/exception/AdminException.java new file mode 100644 index 00000000..5bf4ad12 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/exception/AdminException.java @@ -0,0 +1,11 @@ +package com.softeer.backend.bo_domain.admin.exception; + +import com.softeer.backend.global.common.code.BaseErrorCode; +import com.softeer.backend.global.common.exception.GeneralException; + +public class AdminException extends GeneralException { + + public AdminException(BaseErrorCode code) { + super(code); + } +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/repository/AdminRepository.java b/src/main/java/com/softeer/backend/bo_domain/admin/repository/AdminRepository.java new file mode 100644 index 00000000..b0bfb7d8 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/repository/AdminRepository.java @@ -0,0 +1,12 @@ +package com.softeer.backend.bo_domain.admin.repository; + +import com.softeer.backend.bo_domain.admin.domain.Admin; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface AdminRepository extends JpaRepository { + Optional findByAccount(String account); +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/serializer/PercentageSerializer.java b/src/main/java/com/softeer/backend/bo_domain/admin/serializer/PercentageSerializer.java new file mode 100644 index 00000000..92cba3ad --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/serializer/PercentageSerializer.java @@ -0,0 +1,19 @@ +package com.softeer.backend.bo_domain.admin.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +public class PercentageSerializer extends JsonSerializer { + + @Override + public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + if (value != null) { + // 백분율로 변환하고 % 기호를 붙입니다. + String formatted = String.format("%.2f%%", value * 100); + gen.writeString(formatted); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/serializer/PhoneNumberSerializer.java b/src/main/java/com/softeer/backend/bo_domain/admin/serializer/PhoneNumberSerializer.java new file mode 100644 index 00000000..9ca88b5a --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/serializer/PhoneNumberSerializer.java @@ -0,0 +1,17 @@ +package com.softeer.backend.bo_domain.admin.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +public class PhoneNumberSerializer extends JsonSerializer { + + @Override + public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + + String formatted = value.replaceAll("(\\d{3})(\\d{3})(\\d+)", "$1-$2-$3"); + gen.writeString(formatted); + } +} \ No newline at end of file diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/service/AdminLoginService.java b/src/main/java/com/softeer/backend/bo_domain/admin/service/AdminLoginService.java new file mode 100644 index 00000000..fde81f89 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/service/AdminLoginService.java @@ -0,0 +1,57 @@ +package com.softeer.backend.bo_domain.admin.service; + +import com.softeer.backend.bo_domain.admin.domain.Admin; +import com.softeer.backend.bo_domain.admin.dto.login.AdminLoginRequestDto; +import com.softeer.backend.bo_domain.admin.exception.AdminException; +import com.softeer.backend.bo_domain.admin.repository.AdminRepository; +import com.softeer.backend.bo_domain.admin.util.PasswordEncoder; +import com.softeer.backend.global.common.code.status.ErrorStatus; +import com.softeer.backend.global.common.constant.RoleType; +import com.softeer.backend.global.common.dto.JwtClaimsDto; +import com.softeer.backend.global.common.dto.JwtTokenResponseDto; +import com.softeer.backend.global.util.JwtUtil; +import com.softeer.backend.global.util.StringRedisUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Service +@RequiredArgsConstructor +public class AdminLoginService { + + private final AdminRepository adminRepository; + private final JwtUtil jwtUtil; + private final StringRedisUtil stringRedisUtil; + private final PasswordEncoder passwordEncoder; + + @Transactional(readOnly = true) + public JwtTokenResponseDto handleLogin(AdminLoginRequestDto adminLoginRequestDto) { + + Admin admin = adminRepository.findByAccount(adminLoginRequestDto.getAccount()) + .orElseThrow(() -> { + log.error("Admin not found."); + return new AdminException(ErrorStatus._NOT_FOUND); + }); + + if (!passwordEncoder.matches(adminLoginRequestDto.getPassword(), admin.getPassword())) { + log.error("Admin password not match."); + throw new AdminException(ErrorStatus._NOT_FOUND); + } + + return jwtUtil.createServiceToken(JwtClaimsDto.builder() + .id(admin.getId()) + .roleType(RoleType.ROLE_ADMIN) + .build()); + + } + + public void handleLogout(int adminId) { + + stringRedisUtil.deleteRefreshToken(JwtClaimsDto.builder() + .id(adminId) + .roleType(RoleType.ROLE_ADMIN) + .build()); + } +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/service/EventPageService.java b/src/main/java/com/softeer/backend/bo_domain/admin/service/EventPageService.java new file mode 100644 index 00000000..1f32c029 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/service/EventPageService.java @@ -0,0 +1,78 @@ +package com.softeer.backend.bo_domain.admin.service; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.softeer.backend.bo_domain.admin.dto.event.DrawEventTimeRequestDto; +import com.softeer.backend.bo_domain.admin.dto.event.FcfsEventTimeRequestDto; +import com.softeer.backend.fo_domain.draw.domain.DrawSetting; +import com.softeer.backend.fo_domain.draw.repository.DrawSettingRepository; +import com.softeer.backend.fo_domain.fcfs.domain.FcfsSetting; +import com.softeer.backend.fo_domain.fcfs.repository.FcfsSettingRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.temporal.TemporalAdjusters; +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional +public class EventPageService { + + private FcfsSettingRepository fcfsSettingRepository; + + private DrawSettingRepository drawSettingRepository; + + public void updateFcfsEventTime(FcfsEventTimeRequestDto fcfsEventTimeRequestDto) { + + List fcfsSettingList = fcfsSettingRepository.findAll(Sort.by(Sort.Order.asc("id"))); + + LocalDate startDate = fcfsEventTimeRequestDto.getStartDate(); + LocalDate endDate = fcfsEventTimeRequestDto.getEndDate(); + LocalTime startTime = fcfsEventTimeRequestDto.getStartTime(); + + updateFcfsSetting(fcfsSettingList.get(0), startDate, startTime); + updateFcfsSetting(fcfsSettingList.get(1), endDate, startTime); + + LocalDate nextWeekStartDate = startDate.plusWeeks(1); + LocalDate nextWeekEndDate = endDate.plusWeeks(1); + + updateFcfsSetting(fcfsSettingList.get(2), nextWeekStartDate, startTime); + updateFcfsSetting(fcfsSettingList.get(3), nextWeekEndDate, startTime); + + DrawSetting drawSetting = drawSettingRepository.findAll().get(0); + updateDrawSetting(drawSetting, startDate, endDate); + + } + + private void updateFcfsSetting(FcfsSetting setting, LocalDate date, LocalTime time) { + + LocalDateTime newStartTime = LocalDateTime.of(date, time); + LocalDateTime newEndTime = newStartTime.plusHours(2); + + setting.setStartTime(newStartTime); + setting.setEndTime(newEndTime); + } + + private void updateDrawSetting(DrawSetting drawSetting, LocalDate startDate, LocalDate endDate) { + LocalDate startDateOfDraw = startDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY)); + + LocalDate endDateOfPreviousWeek = endDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.SATURDAY)); + LocalDate endDateOfDraw = endDateOfPreviousWeek.with(TemporalAdjusters.next(DayOfWeek.SATURDAY)); + + drawSetting.setStartDate(startDateOfDraw); + drawSetting.setEndDate(endDateOfDraw); + } + + public void updateDrawEventTime(DrawEventTimeRequestDto drawEventTimeRequestDto) { + DrawSetting drawSetting = drawSettingRepository.findAll().get(0); + + drawSetting.setStartTime(drawEventTimeRequestDto.getStartTime()); + drawSetting.setEndTime(drawEventTimeRequestDto.getEndTime()); + } +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/service/IndicatorPageService.java b/src/main/java/com/softeer/backend/bo_domain/admin/service/IndicatorPageService.java new file mode 100644 index 00000000..d65d90cb --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/service/IndicatorPageService.java @@ -0,0 +1,32 @@ +package com.softeer.backend.bo_domain.admin.service; + +import com.softeer.backend.bo_domain.admin.dto.indicator.EventIndicatorResponseDto; +import com.softeer.backend.bo_domain.eventparticipation.domain.EventParticipation; +import com.softeer.backend.bo_domain.eventparticipation.repository.EventParticipationRepository; +import com.softeer.backend.fo_domain.draw.domain.DrawSetting; +import com.softeer.backend.fo_domain.draw.repository.DrawSettingRepository; +import kotlinx.serialization.Required; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class IndicatorPageService { + + private final EventParticipationRepository eventParticipationRepository; + private final DrawSettingRepository drawSettingRepository; + + public EventIndicatorResponseDto getEventIndicator() { + + DrawSetting drawSetting = drawSettingRepository.findAll().get(0); + + List eventParticipationList = eventParticipationRepository.findAllByEventDateBetween( + drawSetting.getStartDate(), drawSetting.getEndDate() + ); + + return EventIndicatorResponseDto.of(eventParticipationList); + } + +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/service/MainPageService.java b/src/main/java/com/softeer/backend/bo_domain/admin/service/MainPageService.java new file mode 100644 index 00000000..5ddccb36 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/service/MainPageService.java @@ -0,0 +1,29 @@ +package com.softeer.backend.bo_domain.admin.service; + +import com.softeer.backend.bo_domain.admin.dto.main.MainPageResponseDto; +import com.softeer.backend.fo_domain.draw.domain.DrawSetting; +import com.softeer.backend.fo_domain.draw.repository.DrawSettingRepository; +import com.softeer.backend.fo_domain.fcfs.domain.FcfsSetting; +import com.softeer.backend.fo_domain.fcfs.repository.FcfsSettingRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class MainPageService { + + private final FcfsSettingRepository fcfsSettingRepository; + private final DrawSettingRepository drawSettingRepository; + + @Transactional(readOnly = true) + public MainPageResponseDto getMainPage() { + List fcfsSettingList = fcfsSettingRepository.findAll(Sort.by(Sort.Order.asc("round"))); + List drawSetting = drawSettingRepository.findAll(); + + return MainPageResponseDto.of(fcfsSettingList, drawSetting); + } +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/service/WinnerPageService.java b/src/main/java/com/softeer/backend/bo_domain/admin/service/WinnerPageService.java new file mode 100644 index 00000000..2d911479 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/service/WinnerPageService.java @@ -0,0 +1,69 @@ +package com.softeer.backend.bo_domain.admin.service; + +import com.softeer.backend.bo_domain.admin.dto.winner.DrawWinnerListResponseDto; +import com.softeer.backend.bo_domain.admin.dto.winner.DrawWinnerUpdateRequestDto; +import com.softeer.backend.bo_domain.admin.dto.winner.FcfsWinnerListResponseDto; +import com.softeer.backend.bo_domain.admin.dto.winner.FcfsWinnerUpdateRequestDto; +import com.softeer.backend.bo_domain.admin.exception.AdminException; +import com.softeer.backend.fo_domain.draw.domain.Draw; +import com.softeer.backend.fo_domain.draw.domain.DrawSetting; +import com.softeer.backend.fo_domain.draw.repository.DrawRepository; +import com.softeer.backend.fo_domain.draw.repository.DrawSettingRepository; +import com.softeer.backend.fo_domain.fcfs.domain.Fcfs; +import com.softeer.backend.fo_domain.fcfs.domain.FcfsSetting; +import com.softeer.backend.fo_domain.fcfs.repository.FcfsRepository; +import com.softeer.backend.fo_domain.fcfs.repository.FcfsSettingRepository; +import com.softeer.backend.fo_domain.user.repository.UserRepository; +import com.softeer.backend.global.common.code.status.ErrorStatus; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Slf4j +@Service +@RequiredArgsConstructor +public class WinnerPageService { + + private final FcfsRepository fcfsRepository; + private final DrawRepository drawRepository; + private final FcfsSettingRepository fcfsSettingRepository; + private final DrawSettingRepository drawSettingRepository; + + + @Transactional(readOnly = true) + public FcfsWinnerListResponseDto getFcfsWinnerList(int round) { + List fcfsList = fcfsRepository.findFcfsWithUser(round); + + return FcfsWinnerListResponseDto.of(fcfsList, round); + } + + @Transactional(readOnly = true) + public DrawWinnerListResponseDto getDrawWinnerList(int rank) { + List drawList = drawRepository.findDrawWithUser(rank); + + return DrawWinnerListResponseDto.of(drawList, rank); + } + + @Transactional + public void updateFcfsWinnerNum(FcfsWinnerUpdateRequestDto fcfsWinnerUpdateRequestDto) { + FcfsSetting fcfsSetting = fcfsSettingRepository.findByRound(fcfsWinnerUpdateRequestDto.getRound()) + .orElseThrow(() -> { + log.error("fcfsSetting not found"); + return new AdminException(ErrorStatus._NOT_FOUND); + }); + + fcfsSetting.setWinnerNum(fcfsWinnerUpdateRequestDto.getFcfsWinnerNum()); + } + + @Transactional + public void updateDrawWinnerNum(DrawWinnerUpdateRequestDto drawWinnerUpdateRequestDto) { + DrawSetting drawSetting = drawSettingRepository.findAll().get(0); + + drawSetting.setWinnerNum1(drawWinnerUpdateRequestDto.getFirstWinnerNum()); + drawSetting.setWinnerNum2(drawWinnerUpdateRequestDto.getSecondWinnerNum()); + drawSetting.setWinnerNum3(drawWinnerUpdateRequestDto.getThirdWinnerNum()); + } +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/util/PasswordEncoder.java b/src/main/java/com/softeer/backend/bo_domain/admin/util/PasswordEncoder.java new file mode 100644 index 00000000..ad37d213 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/util/PasswordEncoder.java @@ -0,0 +1,18 @@ +package com.softeer.backend.bo_domain.admin.util; + +import org.mindrot.jbcrypt.BCrypt; +import org.springframework.stereotype.Component; + +@Component +public class PasswordEncoder { + + // 비밀번호를 해시화 + public String encode(String rawPassword) { + return BCrypt.hashpw(rawPassword, BCrypt.gensalt()); + } + + // 비밀번호 비교 (평문 vs 해시) + public boolean matches(String rawPassword, String encodedPassword) { + return BCrypt.checkpw(rawPassword, encodedPassword); + } +} \ No newline at end of file diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/validator/DrawTimeRangeValidator.java b/src/main/java/com/softeer/backend/bo_domain/admin/validator/DrawTimeRangeValidator.java new file mode 100644 index 00000000..697ac6bc --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/validator/DrawTimeRangeValidator.java @@ -0,0 +1,39 @@ +package com.softeer.backend.bo_domain.admin.validator; + +import com.softeer.backend.bo_domain.admin.dto.event.DrawEventTimeRequestDto; +import com.softeer.backend.bo_domain.admin.validator.annotation.ValidDrawTimeRange; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import java.time.LocalTime; + +public class DrawTimeRangeValidator implements ConstraintValidator { + + @Override + public void initialize(ValidDrawTimeRange constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(DrawEventTimeRequestDto value, ConstraintValidatorContext context) { + if (value.getStartTime() == null || value.getEndTime() == null) { + return true; + } + + LocalTime startTime = value.getStartTime(); + LocalTime endTime = value.getEndTime(); + + // 시작 시간 검증: 09:00:00 이후 + if (startTime.isBefore(LocalTime.of(9, 0))) { + return false; + } + + // 종료 시간 검증: 23:59:59 이전 + if (endTime.isAfter(LocalTime.of(23, 59, 59))) { + return false; + } + + // 시작 시간이 종료 시간보다 이전인지 확인 + return !startTime.isAfter(endTime); + } +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/validator/FcfsDateRangeValidator.java b/src/main/java/com/softeer/backend/bo_domain/admin/validator/FcfsDateRangeValidator.java new file mode 100644 index 00000000..5ba2208e --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/validator/FcfsDateRangeValidator.java @@ -0,0 +1,41 @@ +package com.softeer.backend.bo_domain.admin.validator; + +import com.softeer.backend.bo_domain.admin.dto.event.FcfsEventTimeRequestDto; +import com.softeer.backend.bo_domain.admin.validator.annotation.ValidFcfsDateRange; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.temporal.TemporalAdjusters; +import java.time.temporal.WeekFields; +import java.util.Locale; + +public class FcfsDateRangeValidator implements ConstraintValidator { + + @Override + public void initialize(ValidFcfsDateRange constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(FcfsEventTimeRequestDto value, ConstraintValidatorContext context) { + if (value.getStartDate() == null || value.getEndDate() == null) { + return true; + } + + LocalDate startDate = value.getStartDate(); + LocalDate endDate = value.getEndDate(); + + LocalDate startDateWeekStart = startDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY)); + LocalDate endDateWeekStart = endDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY)); + + boolean isSameWeek = startDateWeekStart.equals(endDateWeekStart); + + // 시작 날짜가 종료 날짜보다 이전인지 확인 + boolean isStartBeforeEnd = !startDate.isAfter(endDate); + + // 두 검증 조건을 모두 만족하는지 확인 + return isSameWeek && isStartBeforeEnd; + } +} \ No newline at end of file diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/validator/FcfsTimeRangeValidator.java b/src/main/java/com/softeer/backend/bo_domain/admin/validator/FcfsTimeRangeValidator.java new file mode 100644 index 00000000..fa06de7b --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/validator/FcfsTimeRangeValidator.java @@ -0,0 +1,34 @@ +package com.softeer.backend.bo_domain.admin.validator; + +import com.softeer.backend.bo_domain.admin.dto.event.FcfsEventTimeRequestDto; +import com.softeer.backend.bo_domain.admin.validator.annotation.ValidFcfsTimeRange; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import java.time.LocalTime; + +public class FcfsTimeRangeValidator implements ConstraintValidator { + + @Override + public void initialize(ValidFcfsTimeRange constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(FcfsEventTimeRequestDto value, ConstraintValidatorContext context) { + if (value.getStartTime() == null) { + return true; + } + + LocalTime startTime = value.getStartTime(); + + // 시작 시간이 오전 9시 이후인지 검증 + boolean isStartTimeValid = !startTime.isBefore(LocalTime.of(9, 0)); + + // 시작 시간이 오후 6시 이전인지 검증 + boolean isEndTimeValid = !startTime.isAfter(LocalTime.of(18, 0)); + + // 모든 검증 조건이 만족되는지 확인 + return isStartTimeValid && isEndTimeValid; + } +} \ No newline at end of file diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/validator/annotation/ValidDrawTimeRange.java b/src/main/java/com/softeer/backend/bo_domain/admin/validator/annotation/ValidDrawTimeRange.java new file mode 100644 index 00000000..222715c3 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/validator/annotation/ValidDrawTimeRange.java @@ -0,0 +1,22 @@ +package com.softeer.backend.bo_domain.admin.validator.annotation; + +import com.softeer.backend.bo_domain.admin.validator.DrawTimeRangeValidator; +import com.softeer.backend.bo_domain.admin.validator.FcfsDateRangeValidator; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Constraint(validatedBy = DrawTimeRangeValidator.class) +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ValidDrawTimeRange { + String message() default "시작시간은 09:00 이후, 종료 시간은 11:59:59 이전이어야 합니다."; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/validator/annotation/ValidFcfsDateRange.java b/src/main/java/com/softeer/backend/bo_domain/admin/validator/annotation/ValidFcfsDateRange.java new file mode 100644 index 00000000..228e6659 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/validator/annotation/ValidFcfsDateRange.java @@ -0,0 +1,21 @@ +package com.softeer.backend.bo_domain.admin.validator.annotation; + +import com.softeer.backend.bo_domain.admin.validator.FcfsDateRangeValidator; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Constraint(validatedBy = FcfsDateRangeValidator.class) +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ValidFcfsDateRange { + String message() default "선착순 날짜는 같은 주에 있어야 합니다."; + + Class[] groups() default {}; + + Class[] payload() default {}; +} \ No newline at end of file diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/validator/annotation/ValidFcfsTimeRange.java b/src/main/java/com/softeer/backend/bo_domain/admin/validator/annotation/ValidFcfsTimeRange.java new file mode 100644 index 00000000..6e37271c --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/validator/annotation/ValidFcfsTimeRange.java @@ -0,0 +1,21 @@ +package com.softeer.backend.bo_domain.admin.validator.annotation; + +import com.softeer.backend.bo_domain.admin.validator.FcfsTimeRangeValidator; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Constraint(validatedBy = FcfsTimeRangeValidator.class) +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ValidFcfsTimeRange { + String message() default "시작 시간값은 09:00:00 ~ 18:00:00 범위에 속해야 합니다."; + + Class[] groups() default {}; + + Class[] payload() default {}; +} \ No newline at end of file diff --git a/src/main/java/com/softeer/backend/bo_domain/eventparticipation/domain/EventParticipation.java b/src/main/java/com/softeer/backend/bo_domain/eventparticipation/domain/EventParticipation.java index 7c096db0..5ae8962e 100644 --- a/src/main/java/com/softeer/backend/bo_domain/eventparticipation/domain/EventParticipation.java +++ b/src/main/java/com/softeer/backend/bo_domain/eventparticipation/domain/EventParticipation.java @@ -3,6 +3,8 @@ import jakarta.persistence.*; import lombok.*; +import java.time.LocalDate; + @Entity @NoArgsConstructor @AllArgsConstructor @@ -18,7 +20,7 @@ public class EventParticipation { @Column(name = "total_visitors_count", nullable = false) @Builder.Default - private int totalVisitorsCount = 0; + private int visitorCount = 0; @Column(name = "fcfs_participant_count", nullable = false) @Builder.Default @@ -28,8 +30,11 @@ public class EventParticipation { @Builder.Default private int drawParticipantCount = 0; + @Column(name = "event_date", nullable = false) + private LocalDate eventDate; + public void addTotalVisitorsCount(int totalVisitorsCount) { - this.totalVisitorsCount += totalVisitorsCount; + this.visitorCount += totalVisitorsCount; } public void addFcfsParticipantCount(int fcfsParticipantCount) { diff --git a/src/main/java/com/softeer/backend/bo_domain/eventparticipation/repository/EventParticipationRepository.java b/src/main/java/com/softeer/backend/bo_domain/eventparticipation/repository/EventParticipationRepository.java index 8219012d..6ce7060a 100644 --- a/src/main/java/com/softeer/backend/bo_domain/eventparticipation/repository/EventParticipationRepository.java +++ b/src/main/java/com/softeer/backend/bo_domain/eventparticipation/repository/EventParticipationRepository.java @@ -3,11 +3,17 @@ import com.softeer.backend.bo_domain.eventparticipation.domain.EventParticipation; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import java.time.LocalDate; import java.util.List; public interface EventParticipationRepository extends JpaRepository { + @Query("SELECT e FROM EventParticipation e WHERE e.eventDate BETWEEN :startDate AND :endDate") + List findAllByEventDateBetween(@Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate); + default EventParticipation findSingleEventParticipation() { List results = findAll(); if (results.isEmpty()) { diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java b/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java index f4333322..0f4652aa 100644 --- a/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java +++ b/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java @@ -10,6 +10,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -25,6 +26,7 @@ public class CommentService { *

* 커서 기반 무한 스크롤 기능을 사용하여 다음 cursor 값을 받아 해당 값보다 작으면서 정해진 개수 만큼의 기대평을 반환한다. */ + @Transactional(readOnly = true) public CommentsResponseDto getComments(Integer userId, Integer cursor) { PageRequest pageRequest = PageRequest.of(0, SCROLL_SIZE + 1); @@ -38,6 +40,7 @@ public CommentsResponseDto getComments(Integer userId, Integer cursor) { /** * 기대평을 저장하는 메서드 */ + @Transactional public void saveComment(Integer userId, int commentNum) { // 로그인 한 유저가 기대평을 등록했다면 User entity의 id값을 기반으로 닉네임을 설정한다. diff --git a/src/main/java/com/softeer/backend/fo_domain/draw/domain/Draw.java b/src/main/java/com/softeer/backend/fo_domain/draw/domain/Draw.java index 196864dd..b346b641 100644 --- a/src/main/java/com/softeer/backend/fo_domain/draw/domain/Draw.java +++ b/src/main/java/com/softeer/backend/fo_domain/draw/domain/Draw.java @@ -8,6 +8,7 @@ import lombok.NoArgsConstructor; import java.sql.Date; +import java.time.LocalDateTime; @Getter @Entity @@ -29,5 +30,5 @@ public class Draw { private Integer rank; @Column(name = "winning_date") - private Date winningDate; + private LocalDateTime winningDate; } diff --git a/src/main/java/com/softeer/backend/fo_domain/draw/domain/DrawSetting.java b/src/main/java/com/softeer/backend/fo_domain/draw/domain/DrawSetting.java index e9eaf865..d81a6ac0 100644 --- a/src/main/java/com/softeer/backend/fo_domain/draw/domain/DrawSetting.java +++ b/src/main/java/com/softeer/backend/fo_domain/draw/domain/DrawSetting.java @@ -3,12 +3,17 @@ import jakarta.persistence.*; import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.Setter; import org.springframework.format.annotation.DateTimeFormat; import java.sql.Date; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; @Entity @Getter +@Setter @Table(name = "draw_setting") @RequiredArgsConstructor public class DrawSetting { @@ -17,13 +22,17 @@ public class DrawSetting { @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer draw_setting_id; + @Column(name = "start_date") + private LocalDate startDate; + + @Column(name = "end_date") + private LocalDate endDate; + @Column(name = "start_time") - @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private Date startTime; + private LocalTime startTime; @Column(name = "end_time") - @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private Date endTime; + private LocalTime endTime; @Column(name = "winner_num_1") private Integer winnerNum1; diff --git a/src/main/java/com/softeer/backend/fo_domain/draw/repository/DrawRepository.java b/src/main/java/com/softeer/backend/fo_domain/draw/repository/DrawRepository.java index 155f760e..0ee77114 100644 --- a/src/main/java/com/softeer/backend/fo_domain/draw/repository/DrawRepository.java +++ b/src/main/java/com/softeer/backend/fo_domain/draw/repository/DrawRepository.java @@ -2,8 +2,15 @@ import com.softeer.backend.fo_domain.draw.domain.Draw; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface DrawRepository extends JpaRepository { + + @Query("SELECT d FROM Draw d JOIN FETCH d.user WHERE d.rank = :rank") + List findDrawWithUser(@Param("rank") int rank); } diff --git a/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawSettingManager.java b/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawSettingManager.java index 0077e1ca..dd3f4982 100644 --- a/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawSettingManager.java +++ b/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawSettingManager.java @@ -9,11 +9,15 @@ import jakarta.annotation.PostConstruct; import lombok.Getter; import lombok.RequiredArgsConstructor; +import net.bytebuddy.asm.Advice; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.support.CronTrigger; import org.springframework.stereotype.Component; import java.sql.Date; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; @Getter @Component @@ -23,8 +27,10 @@ public class DrawSettingManager { private final ThreadPoolTaskScheduler taskScheduler; private final EventLockRedisUtil eventLockRedisUtil; - private Date startTime; - private Date endTime; + private LocalDate startDate; + private LocalDate endDate; + private LocalTime startTime; + private LocalTime endTime; private int winnerNum1; private int winnerNum2; private int winnerNum3; @@ -37,6 +43,8 @@ public void initializeDrawSettingManager() { DrawSetting drawSetting = drawSettingRepository.findById(1) .orElseThrow(() -> new DrawException(ErrorStatus._NOT_FOUND)); + startDate = drawSetting.getStartDate(); + endDate = drawSetting.getEndDate(); startTime = drawSetting.getStartTime(); endTime = drawSetting.getEndTime(); winnerNum1 = drawSetting.getWinnerNum1(); diff --git a/src/main/java/com/softeer/backend/fo_domain/fcfs/domain/FcfsSetting.java b/src/main/java/com/softeer/backend/fo_domain/fcfs/domain/FcfsSetting.java index 4151fb7b..cb382006 100644 --- a/src/main/java/com/softeer/backend/fo_domain/fcfs/domain/FcfsSetting.java +++ b/src/main/java/com/softeer/backend/fo_domain/fcfs/domain/FcfsSetting.java @@ -1,10 +1,7 @@ package com.softeer.backend.fo_domain.fcfs.domain; import jakarta.persistence.*; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import java.time.LocalDateTime; @@ -12,6 +9,7 @@ @NoArgsConstructor @AllArgsConstructor @Getter +@Setter @Builder @Table(name = "fcfs_setting") public class FcfsSetting { diff --git a/src/main/java/com/softeer/backend/fo_domain/fcfs/repository/FcfsRepository.java b/src/main/java/com/softeer/backend/fo_domain/fcfs/repository/FcfsRepository.java index ac11879a..1eef9320 100644 --- a/src/main/java/com/softeer/backend/fo_domain/fcfs/repository/FcfsRepository.java +++ b/src/main/java/com/softeer/backend/fo_domain/fcfs/repository/FcfsRepository.java @@ -2,9 +2,16 @@ import com.softeer.backend.fo_domain.fcfs.domain.Fcfs; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface FcfsRepository extends JpaRepository { + @Query("SELECT f FROM Fcfs f JOIN FETCH f.user WHERE f.round = :round") + List findFcfsWithUser(@Param("round") int round); + } diff --git a/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsSettingManager.java b/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsSettingManager.java index 4e58eb6b..8e9f51a2 100644 --- a/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsSettingManager.java +++ b/src/main/java/com/softeer/backend/fo_domain/fcfs/service/FcfsSettingManager.java @@ -96,6 +96,7 @@ protected void updateFcfsSetting() { log.info("FcfsSetting updated to round {}", round); + // TODO: 현재 날짜를 기준으로 하루 전 날짜로 방문자수, 추첨 및 선착순 참가자 수를 EventParticipation에 저장하는 로직 구현 int participantCount = eventLockRedisUtil.getData(RedisLockPrefix.FCFS_LOCK_PREFIX.getPrefix() + round); EventParticipation eventParticipation = eventParticipationRepository.findSingleEventParticipation(); eventParticipation.addFcfsParticipantCount(participantCount); diff --git a/src/main/java/com/softeer/backend/fo_domain/user/controller/LoginController.java b/src/main/java/com/softeer/backend/fo_domain/user/controller/LoginController.java index 14922d5f..2e67558c 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/controller/LoginController.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/controller/LoginController.java @@ -1,7 +1,7 @@ package com.softeer.backend.fo_domain.user.controller; import com.softeer.backend.fo_domain.user.dto.LoginRequestDto; -import com.softeer.backend.fo_domain.user.dto.UserTokenResponseDto; +import com.softeer.backend.global.common.dto.JwtTokenResponseDto; import com.softeer.backend.fo_domain.user.service.LoginService; import com.softeer.backend.global.common.response.ResponseDto; import jakarta.validation.Valid; @@ -17,10 +17,10 @@ public class LoginController { private final LoginService loginService; @PostMapping("/login") - ResponseDto handleLogin(@Valid @RequestBody LoginRequestDto loginRequestDto) { - UserTokenResponseDto userTokenResponseDto = loginService.handleLogin(loginRequestDto); + ResponseDto handleLogin(@Valid @RequestBody LoginRequestDto loginRequestDto) { + JwtTokenResponseDto jwtTokenResponseDto = loginService.handleLogin(loginRequestDto); - return ResponseDto.onSuccess(userTokenResponseDto); + return ResponseDto.onSuccess(jwtTokenResponseDto); } } diff --git a/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java b/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java index 875f4673..64f6170a 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java @@ -2,12 +2,12 @@ import com.softeer.backend.fo_domain.user.domain.User; import com.softeer.backend.fo_domain.user.dto.LoginRequestDto; -import com.softeer.backend.fo_domain.user.dto.UserTokenResponseDto; +import com.softeer.backend.global.common.dto.JwtTokenResponseDto; import com.softeer.backend.fo_domain.user.exception.UserException; import com.softeer.backend.fo_domain.user.repository.UserRepository; import com.softeer.backend.global.common.code.status.ErrorStatus; import com.softeer.backend.global.common.constant.RoleType; -import com.softeer.backend.global.common.entity.JwtClaimsDto; +import com.softeer.backend.global.common.dto.JwtClaimsDto; import com.softeer.backend.global.util.JwtUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -28,8 +28,8 @@ public class LoginService { * 3. 전화번호가 이미 User DB에 등록되어 있는 경우, 전화번호로 User 객체를 조회한다. * 4. User 객체의 id를 얻은 후에, access & refresh token을 client에게 전달한다. */ - @Transactional - public UserTokenResponseDto handleLogin(LoginRequestDto loginRequestDto) { + @Transactional(readOnly = true) + public JwtTokenResponseDto handleLogin(LoginRequestDto loginRequestDto) { // 인증번호가 인증 되지 않은 경우, 예외 발생 if (!loginRequestDto.getHasCodeVerified()) { diff --git a/src/main/java/com/softeer/backend/global/annotation/argumentresolver/AuthInfoArgumentResolver.java b/src/main/java/com/softeer/backend/global/annotation/argumentresolver/AuthInfoArgumentResolver.java index 7cab9d86..98a98d6b 100644 --- a/src/main/java/com/softeer/backend/global/annotation/argumentresolver/AuthInfoArgumentResolver.java +++ b/src/main/java/com/softeer/backend/global/annotation/argumentresolver/AuthInfoArgumentResolver.java @@ -1,7 +1,7 @@ package com.softeer.backend.global.annotation.argumentresolver; import com.softeer.backend.global.annotation.AuthInfo; -import com.softeer.backend.global.common.entity.JwtClaimsDto; +import com.softeer.backend.global.common.dto.JwtClaimsDto; import jakarta.servlet.http.HttpServletRequest; import lombok.NonNull; import org.springframework.core.MethodParameter; diff --git a/src/main/java/com/softeer/backend/global/common/code/status/SuccessStatus.java b/src/main/java/com/softeer/backend/global/common/code/status/SuccessStatus.java index 1525c63e..bf21e9da 100644 --- a/src/main/java/com/softeer/backend/global/common/code/status/SuccessStatus.java +++ b/src/main/java/com/softeer/backend/global/common/code/status/SuccessStatus.java @@ -13,7 +13,7 @@ @RequiredArgsConstructor public enum SuccessStatus implements BaseCode { // Success - _OK(HttpStatus.OK, "S-200", "요청 처리 성공"); + _OK(HttpStatus.OK, "S200", "요청 처리 성공"); // 예외의 Http 상태값 private final HttpStatus httpStatus; diff --git a/src/main/java/com/softeer/backend/global/common/constant/ValidationConstant.java b/src/main/java/com/softeer/backend/global/common/constant/ValidationConstant.java index b44ff9d6..8e802a14 100644 --- a/src/main/java/com/softeer/backend/global/common/constant/ValidationConstant.java +++ b/src/main/java/com/softeer/backend/global/common/constant/ValidationConstant.java @@ -9,4 +9,15 @@ public class ValidationConstant { public static final String VERIFICATION_CODE_REGEX = "^[a-zA-Z0-9]{6}$"; public static final String VERIFICATION_CODE_MSG = "잘못된 인증코드 형식입니다."; + // 최소 4자에서 최대 20자까지 허용 + // 영어 대문자, 소문자, 숫자 허용 + public static final String ADMIN_ACCOUNT_REGEX = "^[a-zA-Z0-9]{4,20}$"; + public static final String ADMIN_ACCOUNT_MSG = "잘못된 아이디 형식입니다."; + + // 최소 8자에서 최대 20자까지 허용 + // 적어도 하나의 대문자, 소문자, 숫자, 특수문자 포함 + // 허용할 특수문자: @, #, $, %, &, *, !, ^ + public static final String ADMIN_PASSWORD_REGEX = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@#$%^&*!])[A-Za-z\\d@#$%^&*!]{8,20}$"; + public static final String ADMIN_PASSWORD_MSG = "잘못된 비밀번호 형식입니다."; + } diff --git a/src/main/java/com/softeer/backend/global/common/entity/JwtClaimsDto.java b/src/main/java/com/softeer/backend/global/common/dto/JwtClaimsDto.java similarity index 86% rename from src/main/java/com/softeer/backend/global/common/entity/JwtClaimsDto.java rename to src/main/java/com/softeer/backend/global/common/dto/JwtClaimsDto.java index aace778d..ebf289d8 100644 --- a/src/main/java/com/softeer/backend/global/common/entity/JwtClaimsDto.java +++ b/src/main/java/com/softeer/backend/global/common/dto/JwtClaimsDto.java @@ -1,4 +1,4 @@ -package com.softeer.backend.global.common.entity; +package com.softeer.backend.global.common.dto; import com.softeer.backend.global.common.constant.RoleType; import lombok.Builder; diff --git a/src/main/java/com/softeer/backend/fo_domain/user/dto/UserTokenResponseDto.java b/src/main/java/com/softeer/backend/global/common/dto/JwtTokenResponseDto.java similarity index 82% rename from src/main/java/com/softeer/backend/fo_domain/user/dto/UserTokenResponseDto.java rename to src/main/java/com/softeer/backend/global/common/dto/JwtTokenResponseDto.java index 6f68a6db..aa3c20fb 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/dto/UserTokenResponseDto.java +++ b/src/main/java/com/softeer/backend/global/common/dto/JwtTokenResponseDto.java @@ -1,4 +1,4 @@ -package com.softeer.backend.fo_domain.user.dto; +package com.softeer.backend.global.common.dto; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.AllArgsConstructor; @@ -12,7 +12,7 @@ @Setter @Builder @AllArgsConstructor -public class UserTokenResponseDto { +public class JwtTokenResponseDto { private String accessToken; diff --git a/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java b/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java index 5dc46d21..60f3a6a2 100644 --- a/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java +++ b/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java @@ -3,13 +3,13 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.softeer.backend.global.common.code.status.ErrorStatus; -import com.softeer.backend.global.common.entity.JwtClaimsDto; +import com.softeer.backend.global.common.dto.JwtClaimsDto; import com.softeer.backend.global.common.exception.JwtAuthenticationException; import com.softeer.backend.global.common.response.ResponseDto; import com.softeer.backend.global.config.properties.JwtProperties; import com.softeer.backend.global.util.JwtUtil; import com.softeer.backend.global.util.StringRedisUtil; -import com.softeer.backend.fo_domain.user.dto.UserTokenResponseDto; +import com.softeer.backend.global.common.dto.JwtTokenResponseDto; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -172,23 +172,23 @@ private void makeAndSendAccessTokenAndRefreshToken(HttpServletResponse response, String refreshToken) throws IOException { LocalDateTime expireTime = LocalDateTime.now().plusSeconds(this.jwtProperties.getAccessExpiration() / 1000); // refresh token, access token 을 응답 본문에 넣어 응답 - UserTokenResponseDto userTokenResponseDto = UserTokenResponseDto.builder() + JwtTokenResponseDto jwtTokenResponseDto = JwtTokenResponseDto.builder() .accessToken(accessToken) .refreshToken(refreshToken) .expiredTime(expireTime) .build(); - makeResultResponse(response, userTokenResponseDto); + makeResultResponse(response, jwtTokenResponseDto); } private void makeResultResponse(HttpServletResponse response, - UserTokenResponseDto userTokenResponseDto) throws IOException { + JwtTokenResponseDto jwtTokenResponseDto) throws IOException { response.setStatus(HttpStatus.OK.value()); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); try (OutputStream os = response.getOutputStream()) { ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()); - ResponseDto responseDto = ResponseDto.onSuccess(userTokenResponseDto); + ResponseDto responseDto = ResponseDto.onSuccess(jwtTokenResponseDto); objectMapper.writeValue(os, responseDto); os.flush(); } diff --git a/src/main/java/com/softeer/backend/global/filter/JwtAuthorizationFilter.java b/src/main/java/com/softeer/backend/global/filter/JwtAuthorizationFilter.java index 36c1e11f..76850168 100644 --- a/src/main/java/com/softeer/backend/global/filter/JwtAuthorizationFilter.java +++ b/src/main/java/com/softeer/backend/global/filter/JwtAuthorizationFilter.java @@ -2,7 +2,7 @@ import com.softeer.backend.global.common.code.status.ErrorStatus; import com.softeer.backend.global.common.constant.RoleType; -import com.softeer.backend.global.common.entity.JwtClaimsDto; +import com.softeer.backend.global.common.dto.JwtClaimsDto; import com.softeer.backend.global.common.exception.JwtAuthorizationException; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; diff --git a/src/main/java/com/softeer/backend/global/util/JwtUtil.java b/src/main/java/com/softeer/backend/global/util/JwtUtil.java index 77cc1e1b..982a560e 100644 --- a/src/main/java/com/softeer/backend/global/util/JwtUtil.java +++ b/src/main/java/com/softeer/backend/global/util/JwtUtil.java @@ -2,10 +2,10 @@ import com.softeer.backend.global.common.code.status.ErrorStatus; import com.softeer.backend.global.common.constant.RoleType; -import com.softeer.backend.global.common.entity.JwtClaimsDto; +import com.softeer.backend.global.common.dto.JwtClaimsDto; import com.softeer.backend.global.common.exception.JwtAuthenticationException; import com.softeer.backend.global.config.properties.JwtProperties; -import com.softeer.backend.fo_domain.user.dto.UserTokenResponseDto; +import com.softeer.backend.global.common.dto.JwtTokenResponseDto; import io.jsonwebtoken.*; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; @@ -89,13 +89,13 @@ private JwtClaimsDto getAuthInfoFromToken(String token) { } // 전화번호 로그인 및 admin 로그인 시 jwt 응답 생성 + redis refresh 저장 - public UserTokenResponseDto createServiceToken(JwtClaimsDto jwtClaimsDto) { + public JwtTokenResponseDto createServiceToken(JwtClaimsDto jwtClaimsDto) { stringRedisUtil.deleteData(stringRedisUtil.getRedisKeyForJwt(jwtClaimsDto)); String accessToken = createAccessToken(jwtClaimsDto); String refreshToken = createRefreshToken(jwtClaimsDto); // 서비스 토큰 생성 - UserTokenResponseDto userTokenResponseDto = UserTokenResponseDto.builder() + JwtTokenResponseDto jwtTokenResponseDto = JwtTokenResponseDto.builder() .accessToken(accessToken) .refreshToken(refreshToken) .expiredTime(LocalDateTime.now().plusSeconds(jwtProperties.getAccessExpiration() / 1000)) @@ -103,9 +103,9 @@ public UserTokenResponseDto createServiceToken(JwtClaimsDto jwtClaimsDto) { // redis refresh token 저장 stringRedisUtil.setDataExpire(stringRedisUtil.getRedisKeyForJwt(jwtClaimsDto), - userTokenResponseDto.getRefreshToken(), jwtProperties.getRefreshExpiration()); + jwtTokenResponseDto.getRefreshToken(), jwtProperties.getRefreshExpiration()); - return userTokenResponseDto; + return jwtTokenResponseDto; } // token 유효성 검증 diff --git a/src/main/java/com/softeer/backend/global/util/StringRedisUtil.java b/src/main/java/com/softeer/backend/global/util/StringRedisUtil.java index adc26257..86ba9aa5 100644 --- a/src/main/java/com/softeer/backend/global/util/StringRedisUtil.java +++ b/src/main/java/com/softeer/backend/global/util/StringRedisUtil.java @@ -1,7 +1,7 @@ package com.softeer.backend.global.util; import com.softeer.backend.global.common.constant.RoleType; -import com.softeer.backend.global.common.entity.JwtClaimsDto; +import com.softeer.backend.global.common.dto.JwtClaimsDto; import lombok.RequiredArgsConstructor; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; @@ -83,4 +83,10 @@ public String getRedisKeyForJwt(JwtClaimsDto jwtClaimsDto) { return roleType.getRedisKeyPrefix() + id; } + // redis에 저장된 Refresh Token을 삭제하는 메서드 + public void deleteRefreshToken(JwtClaimsDto jwtClaimsDto) { + + deleteData(getRedisKeyForJwt(jwtClaimsDto)); + } + } From 9faa347d5a626408a21cc550ebefdedf257349c6 Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Tue, 6 Aug 2024 10:19:44 +0900 Subject: [PATCH 23/39] =?UTF-8?q?infra:=20=EB=A0=88=EB=94=94=EC=8A=A4=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/softeer/backend/fo_domain/draw/service/DrawService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawService.java b/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawService.java index abb35f2b..c39c8a12 100644 --- a/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawService.java +++ b/src/main/java/com/softeer/backend/fo_domain/draw/service/DrawService.java @@ -27,7 +27,7 @@ @Service @RequiredArgsConstructor public class DrawService { - private final DrawRepository drawRepository; + // private final DrawRepository drawRepository; private final DrawParticipationInfoRepository drawParticipationInfoRepository; private final ShareInfoRepository shareInfoRepository; private final ShareUrlInfoRepository shareUrlInfoRepository; From 6fbc9c828348dd52d70681ba3911a6ab1c92af97 Mon Sep 17 00:00:00 2001 From: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Date: Thu, 8 Aug 2024 20:04:49 +0900 Subject: [PATCH 24/39] =?UTF-8?q?[Feat]=20=EA=B8=B0=EB=8C=80=ED=8F=89=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20(#57)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson --- build.gradle | 2 + .../comment/dto/CommentsResponse.java | 86 +++++++++++++++++++ .../fo_domain/user/dto/LoginRequestDto.java | 1 + .../filter/JwtAuthenticationFilter.java | 8 ++ 4 files changed, 97 insertions(+) create mode 100644 src/main/java/com/softeer/backend/fo_domain/comment/dto/CommentsResponse.java diff --git a/build.gradle b/build.gradle index cfc40bd7..2d524751 100644 --- a/build.gradle +++ b/build.gradle @@ -36,6 +36,8 @@ dependencies { // JWT 설정 implementation 'io.jsonwebtoken:jjwt:0.9.1' + implementation "com.googlecode.json-simple:json-simple:1.1.1" // Google Simple JSON + implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' //DatatypeConverter // Google Simple JSON implementation "com.googlecode.json-simple:json-simple:1.1.1" diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/dto/CommentsResponse.java b/src/main/java/com/softeer/backend/fo_domain/comment/dto/CommentsResponse.java new file mode 100644 index 00000000..d3e49356 --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/comment/dto/CommentsResponse.java @@ -0,0 +1,86 @@ +package com.softeer.backend.fo_domain.comment.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.softeer.backend.fo_domain.comment.constant.CommentNickname; +import com.softeer.backend.fo_domain.comment.constant.ExpectationComment; +import com.softeer.backend.fo_domain.comment.domain.Comment; +import com.softeer.backend.fo_domain.comment.util.ScrollPaginationUtil; +import lombok.*; + +import java.util.List; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PUBLIC) +@Builder +@Getter +public class CommentsResponse { + public static final int LAST_CURSOR = -1; + + private int nextCursor; + + private int totalComments; + + private List comments; + + @Getter + @AllArgsConstructor + @Builder + public static class CommentResponse { + + private Boolean isMine; + + private String nickName; + + private String comment; + } + + public static CommentsResponse of(ScrollPaginationUtil commentsScroll, Integer userId) { + if (commentsScroll.isLastScroll()) { + return CommentsResponse.newLastScroll(commentsScroll.getCurrentScrollItems(), userId); + } + return CommentsResponse.newScrollHasNext(commentsScroll.getCurrentScrollItems(), commentsScroll.getNextCursor().getId(), + userId); + } + + // 마지막 스크롤일 때의 응답값을 구성하는 메서드 + // nextCursor 값을 -1로 설정한다. + private static CommentsResponse newLastScroll(List commentsScroll, Integer userId) { + return newScrollHasNext(commentsScroll, LAST_CURSOR, userId); + } + + // 마지막 스크롤이 아닐 때의 응답값을 구성하는 메서드 + private static CommentsResponse newScrollHasNext(List commentsScroll, int nextCursor, + Integer userId) { + return CommentsResponse.builder() + .nextCursor(nextCursor) + .totalComments(commentsScroll.size()) + .comments(getContents(commentsScroll, userId)) + .build(); + } + + // CommentResponse를 생성하여 반환하는 메서드 + // 유저가 로그인을 한 상태에서 자신의 댓글이 응답에 포함될 경우, + // isMine 변수값을 true로, nickname의 접미사에 '(나)'를 붙여서 응답을 구성한다. + private static List getContents(List commentsScroll, Integer userId) { + return commentsScroll.stream() + .map(_comment -> { + boolean isMine = false; + String nickname = _comment.getNickname(); + String comment = _comment.getExpectationComment().getComment(); + + if(userId != null && _comment.getUserId() != null && + _comment.getUserId().equals(userId)){ + isMine = true; + nickname = nickname + CommentNickname.MY_NICKNAME_SUFFIX; + } + + return CommentResponse.builder() + .isMine(isMine) + .nickName(nickname) + .comment(comment) + .build(); + }) + .toList(); + + } +} diff --git a/src/main/java/com/softeer/backend/fo_domain/user/dto/LoginRequestDto.java b/src/main/java/com/softeer/backend/fo_domain/user/dto/LoginRequestDto.java index e8f334d4..2309ef36 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/dto/LoginRequestDto.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/dto/LoginRequestDto.java @@ -1,5 +1,6 @@ package com.softeer.backend.fo_domain.user.dto; +import com.fasterxml.jackson.annotation.JsonProperty; import com.softeer.backend.global.common.constant.ValidationConstant; import jakarta.validation.constraints.Pattern; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java b/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java index 60f3a6a2..20c41801 100644 --- a/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java +++ b/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java @@ -65,6 +65,14 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse return; } + // optionalAuthUrls에 등록된 url 중, access token이 header에 없으면 인증 x + if(isUriInOptionalAuthList(request.getRequestURI()) && + jwtUtil.extractAccessToken(request).isEmpty()){ + + filterChain.doFilter(request, response); + return; + } + // Case 01) Access Token 재발급인 경우(Authorization Header Access Token 유효성 x) if (request.getRequestURI().contains("/reissue")) { From a63f49a7edb07475e357e69ca369d693d5cc96a7 Mon Sep 17 00:00:00 2001 From: DrRivaski <48974215+DrRivaski@users.noreply.github.com> Date: Sun, 11 Aug 2024 21:36:23 +0900 Subject: [PATCH 25/39] =?UTF-8?q?[Refactor]=20=EA=B3=B5=EC=9C=A0=20url=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=ED=95=98=EB=8A=94=20api=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20(#70)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * infra: 빌드 테스트 yml 작성 * infra: DB 정보 추가 * infra: ssh-agent 버전 변경 * infra: known_hosts 추가 * infra: db port 변경 * infra: database test 설정 변경 * infra: DB 환경변수 설정 및 application.yml 생성 * infra: application.yml 동적 생성 스크립트 수정 * infra: 레디스 설정 추가 * infra: redis test 추가 * infra: redis 버전 변경 * infra: redis cli 설치 * infra: application.yml 위치 및 내용 확인 * infra: Github Actions 환경변수에 REDIS_HOST, REDIS_PORT 추가 * infra: 환경변수 확인 추가 * feat: draw_rank column 이름 수정 * infra: pull_request시 Github Actions 동작하도록 수정 * cicd test (#54) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test --------- Co-authored-by: hyeokson * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson * cicd test (#58) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * chore: ci/cd를 위한 커밋 --------- Co-authored-by: hyeokson * refactor: 공유 url 조회하는 레포지토리 변경 - ShareInfoRepository -> ShareUrlInfoRepository * refactor: 잘못 작성된 메서드 삭제 - findSharedUrlByUserId 삭제 * refactor: 사용되지 않는 shareInfoRepository 삭제 * refactor: 변수명 변경 - sharedUrl -> shareUrl * [Feat] 성공, 실패 상태 코드 수정하기 (#65) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: cors 도메인 설정 * refactor: 커스텀 코드 형식 수정 및 에러코드 수정 - '(에러를 구분하는 알파벳)3자리 숫자' 형태로 커스텀 에러 코드 관리 - 클라이언트에서 에러 코드에 의해 분기되지 않으면 하나의 에러로 관리하도록 변경 * refactor: 하나의 성공 코드로 관리하도록 변경 * rebase: 원본 develop 브랜치와 rebase * rebase: 원본 develop 브랜치 rebase * feat: cors 설정에 localhost 추가 * refactor: 함수명 변경 * refactor: 예외 코드 변경 --------- Co-authored-by: hyeokson * [Feat]Admin Api 구현 (#67) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: Admin entity 클래스 생성 * feat: Admin exception 클래스 생성 * feat: Admin 로그인 컨트롤러 구현 * feat: Admin 로그인 요청 dto 구현 * feat: Admin 로그인 서비스 클래스 구현 * feat: Admin repository 구현 * feat: 추첨 이벤트 시간 설정 요청 dto 구현 * feat: 추첨 시간 검증 클래스 구현 * feat: 추첨 당첨자 응답 dto 구현 * feat: 추첨 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 응답 dto 구현 * feat: 이벤트 페이지 컨트롤러 구현 * feat: 이벤트 페이지 service 클래스 구현 * feat: 선착순 날짜 검증 클래스 구현 * feat: 선착순 날짜 등록 요청 dto 구현 * feat: 선착순 시간 검증 클래스 구현 * feat: 선착순 당첨자 응답 dto 구현 * feat: 선착순 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 컨트롤러 클래스 구현 * feat: 이벤트 지표 service 클래스 구현 * feat: 메인 페이지 관련 컨트롤러 클래스 구현 * feat: 메인 페이지 응답 dto 구현 * feat: 메인 페이지 service 클래스 구현 * feat: password encoder 구현 * feat: 확률값을 %형태로 바꿔주는 serializer 구현 * feat: 전화번호에 '-'를 붙여주는 serializer 구현 * feat: 추첨 시간 검증 애노테이션 구현 * feat: 선착순 날짜 검증 애노테이션 구현 * feat: 선착순 시간 검증 애노테이션 구현 * feat: 당첨 관리 페이지 컨트롤러 클래스 구현 * feat: 당첨 관리 페이지 service 클래스 구현 * config: Bcrypt 의존성 설정 * refactor: winningDate 변수의 자료형 변경 * feat: Draw, User를 조회하는 메서드 구현 * refactor: 변수명 변경 * feat: Transactional 애노테이션 추가 * refactor: 자료형 변경 및 시간 관련 변수 분리 * refactor: 자료형 변경 * feat: eventDate 변수 추가 * feat: EventParticipation 조회 메서드 구현 * feat: round값으로 Fcfs 조회하는 메서드 구현 * feat: @setter 애노테이션 추가 * docs: TODO 추가 * refactor: 클래스명 변경 * refactor: 패키지 변경 * refactor: 패키지 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 변경 * refactor: Refresh Token을 삭제하는 메서드 구현 * refactor: 커스텀 코드값 변경 * refactor: 검증 관련 상수 추가 * style: 코드 형식 맞추기 --------- Co-authored-by: hyeokson * infra: 레디스 설정 추가 * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson --------- Co-authored-by: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Co-authored-by: hyeokson --- build.gradle | 6 ++++++ .../fo_domain/share/repository/ShareInfoRepository.java | 1 - .../fo_domain/share/service/ShareInfoService.java | 9 +++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 2d524751..819d78af 100644 --- a/build.gradle +++ b/build.gradle @@ -45,6 +45,12 @@ dependencies { //DatatypeConverter implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + // Google Simple JSON + implementation "com.googlecode.json-simple:json-simple:1.1.1" + + //DatatypeConverter + implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + // JPA 설정 implementation 'org.springframework.boot:spring-boot-starter-data-jpa' diff --git a/src/main/java/com/softeer/backend/fo_domain/share/repository/ShareInfoRepository.java b/src/main/java/com/softeer/backend/fo_domain/share/repository/ShareInfoRepository.java index 21912016..e21e2fcd 100644 --- a/src/main/java/com/softeer/backend/fo_domain/share/repository/ShareInfoRepository.java +++ b/src/main/java/com/softeer/backend/fo_domain/share/repository/ShareInfoRepository.java @@ -8,6 +8,5 @@ @Repository public interface ShareInfoRepository extends JpaRepository { - Optional findSharedUrlByUserId(Integer userId); Optional findShareInfoByUserId(Integer userId); } diff --git a/src/main/java/com/softeer/backend/fo_domain/share/service/ShareInfoService.java b/src/main/java/com/softeer/backend/fo_domain/share/service/ShareInfoService.java index 4d35a90e..56c5868d 100644 --- a/src/main/java/com/softeer/backend/fo_domain/share/service/ShareInfoService.java +++ b/src/main/java/com/softeer/backend/fo_domain/share/service/ShareInfoService.java @@ -3,6 +3,7 @@ import com.softeer.backend.fo_domain.share.dto.ShareUrlResponseDto; import com.softeer.backend.fo_domain.share.exception.ShareInfoException; import com.softeer.backend.fo_domain.share.repository.ShareInfoRepository; +import com.softeer.backend.fo_domain.share.repository.ShareUrlInfoRepository; import com.softeer.backend.global.common.code.status.ErrorStatus; import com.softeer.backend.global.common.response.ResponseDto; import lombok.RequiredArgsConstructor; @@ -11,16 +12,16 @@ @Service @RequiredArgsConstructor public class ShareInfoService { - private final ShareInfoRepository shareInfoRepository; + private final ShareUrlInfoRepository shareUrlInfoRepository; public ResponseDto getShortenShareUrl(Integer userId) { - String sharedUrl = shareInfoRepository.findSharedUrlByUserId(userId).orElseThrow( + String shareUrl = shareUrlInfoRepository.findShareUrlByUserId(userId).orElseThrow( () -> new ShareInfoException(ErrorStatus._NOT_FOUND) ); - // 만약 DB에 이미 생성된 단축 url이 있다면 반환 + // DB에 이미 생성된 단축 url 반환 return ResponseDto.onSuccess(ShareUrlResponseDto.builder() - .shareUrl(sharedUrl) + .shareUrl(shareUrl) .build()); } } From 402432f46ba3493a2a415eb180255c21979c5023 Mon Sep 17 00:00:00 2001 From: DrRivaski <48974215+DrRivaski@users.noreply.github.com> Date: Sun, 11 Aug 2024 21:36:23 +0900 Subject: [PATCH 26/39] =?UTF-8?q?[Refactor]=20=EA=B3=B5=EC=9C=A0=20url=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=ED=95=98=EB=8A=94=20api=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20(#70)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * infra: 빌드 테스트 yml 작성 * infra: DB 정보 추가 * infra: ssh-agent 버전 변경 * infra: known_hosts 추가 * infra: db port 변경 * infra: database test 설정 변경 * infra: DB 환경변수 설정 및 application.yml 생성 * infra: application.yml 동적 생성 스크립트 수정 * infra: 레디스 설정 추가 * infra: redis test 추가 * infra: redis 버전 변경 * infra: redis cli 설치 * infra: application.yml 위치 및 내용 확인 * infra: Github Actions 환경변수에 REDIS_HOST, REDIS_PORT 추가 * infra: 환경변수 확인 추가 * feat: draw_rank column 이름 수정 * infra: pull_request시 Github Actions 동작하도록 수정 * cicd test (#54) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test --------- Co-authored-by: hyeokson * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson * cicd test (#58) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * chore: ci/cd를 위한 커밋 --------- Co-authored-by: hyeokson * refactor: 공유 url 조회하는 레포지토리 변경 - ShareInfoRepository -> ShareUrlInfoRepository * refactor: 잘못 작성된 메서드 삭제 - findSharedUrlByUserId 삭제 * refactor: 사용되지 않는 shareInfoRepository 삭제 * refactor: 변수명 변경 - sharedUrl -> shareUrl * [Feat] 성공, 실패 상태 코드 수정하기 (#65) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: cors 도메인 설정 * refactor: 커스텀 코드 형식 수정 및 에러코드 수정 - '(에러를 구분하는 알파벳)3자리 숫자' 형태로 커스텀 에러 코드 관리 - 클라이언트에서 에러 코드에 의해 분기되지 않으면 하나의 에러로 관리하도록 변경 * refactor: 하나의 성공 코드로 관리하도록 변경 * rebase: 원본 develop 브랜치와 rebase * rebase: 원본 develop 브랜치 rebase * feat: cors 설정에 localhost 추가 * refactor: 함수명 변경 * refactor: 예외 코드 변경 --------- Co-authored-by: hyeokson * [Feat]Admin Api 구현 (#67) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: Admin entity 클래스 생성 * feat: Admin exception 클래스 생성 * feat: Admin 로그인 컨트롤러 구현 * feat: Admin 로그인 요청 dto 구현 * feat: Admin 로그인 서비스 클래스 구현 * feat: Admin repository 구현 * feat: 추첨 이벤트 시간 설정 요청 dto 구현 * feat: 추첨 시간 검증 클래스 구현 * feat: 추첨 당첨자 응답 dto 구현 * feat: 추첨 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 응답 dto 구현 * feat: 이벤트 페이지 컨트롤러 구현 * feat: 이벤트 페이지 service 클래스 구현 * feat: 선착순 날짜 검증 클래스 구현 * feat: 선착순 날짜 등록 요청 dto 구현 * feat: 선착순 시간 검증 클래스 구현 * feat: 선착순 당첨자 응답 dto 구현 * feat: 선착순 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 컨트롤러 클래스 구현 * feat: 이벤트 지표 service 클래스 구현 * feat: 메인 페이지 관련 컨트롤러 클래스 구현 * feat: 메인 페이지 응답 dto 구현 * feat: 메인 페이지 service 클래스 구현 * feat: password encoder 구현 * feat: 확률값을 %형태로 바꿔주는 serializer 구현 * feat: 전화번호에 '-'를 붙여주는 serializer 구현 * feat: 추첨 시간 검증 애노테이션 구현 * feat: 선착순 날짜 검증 애노테이션 구현 * feat: 선착순 시간 검증 애노테이션 구현 * feat: 당첨 관리 페이지 컨트롤러 클래스 구현 * feat: 당첨 관리 페이지 service 클래스 구현 * config: Bcrypt 의존성 설정 * refactor: winningDate 변수의 자료형 변경 * feat: Draw, User를 조회하는 메서드 구현 * refactor: 변수명 변경 * feat: Transactional 애노테이션 추가 * refactor: 자료형 변경 및 시간 관련 변수 분리 * refactor: 자료형 변경 * feat: eventDate 변수 추가 * feat: EventParticipation 조회 메서드 구현 * feat: round값으로 Fcfs 조회하는 메서드 구현 * feat: @setter 애노테이션 추가 * docs: TODO 추가 * refactor: 클래스명 변경 * refactor: 패키지 변경 * refactor: 패키지 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 변경 * refactor: Refresh Token을 삭제하는 메서드 구현 * refactor: 커스텀 코드값 변경 * refactor: 검증 관련 상수 추가 * style: 코드 형식 맞추기 --------- Co-authored-by: hyeokson * infra: 레디스 설정 추가 * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson --------- Co-authored-by: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Co-authored-by: hyeokson --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index 819d78af..1437840e 100644 --- a/build.gradle +++ b/build.gradle @@ -51,6 +51,12 @@ dependencies { //DatatypeConverter implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + // Google Simple JSON + implementation "com.googlecode.json-simple:json-simple:1.1.1" + + //DatatypeConverter + implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + // JPA 설정 implementation 'org.springframework.boot:spring-boot-starter-data-jpa' From a88eed7e88994e254808e3d7893899928cbca442 Mon Sep 17 00:00:00 2001 From: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Date: Sun, 11 Aug 2024 23:42:20 +0900 Subject: [PATCH 27/39] =?UTF-8?q?[Feature]=20static=20=08text=EB=A5=BC=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=ED=95=98=EB=8A=94=20enum=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(#71)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * refactor: transactional 어노테이션 수정 * refactor: 변수명 변경 * feat: MainPage 컨트롤러 클래스 생성 * feat: MainPage service 클래스 생성 * feat: StaticResources entity 클래스 생성 * feat: StaticResources repository 클래스 생성 * feat: StaticResourcesUtil 클래스 생성 * feat: 정적 text를 관리하는 enum 생성 * refactor: 변수명 변경 * refactor: 검증 애노테이션 추가 * refactor: DayOfWeek 속성 변경 * refactor: 예외 msg를 응답객체 result에 넣도록 변경 * refactor: 변수명 변경 * refactor: DayOfWeek 속성 변경 * refactor: 검증 애노테이션 추가 * refactor: 검증 상수 추가 * refactor: 변수 타입을 래퍼타입으로 변경 * refactor: 클래스명 변경 --------- Co-authored-by: hyeokson --- ...ller.java => AdminMainPageController.java} | 2 +- .../controller/WinnerPageController.java | 4 +- .../winner/DrawWinnerUpdateRequestDto.java | 19 +++- .../winner/FcfsWinnerUpdateRequestDto.java | 12 ++- .../admin/service/EventPageService.java | 6 +- .../validator/FcfsDateRangeValidator.java | 4 +- .../comment/constant/ExpectationComment.java | 6 +- .../comment/controller/CommentController.java | 4 +- .../comment/service/CommentService.java | 4 +- .../controller/MainPageController.java | 7 ++ .../mainpage/service/MainPageService.java | 4 + .../fo_domain/user/service/LoginService.java | 2 +- .../common/constant/ValidationConstant.java | 3 + .../common/exception/ExceptionAdvice.java | 21 ++--- .../staticresources/constant/StaticText.java | 89 +++++++++++++++++++ .../domain/StaticResources.java | 27 ++++++ .../repository/StaticResourcesRepository.java | 7 ++ .../util/StaticResourcesUtil.java | 43 +++++++++ 18 files changed, 233 insertions(+), 31 deletions(-) rename src/main/java/com/softeer/backend/bo_domain/admin/controller/{MainPageController.java => AdminMainPageController.java} (95%) create mode 100644 src/main/java/com/softeer/backend/fo_domain/mainpage/controller/MainPageController.java create mode 100644 src/main/java/com/softeer/backend/fo_domain/mainpage/service/MainPageService.java create mode 100644 src/main/java/com/softeer/backend/global/staticresources/constant/StaticText.java create mode 100644 src/main/java/com/softeer/backend/global/staticresources/domain/StaticResources.java create mode 100644 src/main/java/com/softeer/backend/global/staticresources/repository/StaticResourcesRepository.java create mode 100644 src/main/java/com/softeer/backend/global/staticresources/util/StaticResourcesUtil.java diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/controller/MainPageController.java b/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminMainPageController.java similarity index 95% rename from src/main/java/com/softeer/backend/bo_domain/admin/controller/MainPageController.java rename to src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminMainPageController.java index 07303d34..824b3b39 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/controller/MainPageController.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminMainPageController.java @@ -11,7 +11,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("/admin") -public class MainPageController { +public class AdminMainPageController { private final MainPageService mainPageService; @GetMapping("/main") diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/controller/WinnerPageController.java b/src/main/java/com/softeer/backend/bo_domain/admin/controller/WinnerPageController.java index e7d5a902..d2a661ee 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/controller/WinnerPageController.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/controller/WinnerPageController.java @@ -17,7 +17,7 @@ public class WinnerPageController { private final WinnerPageService winnerPageService; @GetMapping("/fcfs/{round}") - public ResponseDto getFcfsWinnerList(@PathVariable int round) { + public ResponseDto getFcfsWinnerList(@PathVariable Integer round) { FcfsWinnerListResponseDto fcfsWinnerListResponseDto = winnerPageService.getFcfsWinnerList(round); @@ -25,7 +25,7 @@ public ResponseDto getFcfsWinnerList(@PathVariable in } @GetMapping("/draw/{rank}") - public ResponseDto getDrawWinnerList(@PathVariable int rank) { + public ResponseDto getDrawWinnerList(@PathVariable Integer rank) { DrawWinnerListResponseDto drawWinnerListResponseDto = winnerPageService.getDrawWinnerList(rank); diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/DrawWinnerUpdateRequestDto.java b/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/DrawWinnerUpdateRequestDto.java index d141dff8..5fe792fa 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/DrawWinnerUpdateRequestDto.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/DrawWinnerUpdateRequestDto.java @@ -1,5 +1,9 @@ package com.softeer.backend.bo_domain.admin.dto.winner; +import com.softeer.backend.global.common.constant.ValidationConstant; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; import lombok.*; @NoArgsConstructor(access = AccessLevel.PRIVATE) @@ -8,9 +12,18 @@ @Getter public class DrawWinnerUpdateRequestDto { - private int firstWinnerNum; + @NotNull + @Min(value = 1, message = ValidationConstant.MIN_VALUE_MSG) + @Max(value = 5, message = ValidationConstant.MAX_VALUE_MSG) + private Integer firstWinnerNum; - private int secondWinnerNum; + @NotNull + @Min(value = 1, message = ValidationConstant.MIN_VALUE_MSG) + @Max(value = 10, message = ValidationConstant.MAX_VALUE_MSG) + private Integer secondWinnerNum; - private int thirdWinnerNum; + @NotNull + @Min(value = 1, message = ValidationConstant.MIN_VALUE_MSG) + @Max(value = 100, message = ValidationConstant.MAX_VALUE_MSG) + private Integer thirdWinnerNum; } diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/FcfsWinnerUpdateRequestDto.java b/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/FcfsWinnerUpdateRequestDto.java index 6553eda3..0c8105b7 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/FcfsWinnerUpdateRequestDto.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/dto/winner/FcfsWinnerUpdateRequestDto.java @@ -1,5 +1,9 @@ package com.softeer.backend.bo_domain.admin.dto.winner; +import com.softeer.backend.global.common.constant.ValidationConstant; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; import lombok.*; @NoArgsConstructor(access = AccessLevel.PRIVATE) @@ -8,7 +12,11 @@ @Getter public class FcfsWinnerUpdateRequestDto { - private int round; + @NotNull + private Integer round; - private int fcfsWinnerNum; + @NotNull + @Min(value = 1, message = ValidationConstant.MIN_VALUE_MSG) + @Max(value = 50, message = ValidationConstant.MAX_VALUE_MSG) + private Integer fcfsWinnerNum; } diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/service/EventPageService.java b/src/main/java/com/softeer/backend/bo_domain/admin/service/EventPageService.java index 1f32c029..ba36e143 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/service/EventPageService.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/service/EventPageService.java @@ -60,10 +60,10 @@ private void updateFcfsSetting(FcfsSetting setting, LocalDate date, LocalTime ti } private void updateDrawSetting(DrawSetting drawSetting, LocalDate startDate, LocalDate endDate) { - LocalDate startDateOfDraw = startDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY)); + LocalDate startDateOfDraw = startDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); - LocalDate endDateOfPreviousWeek = endDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.SATURDAY)); - LocalDate endDateOfDraw = endDateOfPreviousWeek.with(TemporalAdjusters.next(DayOfWeek.SATURDAY)); + LocalDate endDateOfPreviousWeek = endDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)); + LocalDate endDateOfDraw = endDateOfPreviousWeek.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)); drawSetting.setStartDate(startDateOfDraw); drawSetting.setEndDate(endDateOfDraw); diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/validator/FcfsDateRangeValidator.java b/src/main/java/com/softeer/backend/bo_domain/admin/validator/FcfsDateRangeValidator.java index 5ba2208e..3627bcce 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/validator/FcfsDateRangeValidator.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/validator/FcfsDateRangeValidator.java @@ -27,8 +27,8 @@ public boolean isValid(FcfsEventTimeRequestDto value, ConstraintValidatorContext LocalDate startDate = value.getStartDate(); LocalDate endDate = value.getEndDate(); - LocalDate startDateWeekStart = startDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY)); - LocalDate endDateWeekStart = endDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY)); + LocalDate startDateWeekStart = startDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); + LocalDate endDateWeekStart = endDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); boolean isSameWeek = startDateWeekStart.equals(endDateWeekStart); diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/constant/ExpectationComment.java b/src/main/java/com/softeer/backend/fo_domain/comment/constant/ExpectationComment.java index d407cfb5..271a7525 100644 --- a/src/main/java/com/softeer/backend/fo_domain/comment/constant/ExpectationComment.java +++ b/src/main/java/com/softeer/backend/fo_domain/comment/constant/ExpectationComment.java @@ -27,14 +27,14 @@ public int getCommentOrder() { return this.ordinal() + 1; } - public static ExpectationComment of(int commentNum) { + public static ExpectationComment of(int commentType) { for (ExpectationComment comment : values()) { - if (comment.getCommentOrder() == commentNum) { + if (comment.getCommentOrder() == commentType) { return comment; } } - log.error("Invalid comment number: " + commentNum); + log.error("Invalid comment number: " + commentType); throw new CommentException(ErrorStatus._NOT_FOUND); } } diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/controller/CommentController.java b/src/main/java/com/softeer/backend/fo_domain/comment/controller/CommentController.java index 2f94d3b5..fce14939 100644 --- a/src/main/java/com/softeer/backend/fo_domain/comment/controller/CommentController.java +++ b/src/main/java/com/softeer/backend/fo_domain/comment/controller/CommentController.java @@ -29,10 +29,10 @@ ResponseDto getComment(@RequestParam(name = "cursor", requi } @PostMapping("/comment") - ResponseDto saveComment(@RequestParam(name = "commentNum") int commentNum, + ResponseDto saveComment(@RequestParam(name = "commentType") int commentType, @AuthInfo Integer userId) { - commentService.saveComment(userId, commentNum); + commentService.saveComment(userId, commentType); return ResponseDto.onSuccess(); diff --git a/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java b/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java index 0f4652aa..145229c3 100644 --- a/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java +++ b/src/main/java/com/softeer/backend/fo_domain/comment/service/CommentService.java @@ -41,7 +41,7 @@ public CommentsResponseDto getComments(Integer userId, Integer cursor) { * 기대평을 저장하는 메서드 */ @Transactional - public void saveComment(Integer userId, int commentNum) { + public void saveComment(Integer userId, int commentType) { // 로그인 한 유저가 기대평을 등록했다면 User entity의 id값을 기반으로 닉네임을 설정한다. // 로그인 하지 않았다면, 랜덤으로 닉네임을 설정한다. @@ -50,7 +50,7 @@ public void saveComment(Integer userId, int commentNum) { commentRepository.save(Comment.builder() .nickname(randomNickname) - .expectationComment(ExpectationComment.of(commentNum)) + .expectationComment(ExpectationComment.of(commentType)) .userId(userId) .build() ); diff --git a/src/main/java/com/softeer/backend/fo_domain/mainpage/controller/MainPageController.java b/src/main/java/com/softeer/backend/fo_domain/mainpage/controller/MainPageController.java new file mode 100644 index 00000000..33f4860c --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/mainpage/controller/MainPageController.java @@ -0,0 +1,7 @@ +package com.softeer.backend.fo_domain.mainpage.controller; + +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class MainPageController { +} diff --git a/src/main/java/com/softeer/backend/fo_domain/mainpage/service/MainPageService.java b/src/main/java/com/softeer/backend/fo_domain/mainpage/service/MainPageService.java new file mode 100644 index 00000000..9fd0bbf9 --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/mainpage/service/MainPageService.java @@ -0,0 +1,4 @@ +package com.softeer.backend.fo_domain.mainpage.service; + +public class MainPageService { +} diff --git a/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java b/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java index 64f6170a..60c1ee0a 100644 --- a/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java +++ b/src/main/java/com/softeer/backend/fo_domain/user/service/LoginService.java @@ -28,7 +28,7 @@ public class LoginService { * 3. 전화번호가 이미 User DB에 등록되어 있는 경우, 전화번호로 User 객체를 조회한다. * 4. User 객체의 id를 얻은 후에, access & refresh token을 client에게 전달한다. */ - @Transactional(readOnly = true) + @Transactional public JwtTokenResponseDto handleLogin(LoginRequestDto loginRequestDto) { // 인증번호가 인증 되지 않은 경우, 예외 발생 diff --git a/src/main/java/com/softeer/backend/global/common/constant/ValidationConstant.java b/src/main/java/com/softeer/backend/global/common/constant/ValidationConstant.java index 8e802a14..c823ea04 100644 --- a/src/main/java/com/softeer/backend/global/common/constant/ValidationConstant.java +++ b/src/main/java/com/softeer/backend/global/common/constant/ValidationConstant.java @@ -20,4 +20,7 @@ public class ValidationConstant { public static final String ADMIN_PASSWORD_REGEX = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@#$%^&*!])[A-Za-z\\d@#$%^&*!]{8,20}$"; public static final String ADMIN_PASSWORD_MSG = "잘못된 비밀번호 형식입니다."; + public static final String MIN_VALUE_MSG = "값은 최소 {value}이어야 합니다."; + public static final String MAX_VALUE_MSG = "값은 최대 {value}이어야 합니다."; + } diff --git a/src/main/java/com/softeer/backend/global/common/exception/ExceptionAdvice.java b/src/main/java/com/softeer/backend/global/common/exception/ExceptionAdvice.java index 279a4061..f0ebd1a2 100644 --- a/src/main/java/com/softeer/backend/global/common/exception/ExceptionAdvice.java +++ b/src/main/java/com/softeer/backend/global/common/exception/ExceptionAdvice.java @@ -17,9 +17,7 @@ import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Optional; +import java.util.*; /** @@ -56,12 +54,13 @@ public ResponseEntity handleEventLockException(EventLockException eventL */ @ExceptionHandler public ResponseEntity handleValidationException(ConstraintViolationException constraintViolationException, WebRequest request) { - String errorMessage = constraintViolationException.getConstraintViolations().stream() - .map(ConstraintViolation::getMessage) - .findFirst() - .orElseThrow(() -> new RuntimeException("ConstraintViolationException 추출 도중 에러 발생")); - return handleConstraintExceptionInternal(constraintViolationException, ErrorStatus.valueOf(errorMessage), HttpHeaders.EMPTY, request); + List errorMessages = constraintViolationException.getConstraintViolations().stream() + .map(violation -> Optional.ofNullable(violation.getMessage()).orElse("")) + .toList(); + + return handleConstraintExceptionInternal(constraintViolationException, ErrorStatus._VALIDATION_ERROR, HttpHeaders.EMPTY, request, + errorMessages); } /** @@ -157,10 +156,12 @@ private ResponseEntity handleEventLockExceptionInternal(EventLockExcepti // ConstraintViolationException에 대한 client 응답 객체를 생성하는 메서드 private ResponseEntity handleConstraintExceptionInternal(Exception e, ErrorStatus errorCommonStatus, - HttpHeaders headers, WebRequest request) { + HttpHeaders headers, WebRequest request, + List errorMessages) { + log.error("ConstraintViolationException captured in ExceptionAdvice", e); - ResponseDto body = ResponseDto.onFailure(errorCommonStatus.getCode(), errorCommonStatus.getMessage(), null); + ResponseDto body = ResponseDto.onFailure(errorCommonStatus.getCode(), errorCommonStatus.getMessage(), errorMessages); return super.handleExceptionInternal( e, body, diff --git a/src/main/java/com/softeer/backend/global/staticresources/constant/StaticText.java b/src/main/java/com/softeer/backend/global/staticresources/constant/StaticText.java new file mode 100644 index 00000000..7d474d3b --- /dev/null +++ b/src/main/java/com/softeer/backend/global/staticresources/constant/StaticText.java @@ -0,0 +1,89 @@ +package com.softeer.backend.global.staticresources.constant; + +public enum StaticText { + + EVENT_PERIOD("%s ~ %s"), + FCFS_INFO("매주 %s, %s %s %s시 선착순 %"), + FCFS_TITLE("'24시 내 차' 이벤트"), + FCFS_CONTENT("하단의 The new IONIQ 5 정보를 바탕으로 빠르게 문장 퀴즈를 맞춰\n" + + "24시간 렌트권과 신차 할인권을 얻을 수 있어요."), + + TOTAL_DRAW_WINNER("추첨 %s명"), + REMAIN_DRAW_COUNT("남은 경품 %s개"), + DRAW_TITLE("매일 복권 긁고 경품 받기"), + DRAW_CONTENT("이벤트 기간 동안 추첨을 통해 아이패드 pro 11인치, 현대백화점 10만원권, 1만원권을 드려요.\n" + + "일주일 연속 참여 시, 스타벅스 쿠폰을 무조건 받을 수 있어요."), + + MAIN_TITLE("The new IONIQ 5"), + MAIN_SUBTITLE("새롭게 돌아온 The new IONIQ 5를 소개합니다"), + + INTERIOR_TITLE("Interior"), + INTERIOR_SUBTITLE("내부 인테리어"), + INTERIOR_IMAGE_TITLE("Living Space"), + INTERIOR_IMAGE_CONTENT("편안한 거주 공간 (Living Space) 테마를 반영하여 더 넓은 실내 공간을 즐길 수 있도록 연출합니다."), + INTERIOR_OPENNESS_TITLE("개방감"), + INTERIOR_OPENNESS_SUBTITLE("개방감과 와이드한 이미지 제공"), + INTERIOR_OPENNESS_CONENT("심리스 스타일의 12.3인치 LCD 클러스터는 탁월한 개방감으로 즐거운 드라이빙 환경을 제공합니다.\n" + + "클러스터와 인포테인먼트 시스템에 일체형 커버글래스를 적용하여 와이드한 이미지를 제공합니다."), + + INTERIOR_WELLNESS_TITLE("웰니스"), + INTERIOR_WELLNESS_SUBTITLE("웰니스와 친환경"), + INTERIOR_WELLNESS_CONTENT("혼커버, 스위치, 스티어링 휠, 도어 등에 유채꽃과 옥수수에서 추출한 성분 약 10%가 함유된 바이오 페인트를 이용했습니다.\n" + + "시트와 도어 트림에는 재활용 투명 PET병을 재활용한 원사 약 20%의 섬유가 사용됐습니다."), + + PERFORMANCE_TITLE("Performance"), + PERFORMANCE_SUBTITLE("주행성능"), + PERFORMANCE_IMAGE_TITLE("Large Capacity Battery"), + PERFORMANCE_IMAGE_CONTENT("항속형 대용량 배터리를 적용하여 주행 가능 거리를 높였습니다."), + PERFORMANCE_BRAKING_TITLE("에너지 효율"), + PERFORMANCE_BRAKING_SUBTITLE("회생 제동 시스템"), + PERFORMANCE_BRAKING_CONENT("스티어링 휠의 패들쉬프트를 통해 회생제동 수준을 단계별로 조작할 수 있어\n" + + "브레이크 및 가족 페달 작동을 최소화하여 에너지 효율을 높일 수 있습니다."), + + PERFORMANCE_DRIVING_TITLE("주행성능"), + PERFORMANCE_DRIVING_SUBTITLE("주행 성능"), + PERFORMANCE_DRIVING_CONTENT("1회 충전 주행 가능 거리: 485km (2WD, 19인치, 빌트인 캠 미적용 기준)\n" + + "최고 출력 / 최대 토크: 239 kW (325 PS) / 605 Nm\n" + + "84.0 kWh 대용량 배터리를 장착하여 보다 여유 있는 장거리 주행이 가능합니다."), + + CHARGING_TITLE("Charging"), + CHARGING_SUBTITLE("급속 충전"), + CHARGING_IMAGE_TITLE("V2L/Charging"), + CHARGING_IMAGE_CONTENT("차량 외부로 전력을 공급할 수 있는 V2L 기능과 쉽고 빠르게 충전 관련 서비스는 사용자에게 새로운 경험을 제공합니다."), + CHARGING_FAST_TITLE("초급속 충전"), + CHARGING_FAST_SUBTITLE("18분 초급속 충전 경험"), + CHARGING_FAST_CONENT("400V/800V 멀티 급속 충전 시스템으로 다양한 충전 인프라를 사용할 수 있으며,\n" + + "급속 충전기(350kW) 사용 시 18분 이내에 배터리 용량의 10%에서 80%까지 충전이 가능합니다."), + + CHARGING_V2L_TITLE("실외/실내\n" + + "V2L"), + CHARGING_V2L_SUBTITLE("실외/실내 V2L"), + CHARGING_V2L_CONTENT("차량 외부에서도 실외 V2L 기능을 통해 다양한 전자기기 사용이 가능합니다.\n" + + "2열 시트 하단의 실내 V2L을 사용하여 차량 내부에서 배터리 걱정 없이 전자기기 사용이 가능합니다."), + + SAFE_TITLE("Safe, Convenient"), + SAFE_SUBTITLE("안전성과 편리함"), + SAFE_IMAGE_TITLE("Safe & Convenient Environment"), + SAFE_IMAGE_CONTENT("다양한 안전, 편의 기술로 편리하고 안전한 드라이빙 환경을 제공합니다."), + SAFE_DRIVING_TITLE("주행 안전"), + SAFE_DRIVING_SUBTITLE("도로 주행 중 안전"), + SAFE_DRIVING_CONENT("고속도로 및 자동차 전용도로 주행 시 도로 상황에 맞춰 안전한 속도로 주행하도록 도와주며,\n" + + "안전속도 구간, 곡선 구간, 진출입로 진입 전에 자동으로 속도를 줄이고 해당 구간을 지나면 원래 설정한 속도로 복귀합니다.\n" + + "일정 속도 이상으로 주행 시, 스티어링 휠을 잡은 상태에서 방향지시등 스위치를 변경하고자 하는 차로 방향으로 자동으로 움직입니다."), + + SAFE_ADVANCED_TITLE("후석 승객 알림"), + SAFE_ADVANCED_SUBTITLE("어드밴스드 후석 승객 알림"), + SAFE_ADVANCED_CONTENT("정밀한 레이더 센서가 실내의 승객을 감지하여, 운전자가 후석에 탑승한 유아를 인지하지 못하고 차를 떠나면\n" + + "알림을 주어 안전사고를 예방합니다."); + + + private final String text; + + StaticText(String text) { + this.text = text; + } + + public String format(Object... args) { + return String.format(text, args); + } +} diff --git a/src/main/java/com/softeer/backend/global/staticresources/domain/StaticResources.java b/src/main/java/com/softeer/backend/global/staticresources/domain/StaticResources.java new file mode 100644 index 00000000..5c36b4af --- /dev/null +++ b/src/main/java/com/softeer/backend/global/staticresources/domain/StaticResources.java @@ -0,0 +1,27 @@ +package com.softeer.backend.global.staticresources.domain; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Builder +@Table(name = "static_resources") +public class StaticResources { + + @Id + @Column(name = "static_resources_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column(name = "file_name", nullable = false) + private String fileName; + + @Column(name = "file_url", nullable = false) + private String fileUrl; +} diff --git a/src/main/java/com/softeer/backend/global/staticresources/repository/StaticResourcesRepository.java b/src/main/java/com/softeer/backend/global/staticresources/repository/StaticResourcesRepository.java new file mode 100644 index 00000000..57932b85 --- /dev/null +++ b/src/main/java/com/softeer/backend/global/staticresources/repository/StaticResourcesRepository.java @@ -0,0 +1,7 @@ +package com.softeer.backend.global.staticresources.repository; + +import com.softeer.backend.global.staticresources.domain.StaticResources; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface StaticResourcesRepository extends JpaRepository { +} diff --git a/src/main/java/com/softeer/backend/global/staticresources/util/StaticResourcesUtil.java b/src/main/java/com/softeer/backend/global/staticresources/util/StaticResourcesUtil.java new file mode 100644 index 00000000..3a9c2456 --- /dev/null +++ b/src/main/java/com/softeer/backend/global/staticresources/util/StaticResourcesUtil.java @@ -0,0 +1,43 @@ +package com.softeer.backend.global.staticresources.util; + +import com.softeer.backend.fo_domain.fcfs.domain.FcfsSetting; +import com.softeer.backend.global.staticresources.domain.StaticResources; +import com.softeer.backend.global.staticresources.repository.StaticResourcesRepository; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Component +@RequiredArgsConstructor +public class StaticResourcesUtil { + + private final StaticResourcesRepository staticResourcesRepository; + + private Map s3Urls; + + @PostConstruct + public void init() { + loadInitialData(); + } + + public void loadInitialData() { + List staticResourcesList = staticResourcesRepository.findAll(); + + s3Urls.putAll( + staticResourcesList.stream() + .collect(Collectors.toMap( + StaticResources::getFileName, // Key mapper + StaticResources::getFileUrl // Value mapper + )) + ); + } + + public String getFileUrl(String filename) { + return s3Urls.get(filename); + } +} From cf8557fd60ed9c573e64263d515af567bda82ad9 Mon Sep 17 00:00:00 2001 From: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Date: Sun, 11 Aug 2024 23:51:11 +0900 Subject: [PATCH 28/39] =?UTF-8?q?=08[Refactor]=20MainPageController=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EB=AA=85=20=EB=B3=80=EA=B2=BD=20(#7?= =?UTF-8?q?2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * refactor: transactional 어노테이션 수정 * refactor: 변수명 변경 * feat: MainPage 컨트롤러 클래스 생성 * feat: MainPage service 클래스 생성 * feat: StaticResources entity 클래스 생성 * feat: StaticResources repository 클래스 생성 * feat: StaticResourcesUtil 클래스 생성 * feat: 정적 text를 관리하는 enum 생성 * refactor: 변수명 변경 * refactor: 검증 애노테이션 추가 * refactor: DayOfWeek 속성 변경 * refactor: 예외 msg를 응답객체 result에 넣도록 변경 * refactor: 변수명 변경 * refactor: DayOfWeek 속성 변경 * refactor: 검증 애노테이션 추가 * refactor: 검증 상수 추가 * refactor: 변수 타입을 래퍼타입으로 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * feat: final 객체 초기화 --------- Co-authored-by: hyeokson --- .../bo_domain/admin/controller/AdminMainPageController.java | 6 +++--- .../{MainPageService.java => AdminMainPageService.java} | 2 +- .../global/staticresources/util/StaticResourcesUtil.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename src/main/java/com/softeer/backend/bo_domain/admin/service/{MainPageService.java => AdminMainPageService.java} (96%) diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminMainPageController.java b/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminMainPageController.java index 824b3b39..670014bf 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminMainPageController.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminMainPageController.java @@ -1,7 +1,7 @@ package com.softeer.backend.bo_domain.admin.controller; import com.softeer.backend.bo_domain.admin.dto.main.MainPageResponseDto; -import com.softeer.backend.bo_domain.admin.service.MainPageService; +import com.softeer.backend.bo_domain.admin.service.AdminMainPageService; import com.softeer.backend.global.common.response.ResponseDto; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; @@ -12,11 +12,11 @@ @RequiredArgsConstructor @RequestMapping("/admin") public class AdminMainPageController { - private final MainPageService mainPageService; + private final AdminMainPageService adminMainPageService; @GetMapping("/main") public ResponseDto getMainPage() { - MainPageResponseDto mainPageResponseDto = mainPageService.getMainPage(); + MainPageResponseDto mainPageResponseDto = adminMainPageService.getMainPage(); return ResponseDto.onSuccess(mainPageResponseDto); } diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/service/MainPageService.java b/src/main/java/com/softeer/backend/bo_domain/admin/service/AdminMainPageService.java similarity index 96% rename from src/main/java/com/softeer/backend/bo_domain/admin/service/MainPageService.java rename to src/main/java/com/softeer/backend/bo_domain/admin/service/AdminMainPageService.java index 5ddccb36..e78c484e 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/service/MainPageService.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/service/AdminMainPageService.java @@ -14,7 +14,7 @@ @Service @RequiredArgsConstructor -public class MainPageService { +public class AdminMainPageService { private final FcfsSettingRepository fcfsSettingRepository; private final DrawSettingRepository drawSettingRepository; diff --git a/src/main/java/com/softeer/backend/global/staticresources/util/StaticResourcesUtil.java b/src/main/java/com/softeer/backend/global/staticresources/util/StaticResourcesUtil.java index 3a9c2456..22705b8e 100644 --- a/src/main/java/com/softeer/backend/global/staticresources/util/StaticResourcesUtil.java +++ b/src/main/java/com/softeer/backend/global/staticresources/util/StaticResourcesUtil.java @@ -18,7 +18,7 @@ public class StaticResourcesUtil { private final StaticResourcesRepository staticResourcesRepository; - private Map s3Urls; + private final Map s3Urls = new HashMap<>(); @PostConstruct public void init() { From f26769fb258c89e9209a02b8e462249700ce29be Mon Sep 17 00:00:00 2001 From: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Date: Mon, 12 Aug 2024 02:53:15 +0900 Subject: [PATCH 29/39] =?UTF-8?q?[Feature]=20=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20GET=20API=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20(#73)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * refactor: transactional 어노테이션 수정 * refactor: 변수명 변경 * feat: MainPage 컨트롤러 클래스 생성 * feat: MainPage service 클래스 생성 * feat: StaticResources entity 클래스 생성 * feat: StaticResources repository 클래스 생성 * feat: StaticResourcesUtil 클래스 생성 * feat: 정적 text를 관리하는 enum 생성 * refactor: 변수명 변경 * refactor: 검증 애노테이션 추가 * refactor: DayOfWeek 속성 변경 * refactor: 예외 msg를 응답객체 result에 넣도록 변경 * refactor: 변수명 변경 * refactor: DayOfWeek 속성 변경 * refactor: 검증 애노테이션 추가 * refactor: 검증 상수 추가 * refactor: 변수 타입을 래퍼타입으로 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * feat: final 객체 초기화 * feat: 메인페이지 자동차 정적 정보 응답 dto 구현 * feat: 메인페이지 이벤트 정적 정보 응답 dto 구현 * refactor: 클래스 및 변수명 변경 * refactor: 클래스명 변경 * refactor: 클래스명 변경 * refactor: round 변수 삭제 * feat: 인증검사를 하지 않는 url 추가 * feat: 메인 페이지 컨트롤러 구현 * feat: 메인 페이지 service 클래스 구현 * feat: 정적자원util 클래스 초기화 메서드 구현 * refactor: enum 변수명 수정 * refactor: Fcfs 당첨자 수 수정 로직 변경 --------- Co-authored-by: hyeokson --- .../controller/AdminMainPageController.java | 8 +- ...Dto.java => AdminMainPageResponseDto.java} | 6 +- .../winner/FcfsWinnerUpdateRequestDto.java | 4 +- .../admin/service/AdminMainPageService.java | 6 +- .../admin/service/WinnerPageService.java | 8 +- .../controller/MainPageController.java | 27 +++ .../mainpage/dto/MainPageCarResponseDto.java | 69 ++++++++ .../dto/MainPageEventResponseDto.java | 54 ++++++ .../mainpage/service/MainPageService.java | 166 ++++++++++++++++++ .../filter/JwtAuthenticationFilter.java | 3 +- .../staticresources/constant/StaticText.java | 13 +- .../util/StaticResourcesUtil.java | 100 +++++++++-- 12 files changed, 429 insertions(+), 35 deletions(-) rename src/main/java/com/softeer/backend/bo_domain/admin/dto/main/{MainPageResponseDto.java => AdminMainPageResponseDto.java} (94%) create mode 100644 src/main/java/com/softeer/backend/fo_domain/mainpage/dto/MainPageCarResponseDto.java create mode 100644 src/main/java/com/softeer/backend/fo_domain/mainpage/dto/MainPageEventResponseDto.java diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminMainPageController.java b/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminMainPageController.java index 670014bf..da46374e 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminMainPageController.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminMainPageController.java @@ -1,6 +1,6 @@ package com.softeer.backend.bo_domain.admin.controller; -import com.softeer.backend.bo_domain.admin.dto.main.MainPageResponseDto; +import com.softeer.backend.bo_domain.admin.dto.main.AdminMainPageResponseDto; import com.softeer.backend.bo_domain.admin.service.AdminMainPageService; import com.softeer.backend.global.common.response.ResponseDto; import lombok.RequiredArgsConstructor; @@ -15,9 +15,9 @@ public class AdminMainPageController { private final AdminMainPageService adminMainPageService; @GetMapping("/main") - public ResponseDto getMainPage() { - MainPageResponseDto mainPageResponseDto = adminMainPageService.getMainPage(); + public ResponseDto getMainPage() { + AdminMainPageResponseDto adminMainPageResponseDto = adminMainPageService.getMainPage(); - return ResponseDto.onSuccess(mainPageResponseDto); + return ResponseDto.onSuccess(adminMainPageResponseDto); } } diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/dto/main/MainPageResponseDto.java b/src/main/java/com/softeer/backend/bo_domain/admin/dto/main/AdminMainPageResponseDto.java similarity index 94% rename from src/main/java/com/softeer/backend/bo_domain/admin/dto/main/MainPageResponseDto.java rename to src/main/java/com/softeer/backend/bo_domain/admin/dto/main/AdminMainPageResponseDto.java index 5f6874c5..3be65ded 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/dto/main/MainPageResponseDto.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/dto/main/AdminMainPageResponseDto.java @@ -17,7 +17,7 @@ @AllArgsConstructor(access = AccessLevel.PUBLIC) @Builder @Getter -public class MainPageResponseDto { +public class AdminMainPageResponseDto { public static final int EXPECTED_PARTICIPANT_COUNT = 10000; private List fcfsEventList; @@ -73,7 +73,7 @@ public static class DrawInfo { private double probability; } - public static MainPageResponseDto of(List fcfsSettingList, List drawSettingList) { + public static AdminMainPageResponseDto of(List fcfsSettingList, List drawSettingList) { List fcfsEventList = fcfsSettingList.stream() .map((fcfsSetting) -> FcfsEvent.builder() @@ -110,7 +110,7 @@ public static MainPageResponseDto of(List fcfsSettingList, List fcfsSettingList = fcfsSettingRepository.findAll(Sort.by(Sort.Order.asc("round"))); List drawSetting = drawSettingRepository.findAll(); - return MainPageResponseDto.of(fcfsSettingList, drawSetting); + return AdminMainPageResponseDto.of(fcfsSettingList, drawSetting); } } diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/service/WinnerPageService.java b/src/main/java/com/softeer/backend/bo_domain/admin/service/WinnerPageService.java index 2d911479..789420d0 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/service/WinnerPageService.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/service/WinnerPageService.java @@ -49,13 +49,9 @@ public DrawWinnerListResponseDto getDrawWinnerList(int rank) { @Transactional public void updateFcfsWinnerNum(FcfsWinnerUpdateRequestDto fcfsWinnerUpdateRequestDto) { - FcfsSetting fcfsSetting = fcfsSettingRepository.findByRound(fcfsWinnerUpdateRequestDto.getRound()) - .orElseThrow(() -> { - log.error("fcfsSetting not found"); - return new AdminException(ErrorStatus._NOT_FOUND); - }); + List fcfsSettingList = fcfsSettingRepository.findAll(); - fcfsSetting.setWinnerNum(fcfsWinnerUpdateRequestDto.getFcfsWinnerNum()); + fcfsSettingList.forEach((fcfsSetting) -> fcfsSetting.setWinnerNum(fcfsWinnerUpdateRequestDto.getFcfsWinnerNum())); } @Transactional diff --git a/src/main/java/com/softeer/backend/fo_domain/mainpage/controller/MainPageController.java b/src/main/java/com/softeer/backend/fo_domain/mainpage/controller/MainPageController.java index 33f4860c..f71a62b2 100644 --- a/src/main/java/com/softeer/backend/fo_domain/mainpage/controller/MainPageController.java +++ b/src/main/java/com/softeer/backend/fo_domain/mainpage/controller/MainPageController.java @@ -1,7 +1,34 @@ package com.softeer.backend.fo_domain.mainpage.controller; +import com.softeer.backend.fo_domain.mainpage.dto.MainPageCarResponseDto; +import com.softeer.backend.fo_domain.mainpage.dto.MainPageEventResponseDto; +import com.softeer.backend.fo_domain.mainpage.service.MainPageService; +import com.softeer.backend.global.common.response.ResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController +@RequiredArgsConstructor +@RequestMapping("/main") public class MainPageController { + + private final MainPageService mainPageService; + + @GetMapping("/event") + public ResponseDto getEventPage(){ + MainPageEventResponseDto mainPageEventResponseDto = mainPageService.getEventPage(); + + return ResponseDto.onSuccess(mainPageEventResponseDto); + } + + @GetMapping("/car") + public ResponseDto getCarPage(){ + + MainPageCarResponseDto mainPageCarResponseDto = mainPageService.getCarPage(); + + return ResponseDto.onSuccess(mainPageCarResponseDto); + } + } diff --git a/src/main/java/com/softeer/backend/fo_domain/mainpage/dto/MainPageCarResponseDto.java b/src/main/java/com/softeer/backend/fo_domain/mainpage/dto/MainPageCarResponseDto.java new file mode 100644 index 00000000..bf89cb56 --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/mainpage/dto/MainPageCarResponseDto.java @@ -0,0 +1,69 @@ +package com.softeer.backend.fo_domain.mainpage.dto; + +import lombok.*; + +import java.util.List; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PUBLIC) +@Builder +@Getter +public class MainPageCarResponseDto { + + private CarVideoInfo carVideoInfo; + + private List carInfoList; + + + @Getter + @AllArgsConstructor + @Builder + public static class CarVideoInfo{ + + private String title; + + private String subTitle; + + private String videoUrl; + + private String backgroundImgUrl; + } + + @Getter + @AllArgsConstructor + @Builder + public static class CarInfo{ + + private int id; + + private String title; + + private String subTitle; + + private String imgTitle; + + private String imgContent; + + private String imgUrl; + + private String backgroundImgUrl; + + private List carDetailInfoList; + } + + @Getter + @AllArgsConstructor + @Builder + public static class CarDetailInfo{ + + private int id; + + private String title; + + private String subTitle; + + private String content; + + private String imgUrl; + } +} diff --git a/src/main/java/com/softeer/backend/fo_domain/mainpage/dto/MainPageEventResponseDto.java b/src/main/java/com/softeer/backend/fo_domain/mainpage/dto/MainPageEventResponseDto.java new file mode 100644 index 00000000..46662d36 --- /dev/null +++ b/src/main/java/com/softeer/backend/fo_domain/mainpage/dto/MainPageEventResponseDto.java @@ -0,0 +1,54 @@ +package com.softeer.backend.fo_domain.mainpage.dto; + +import lombok.*; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PUBLIC) +@Builder +@Getter +public class MainPageEventResponseDto { + + private String eventPeriod; + + private FcfsInfo fcfsInfo; + + private DrawInfo drawInfo; + + @Getter + @AllArgsConstructor + @Builder + public static class FcfsInfo{ + + private String fcfsInfo; + + private String fcfsTitle; + + private String fcfsContent; + + private String fcfsRewardImage1; + + private String fcfsRewardImage2; + + } + + @Getter + @AllArgsConstructor + @Builder + public static class DrawInfo{ + + private String totalDrawWinner; + + private String remainDrawCount; + + private String drawTitle; + + private String drawContent; + + private String drawRewardImage1; + + private String drawRewardImage2; + + private String drawRewardImage3; + } + +} diff --git a/src/main/java/com/softeer/backend/fo_domain/mainpage/service/MainPageService.java b/src/main/java/com/softeer/backend/fo_domain/mainpage/service/MainPageService.java index 9fd0bbf9..fdc230de 100644 --- a/src/main/java/com/softeer/backend/fo_domain/mainpage/service/MainPageService.java +++ b/src/main/java/com/softeer/backend/fo_domain/mainpage/service/MainPageService.java @@ -1,4 +1,170 @@ package com.softeer.backend.fo_domain.mainpage.service; +import com.softeer.backend.fo_domain.mainpage.dto.MainPageCarResponseDto; +import com.softeer.backend.fo_domain.mainpage.dto.MainPageEventResponseDto; +import com.softeer.backend.global.staticresources.util.StaticResourcesUtil; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Arrays; + +@Service +@RequiredArgsConstructor public class MainPageService { + + private final StaticResourcesUtil staticResourcesUtil; + + public MainPageEventResponseDto getEventPage(){ + + MainPageEventResponseDto.FcfsInfo fcfsInfo = MainPageEventResponseDto.FcfsInfo.builder() + .fcfsInfo(staticResourcesUtil.getData("FCFS_INFO")) + .fcfsTitle(staticResourcesUtil.getData("FCFS_TITLE")) + .fcfsContent(staticResourcesUtil.getData("FCFS_CONTENT")) + .fcfsRewardImage1(staticResourcesUtil.getData("fcfs_reward_image_1")) + .fcfsRewardImage2(staticResourcesUtil.getData("fcfs_reward_image_2")) + .build(); + + MainPageEventResponseDto.DrawInfo drawInfo = MainPageEventResponseDto.DrawInfo.builder() + .totalDrawWinner(staticResourcesUtil.getData("TOTAL_DRAW_WINNER")) + .remainDrawCount(staticResourcesUtil.getData("REMAIN_DRAW_COUNT")) + .drawTitle(staticResourcesUtil.getData("DRAW_TITLE")) + .drawContent(staticResourcesUtil.getData("DRAW_CONTENT")) + .drawRewardImage1(staticResourcesUtil.getData("draw_reward_image_1")) + .drawRewardImage2(staticResourcesUtil.getData("draw_reward_image_2")) + .drawRewardImage3(staticResourcesUtil.getData("draw_reward_image_3")) + .build(); + + return MainPageEventResponseDto.builder() + .eventPeriod(staticResourcesUtil.getData("EVENT_PERIOD")) + .fcfsInfo(fcfsInfo) + .drawInfo(drawInfo) + .build(); + + } + + public MainPageCarResponseDto getCarPage(){ + + MainPageCarResponseDto.CarDetailInfo carDetailInfo1_1 = MainPageCarResponseDto.CarDetailInfo.builder() + .id(1) + .title(staticResourcesUtil.getData("INTERIOR_OPENNESS_TITLE")) + .subTitle(staticResourcesUtil.getData("INTERIOR_OPENNESS_SUBTITLE")) + .content(staticResourcesUtil.getData("INTERIOR_OPENNESS_CONTENT")) + .imgUrl(staticResourcesUtil.getData("interior_openness_image")) + .build(); + + MainPageCarResponseDto.CarDetailInfo carDetailInfo1_2 = MainPageCarResponseDto.CarDetailInfo.builder() + .id(2) + .title(staticResourcesUtil.getData("INTERIOR_WELLNESS_TITLE")) + .subTitle(staticResourcesUtil.getData("INTERIOR_WELLNESS_SUBTITLE")) + .content(staticResourcesUtil.getData("INTERIOR_WELLNESS_CONTENT")) + .imgUrl(staticResourcesUtil.getData("interior_wellness_image")) + .build(); + + MainPageCarResponseDto.CarInfo carInfo1 = MainPageCarResponseDto.CarInfo.builder() + .id(1) + .title(staticResourcesUtil.getData("INTERIOR_TITLE")) + .subTitle(staticResourcesUtil.getData("INTERIOR_SUBTITLE")) + .imgTitle(staticResourcesUtil.getData("INTERIOR_IMAGE_TITLE")) + .imgContent(staticResourcesUtil.getData("INTERIOR_IMAGE_CONTENT")) + .imgUrl(staticResourcesUtil.getData("interior_thumbnail_image")) + .backgroundImgUrl(staticResourcesUtil.getData("interior_background_image")) + .carDetailInfoList(Arrays.asList(carDetailInfo1_1, carDetailInfo1_2)) + .build(); + + MainPageCarResponseDto.CarDetailInfo carDetailInfo2_1 = MainPageCarResponseDto.CarDetailInfo.builder() + .id(1) + .title(staticResourcesUtil.getData("PERFORMANCE_BRAKING_TITLE")) + .subTitle(staticResourcesUtil.getData("PERFORMANCE_BRAKING_SUBTITLE")) + .content(staticResourcesUtil.getData("PERFORMANCE_BRAKING_CONTENT")) + .imgUrl(staticResourcesUtil.getData("performance_braking_image")) + .build(); + + MainPageCarResponseDto.CarDetailInfo carDetailInfo2_2 = MainPageCarResponseDto.CarDetailInfo.builder() + .id(2) + .title(staticResourcesUtil.getData("PERFORMANCE_DRIVING_TITLE")) + .subTitle(staticResourcesUtil.getData("PERFORMANCE_DRIVING_SUBTITLE")) + .content(staticResourcesUtil.getData("PERFORMANCE_DRIVING_CONTENT")) + .imgUrl(staticResourcesUtil.getData("performance_driving_image")) + .build(); + + MainPageCarResponseDto.CarInfo carInfo2 = MainPageCarResponseDto.CarInfo.builder() + .id(2) + .title(staticResourcesUtil.getData("PERFORMANCE_TITLE")) + .subTitle(staticResourcesUtil.getData("PERFORMANCE_SUBTITLE")) + .imgTitle(staticResourcesUtil.getData("PERFORMANCE_IMAGE_TITLE")) + .imgContent(staticResourcesUtil.getData("PERFORMANCE_IMAGE_CONTENT")) + .imgUrl(staticResourcesUtil.getData("performance_thumbnail_image")) + .backgroundImgUrl(staticResourcesUtil.getData("performance_background_image")) + .carDetailInfoList(Arrays.asList(carDetailInfo2_1, carDetailInfo2_2)) + .build(); + + MainPageCarResponseDto.CarDetailInfo carDetailInfo3_1 = MainPageCarResponseDto.CarDetailInfo.builder() + .id(1) + .title(staticResourcesUtil.getData("CHARGING_FAST_TITLE")) + .subTitle(staticResourcesUtil.getData("CHARGING_FAST_SUBTITLE")) + .content(staticResourcesUtil.getData("CHARGING_FAST_CONTENT")) + .imgUrl(staticResourcesUtil.getData("charging_fast_image")) + .build(); + + MainPageCarResponseDto.CarDetailInfo carDetailInfo3_2 = MainPageCarResponseDto.CarDetailInfo.builder() + .id(2) + .title(staticResourcesUtil.getData("CHARGING_V2L_TITLE")) + .subTitle(staticResourcesUtil.getData("CHARGING_V2L_SUBTITLE")) + .content(staticResourcesUtil.getData("CHARGING_V2L_CONTENT")) + .imgUrl(staticResourcesUtil.getData("charging_v2l_image")) + .build(); + + MainPageCarResponseDto.CarInfo carInfo3 = MainPageCarResponseDto.CarInfo.builder() + .id(3) + .title(staticResourcesUtil.getData("CHARGING_TITLE")) + .subTitle(staticResourcesUtil.getData("CHARGING_SUBTITLE")) + .imgTitle(staticResourcesUtil.getData("CHARGING_IMAGE_TITLE")) + .imgContent(staticResourcesUtil.getData("CHARGING_IMAGE_CONTENT")) + .imgUrl(staticResourcesUtil.getData("charging_thumbnail_image")) + .backgroundImgUrl(staticResourcesUtil.getData("charging_background_image")) + .carDetailInfoList(Arrays.asList(carDetailInfo3_1, carDetailInfo3_2)) + .build(); + + MainPageCarResponseDto.CarDetailInfo carDetailInfo4_1 = MainPageCarResponseDto.CarDetailInfo.builder() + .id(1) + .title(staticResourcesUtil.getData("SAFE_DRIVING_TITLE")) + .subTitle(staticResourcesUtil.getData("SAFE_DRIVING_SUBTITLE")) + .content(staticResourcesUtil.getData("SAFE_DRIVING_CONTENT")) + .imgUrl(staticResourcesUtil.getData("safe_driving_image")) + .build(); + + MainPageCarResponseDto.CarDetailInfo carDetailInfo4_2 = MainPageCarResponseDto.CarDetailInfo.builder() + .id(2) + .title(staticResourcesUtil.getData("SAFE_ADVANCED_TITLE")) + .subTitle(staticResourcesUtil.getData("SAFE_ADVANCED_SUBTITLE")) + .content(staticResourcesUtil.getData("SAFE_ADVANCED_CONTENT")) + .imgUrl(staticResourcesUtil.getData("safe_advanced_image")) + .build(); + + MainPageCarResponseDto.CarInfo carInfo4 = MainPageCarResponseDto.CarInfo.builder() + .id(4) + .title(staticResourcesUtil.getData("SAFE_TITLE")) + .subTitle(staticResourcesUtil.getData("SAFE_SUBTITLE")) + .imgTitle(staticResourcesUtil.getData("SAFE_IMAGE_TITLE")) + .imgContent(staticResourcesUtil.getData("SAFE_IMAGE_CONTENT")) + .imgUrl(staticResourcesUtil.getData("safe_thumbnail_image")) + .backgroundImgUrl(staticResourcesUtil.getData("safe_background_image")) + .carDetailInfoList(Arrays.asList(carDetailInfo4_1, carDetailInfo4_2)) + .build(); + + + + + MainPageCarResponseDto.CarVideoInfo carVideoInfo = MainPageCarResponseDto.CarVideoInfo.builder() + .title(staticResourcesUtil.getData("MAIN_TITLE")) + .subTitle(staticResourcesUtil.getData("MAIN_SUBTITLE")) + .videoUrl(staticResourcesUtil.getData("ioniq_video")) + .backgroundImgUrl(staticResourcesUtil.getData("main_background_image")) + .build(); + + return MainPageCarResponseDto.builder() + .carVideoInfo(carVideoInfo) + .carInfoList(Arrays.asList(carInfo1, carInfo2, carInfo3, carInfo4)) + .build(); + } } diff --git a/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java b/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java index 20c41801..cff2d6c3 100644 --- a/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java +++ b/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java @@ -36,7 +36,8 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { private final String[] whiteListUrls = { "/swagger-ui/**", "/swagger", "/error/**", "/verification/send", "/verification/confirm", - "/login" + "/login", + "/main/event", "/main/car" }; // Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 diff --git a/src/main/java/com/softeer/backend/global/staticresources/constant/StaticText.java b/src/main/java/com/softeer/backend/global/staticresources/constant/StaticText.java index 7d474d3b..7fadd73e 100644 --- a/src/main/java/com/softeer/backend/global/staticresources/constant/StaticText.java +++ b/src/main/java/com/softeer/backend/global/staticresources/constant/StaticText.java @@ -1,9 +1,12 @@ package com.softeer.backend.global.staticresources.constant; +import lombok.Getter; + +@Getter public enum StaticText { EVENT_PERIOD("%s ~ %s"), - FCFS_INFO("매주 %s, %s %s %s시 선착순 %"), + FCFS_INFO("매주 %s, %s %s시 선착순 %s명"), FCFS_TITLE("'24시 내 차' 이벤트"), FCFS_CONTENT("하단의 The new IONIQ 5 정보를 바탕으로 빠르게 문장 퀴즈를 맞춰\n" + "24시간 렌트권과 신차 할인권을 얻을 수 있어요."), @@ -23,7 +26,7 @@ public enum StaticText { INTERIOR_IMAGE_CONTENT("편안한 거주 공간 (Living Space) 테마를 반영하여 더 넓은 실내 공간을 즐길 수 있도록 연출합니다."), INTERIOR_OPENNESS_TITLE("개방감"), INTERIOR_OPENNESS_SUBTITLE("개방감과 와이드한 이미지 제공"), - INTERIOR_OPENNESS_CONENT("심리스 스타일의 12.3인치 LCD 클러스터는 탁월한 개방감으로 즐거운 드라이빙 환경을 제공합니다.\n" + + INTERIOR_OPENNESS_CONTENT("심리스 스타일의 12.3인치 LCD 클러스터는 탁월한 개방감으로 즐거운 드라이빙 환경을 제공합니다.\n" + "클러스터와 인포테인먼트 시스템에 일체형 커버글래스를 적용하여 와이드한 이미지를 제공합니다."), INTERIOR_WELLNESS_TITLE("웰니스"), @@ -37,7 +40,7 @@ public enum StaticText { PERFORMANCE_IMAGE_CONTENT("항속형 대용량 배터리를 적용하여 주행 가능 거리를 높였습니다."), PERFORMANCE_BRAKING_TITLE("에너지 효율"), PERFORMANCE_BRAKING_SUBTITLE("회생 제동 시스템"), - PERFORMANCE_BRAKING_CONENT("스티어링 휠의 패들쉬프트를 통해 회생제동 수준을 단계별로 조작할 수 있어\n" + + PERFORMANCE_BRAKING_CONTENT("스티어링 휠의 패들쉬프트를 통해 회생제동 수준을 단계별로 조작할 수 있어\n" + "브레이크 및 가족 페달 작동을 최소화하여 에너지 효율을 높일 수 있습니다."), PERFORMANCE_DRIVING_TITLE("주행성능"), @@ -52,7 +55,7 @@ public enum StaticText { CHARGING_IMAGE_CONTENT("차량 외부로 전력을 공급할 수 있는 V2L 기능과 쉽고 빠르게 충전 관련 서비스는 사용자에게 새로운 경험을 제공합니다."), CHARGING_FAST_TITLE("초급속 충전"), CHARGING_FAST_SUBTITLE("18분 초급속 충전 경험"), - CHARGING_FAST_CONENT("400V/800V 멀티 급속 충전 시스템으로 다양한 충전 인프라를 사용할 수 있으며,\n" + + CHARGING_FAST_CONTENT("400V/800V 멀티 급속 충전 시스템으로 다양한 충전 인프라를 사용할 수 있으며,\n" + "급속 충전기(350kW) 사용 시 18분 이내에 배터리 용량의 10%에서 80%까지 충전이 가능합니다."), CHARGING_V2L_TITLE("실외/실내\n" + @@ -67,7 +70,7 @@ public enum StaticText { SAFE_IMAGE_CONTENT("다양한 안전, 편의 기술로 편리하고 안전한 드라이빙 환경을 제공합니다."), SAFE_DRIVING_TITLE("주행 안전"), SAFE_DRIVING_SUBTITLE("도로 주행 중 안전"), - SAFE_DRIVING_CONENT("고속도로 및 자동차 전용도로 주행 시 도로 상황에 맞춰 안전한 속도로 주행하도록 도와주며,\n" + + SAFE_DRIVING_CONTENT("고속도로 및 자동차 전용도로 주행 시 도로 상황에 맞춰 안전한 속도로 주행하도록 도와주며,\n" + "안전속도 구간, 곡선 구간, 진출입로 진입 전에 자동으로 속도를 줄이고 해당 구간을 지나면 원래 설정한 속도로 복귀합니다.\n" + "일정 속도 이상으로 주행 시, 스티어링 휠을 잡은 상태에서 방향지시등 스위치를 변경하고자 하는 차로 방향으로 자동으로 움직입니다."), diff --git a/src/main/java/com/softeer/backend/global/staticresources/util/StaticResourcesUtil.java b/src/main/java/com/softeer/backend/global/staticresources/util/StaticResourcesUtil.java index 22705b8e..13137baa 100644 --- a/src/main/java/com/softeer/backend/global/staticresources/util/StaticResourcesUtil.java +++ b/src/main/java/com/softeer/backend/global/staticresources/util/StaticResourcesUtil.java @@ -1,24 +1,43 @@ package com.softeer.backend.global.staticresources.util; +import com.softeer.backend.fo_domain.draw.domain.DrawSetting; +import com.softeer.backend.fo_domain.draw.repository.DrawRepository; +import com.softeer.backend.fo_domain.draw.repository.DrawSettingRepository; +import com.softeer.backend.fo_domain.draw.service.DrawSettingManager; import com.softeer.backend.fo_domain.fcfs.domain.FcfsSetting; +import com.softeer.backend.fo_domain.fcfs.repository.FcfsSettingRepository; +import com.softeer.backend.fo_domain.fcfs.service.FcfsSettingManager; +import com.softeer.backend.global.common.code.status.ErrorStatus; +import com.softeer.backend.global.common.exception.GeneralException; +import com.softeer.backend.global.staticresources.constant.StaticText; import com.softeer.backend.global.staticresources.domain.StaticResources; import com.softeer.backend.global.staticresources.repository.StaticResourcesRepository; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.text.DecimalFormat; +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.*; import java.util.stream.Collectors; +@Slf4j @Component @RequiredArgsConstructor public class StaticResourcesUtil { + private final DateTimeFormatter eventTimeFormatter = DateTimeFormatter.ofPattern("yyyy.MM.dd"); + private final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("a h", Locale.KOREAN); + private final DecimalFormat decimalFormat = new DecimalFormat("#,###"); private final StaticResourcesRepository staticResourcesRepository; - - private final Map s3Urls = new HashMap<>(); + private final DrawSettingRepository drawSettingRepository; + private final FcfsSettingRepository fcfsSettingRepository; + private final DrawRepository drawRepository; + + private final Map staticResourcesMap = new HashMap<>(); @PostConstruct public void init() { @@ -28,16 +47,77 @@ public void init() { public void loadInitialData() { List staticResourcesList = staticResourcesRepository.findAll(); - s3Urls.putAll( + staticResourcesMap.putAll( staticResourcesList.stream() .collect(Collectors.toMap( - StaticResources::getFileName, // Key mapper - StaticResources::getFileUrl // Value mapper + StaticResources::getFileName, + StaticResources::getFileUrl )) ); + + DrawSetting drawSetting = drawSettingRepository.findAll().get(0); + + List fcfsSettingList = fcfsSettingRepository.findAll(); + FcfsSetting firstFcfsSetting = fcfsSettingList.get(0); + FcfsSetting secondFcfsSetting = fcfsSettingList.get(1); + + int totalDrawWinner = drawSetting.getWinnerNum1() + + drawSetting.getWinnerNum2() + drawSetting.getWinnerNum3(); + int remainDrawCount = totalDrawWinner - (int)drawRepository.count(); + + Map formattedTexts = Arrays.stream(StaticText.values()) + .collect(Collectors.toMap( + Enum::name, + enumValue -> { + switch (enumValue) { + case EVENT_PERIOD: + + return enumValue.format(drawSetting.getStartDate().format(eventTimeFormatter), + drawSetting.getEndDate().format(eventTimeFormatter)); + + case FCFS_INFO: + + return enumValue.format(getKoreanDayOfWeek(firstFcfsSetting.getStartTime().getDayOfWeek()), + getKoreanDayOfWeek(secondFcfsSetting.getStartTime().getDayOfWeek()), + firstFcfsSetting.getStartTime().format(timeFormatter), + firstFcfsSetting.getWinnerNum()); + case TOTAL_DRAW_WINNER: + return enumValue.format(decimalFormat.format(totalDrawWinner)); + case REMAIN_DRAW_COUNT: + return enumValue.format(decimalFormat.format(remainDrawCount)); + + default: + return enumValue.getText(); + } + } + )); + + staticResourcesMap.putAll(formattedTexts); + } + + private static String getKoreanDayOfWeek(DayOfWeek dayOfWeek) { + switch (dayOfWeek) { + case MONDAY: + return "월"; + case TUESDAY: + return "화"; + case WEDNESDAY: + return "수"; + case THURSDAY: + return "목"; + case FRIDAY: + return "금"; + case SATURDAY: + return "토"; + case SUNDAY: + return "일"; + default: + log.error("Korean day of week is not supported"); + throw new GeneralException(ErrorStatus._INTERNAL_SERVER_ERROR); + } } - public String getFileUrl(String filename) { - return s3Urls.get(filename); + public String getData(String resourceKey) { + return staticResourcesMap.get(resourceKey); } } From 298efefad80bbe0acab5668923e9dcbbc213d9bf Mon Sep 17 00:00:00 2001 From: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Date: Mon, 12 Aug 2024 04:10:00 +0900 Subject: [PATCH 30/39] =?UTF-8?q?[Feature]=20=EC=96=B4=EB=93=9C=EB=AF=BC?= =?UTF-8?q?=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#75)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: 어드민 회원가입 요청 dto 구현 * feat: swagger controller 구현 * feat: 어드민 회원가입 controller 메서드 구현 * feat: 어드민 로그인 요청 dto 수정 * feat: 어드민 회원가입 기능 구현 * feat: 메서드 추가 - 특정 account에 대한 데이터가 admin 저장소에 있는지 확인하는 메서드 구현 * feat: swagger, admin url 추가 * feat: swagger 서버 주소 변경 * feat: cors 설정 --------- Co-authored-by: hyeokson --- .../admin/controller/AdminLoginController.java | 9 +++++++++ .../admin/dto/login/AdminLoginRequestDto.java | 7 +++---- .../admin/dto/login/AdminSignUpRequestDto.java | 18 ++++++++++++++++++ .../admin/repository/AdminRepository.java | 2 ++ .../admin/service/AdminLoginService.java | 15 +++++++++++++++ .../common/swagger/SwaggerController.java | 13 +++++++++++++ .../global/config/docs/SwaggerConfig.java | 10 +++++----- .../global/config/web/WebMvcConfig.java | 2 +- .../global/filter/JwtAuthenticationFilter.java | 5 +++-- 9 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/softeer/backend/bo_domain/admin/dto/login/AdminSignUpRequestDto.java create mode 100644 src/main/java/com/softeer/backend/global/common/swagger/SwaggerController.java diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminLoginController.java b/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminLoginController.java index 08d04de1..6ac11892 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminLoginController.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/controller/AdminLoginController.java @@ -1,6 +1,7 @@ package com.softeer.backend.bo_domain.admin.controller; import com.softeer.backend.bo_domain.admin.dto.login.AdminLoginRequestDto; +import com.softeer.backend.bo_domain.admin.dto.login.AdminSignUpRequestDto; import com.softeer.backend.bo_domain.admin.service.AdminLoginService; import com.softeer.backend.global.annotation.AuthInfo; import com.softeer.backend.global.common.dto.JwtTokenResponseDto; @@ -33,5 +34,13 @@ ResponseDto handleLogout(@AuthInfo Integer adminId) { return ResponseDto.onSuccess(); } + @PostMapping("/signup") + ResponseDto handleSignUp(@Valid @RequestBody AdminSignUpRequestDto adminSignUpRequestDto) { + + adminLoginService.handleSignUp(adminSignUpRequestDto); + + return ResponseDto.onSuccess(); + } + } diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/dto/login/AdminLoginRequestDto.java b/src/main/java/com/softeer/backend/bo_domain/admin/dto/login/AdminLoginRequestDto.java index 0f87a9f6..96f4cbf6 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/dto/login/AdminLoginRequestDto.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/dto/login/AdminLoginRequestDto.java @@ -1,6 +1,7 @@ package com.softeer.backend.bo_domain.admin.dto.login; import com.softeer.backend.global.common.constant.ValidationConstant; +import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; import lombok.*; @@ -10,11 +11,9 @@ @Getter public class AdminLoginRequestDto { - @Pattern(regexp = ValidationConstant.ADMIN_ACCOUNT_REGEX, - message = ValidationConstant.ADMIN_ACCOUNT_MSG) + @NotNull private String account; - @Pattern(regexp = ValidationConstant.ADMIN_PASSWORD_REGEX, - message = ValidationConstant.ADMIN_PASSWORD_MSG) + @NotNull private String password; } diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/dto/login/AdminSignUpRequestDto.java b/src/main/java/com/softeer/backend/bo_domain/admin/dto/login/AdminSignUpRequestDto.java new file mode 100644 index 00000000..c8ec7ea6 --- /dev/null +++ b/src/main/java/com/softeer/backend/bo_domain/admin/dto/login/AdminSignUpRequestDto.java @@ -0,0 +1,18 @@ +package com.softeer.backend.bo_domain.admin.dto.login; + +import jakarta.validation.constraints.NotNull; +import lombok.*; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PUBLIC) +@Builder +@Getter +public class AdminSignUpRequestDto { + + @NotNull + private String account; + + @NotNull + private String password; + +} diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/repository/AdminRepository.java b/src/main/java/com/softeer/backend/bo_domain/admin/repository/AdminRepository.java index b0bfb7d8..6a9cbca7 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/repository/AdminRepository.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/repository/AdminRepository.java @@ -9,4 +9,6 @@ @Repository public interface AdminRepository extends JpaRepository { Optional findByAccount(String account); + + boolean existsByAccount(String account); } diff --git a/src/main/java/com/softeer/backend/bo_domain/admin/service/AdminLoginService.java b/src/main/java/com/softeer/backend/bo_domain/admin/service/AdminLoginService.java index fde81f89..c0679b38 100644 --- a/src/main/java/com/softeer/backend/bo_domain/admin/service/AdminLoginService.java +++ b/src/main/java/com/softeer/backend/bo_domain/admin/service/AdminLoginService.java @@ -2,6 +2,7 @@ import com.softeer.backend.bo_domain.admin.domain.Admin; import com.softeer.backend.bo_domain.admin.dto.login.AdminLoginRequestDto; +import com.softeer.backend.bo_domain.admin.dto.login.AdminSignUpRequestDto; import com.softeer.backend.bo_domain.admin.exception.AdminException; import com.softeer.backend.bo_domain.admin.repository.AdminRepository; import com.softeer.backend.bo_domain.admin.util.PasswordEncoder; @@ -54,4 +55,18 @@ public void handleLogout(int adminId) { .roleType(RoleType.ROLE_ADMIN) .build()); } + + @Transactional + public void handleSignUp(AdminSignUpRequestDto adminSignUpRequestDto) { + + if(adminRepository.existsByAccount(adminSignUpRequestDto.getAccount())){ + log.error("Admin account already exist."); + throw new AdminException(ErrorStatus._BAD_REQUEST); + } + + adminRepository.save(Admin.builder() + .account(adminSignUpRequestDto.getAccount()) + .password(passwordEncoder.encode(adminSignUpRequestDto.getPassword())) + .build()); + } } diff --git a/src/main/java/com/softeer/backend/global/common/swagger/SwaggerController.java b/src/main/java/com/softeer/backend/global/common/swagger/SwaggerController.java new file mode 100644 index 00000000..7cfbbc3b --- /dev/null +++ b/src/main/java/com/softeer/backend/global/common/swagger/SwaggerController.java @@ -0,0 +1,13 @@ +package com.softeer.backend.global.common.swagger; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class SwaggerController { + + @RequestMapping("/swagger") + public String getRedirectUrl() { + return "redirect:swagger-ui/index.html"; + } +} diff --git a/src/main/java/com/softeer/backend/global/config/docs/SwaggerConfig.java b/src/main/java/com/softeer/backend/global/config/docs/SwaggerConfig.java index 98676316..3b3192e4 100644 --- a/src/main/java/com/softeer/backend/global/config/docs/SwaggerConfig.java +++ b/src/main/java/com/softeer/backend/global/config/docs/SwaggerConfig.java @@ -21,7 +21,7 @@ description = "T라미숙해 api명세", version = "v1"), servers = { - @Server(url = "https://vec-to.net"), + @Server(url = "https://softeer.shop"), @Server(url = "http://localhost:5000") } ) @@ -44,11 +44,11 @@ public GroupedOpenApi chatOpenApi() { @Bean public OpenAPI getOpenApi() { Components components = new Components() - .addSecuritySchemes("bearerAuth", getJwtSecurityScheme()) - .addSecuritySchemes("refreshAuth", getJwtRefreshSecurityScheme()); + .addSecuritySchemes("AccessToken", getJwtSecurityScheme()) + .addSecuritySchemes("RefreshToken", getJwtRefreshSecurityScheme()); SecurityRequirement securityItem = new SecurityRequirement() - .addList("bearerAuth") - .addList("refreshAuth"); + .addList("AccessToken") + .addList("RefreshToken"); return new OpenAPI() .components(components) diff --git a/src/main/java/com/softeer/backend/global/config/web/WebMvcConfig.java b/src/main/java/com/softeer/backend/global/config/web/WebMvcConfig.java index aebbbd41..526f3e2a 100644 --- a/src/main/java/com/softeer/backend/global/config/web/WebMvcConfig.java +++ b/src/main/java/com/softeer/backend/global/config/web/WebMvcConfig.java @@ -48,7 +48,7 @@ public void addArgumentResolvers(List resolvers) public void addCorsMappings(CorsRegistry registry) { // TODO: Origin 도메인 수정 및 헤더값 설정 registry.addMapping("/**") - .allowedOrigins("https://softeer.site", "http://localhost:5173") // 허용할 도메인 설정 + .allowedOrigins("https://softeer.site", "http://localhost:5173", "https://softeer.shop") // 허용할 도메인 설정 .allowedMethods("OPTIONS", "GET", "POST", "PUT", "DELETE") // 허용할 HTTP 메서드 설정 .allowedHeaders("Content-Type", "Authorization", "Authorization-Refresh") // 허용할 헤더 설정 .exposedHeaders("Authorization", "Authorization-Refresh") // 클라이언트에 노출할 헤더 설정 diff --git a/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java b/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java index cff2d6c3..845d61ef 100644 --- a/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java +++ b/src/main/java/com/softeer/backend/global/filter/JwtAuthenticationFilter.java @@ -34,10 +34,11 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { // 인증검사를 하지 않는 url 설정 private final String[] whiteListUrls = { - "/swagger-ui/**", "/swagger", "/error/**", + "/swagger-ui/**", "/swagger", "/v3/**", "/error/**", "/verification/send", "/verification/confirm", "/login", - "/main/event", "/main/car" + "/main/event", "/main/car", + "/admin/login", "/admin/signup" }; // Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 From 315b0a60378b6be9e3dc361a87d573574270bbb5 Mon Sep 17 00:00:00 2001 From: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Date: Mon, 12 Aug 2024 04:27:42 +0900 Subject: [PATCH 31/39] =?UTF-8?q?[Feature]=20=ED=8A=B9=EC=A0=95=20url?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=B4=20=EC=9D=B8=EA=B0=80=20=EA=B2=80?= =?UTF-8?q?=EC=82=AC=20=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#76)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: 어드민 회원가입 요청 dto 구현 * feat: swagger controller 구현 * feat: 어드민 회원가입 controller 메서드 구현 * feat: 어드민 로그인 요청 dto 수정 * feat: 어드민 회원가입 기능 구현 * feat: 메서드 추가 - 특정 account에 대한 데이터가 admin 저장소에 있는지 확인하는 메서드 구현 * feat: swagger, admin url 추가 * feat: swagger 서버 주소 변경 * feat: cors 설정 * feat: 특정 url에 대해서 인가 검사 하지 않도록 구현 --------- Co-authored-by: hyeokson --- .../global/filter/JwtAuthorizationFilter.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/com/softeer/backend/global/filter/JwtAuthorizationFilter.java b/src/main/java/com/softeer/backend/global/filter/JwtAuthorizationFilter.java index 76850168..0f35d2dd 100644 --- a/src/main/java/com/softeer/backend/global/filter/JwtAuthorizationFilter.java +++ b/src/main/java/com/softeer/backend/global/filter/JwtAuthorizationFilter.java @@ -10,6 +10,8 @@ import jakarta.servlet.http.HttpServletResponse; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.util.PatternMatchUtils; +import org.springframework.web.cors.CorsUtils; import org.springframework.web.filter.OncePerRequestFilter; import java.io.IOException; @@ -20,9 +22,21 @@ @Slf4j @NoArgsConstructor public class JwtAuthorizationFilter extends OncePerRequestFilter { + + // 인가검사를 하지 않는 url 설정 + private final String[] whiteListUrls = { + "/admin/login", "/admin/signup" + }; + @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + if(CorsUtils.isPreFlightRequest(request) || isUriInWhiteList(request.getRequestURI())){ + filterChain.doFilter(request, response); + return; + } + + JwtClaimsDto jwtClaimsDto = (JwtClaimsDto) request.getAttribute("jwtClaims"); if (jwtClaimsDto == null || jwtClaimsDto.getRoleType() != RoleType.ROLE_ADMIN) { @@ -34,4 +48,8 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse filterChain.doFilter(request, response); } + private boolean isUriInWhiteList(String url) { + return PatternMatchUtils.simpleMatch(whiteListUrls, url); + } + } From 8675b995806c7771af4132d135c2940c13fa0713 Mon Sep 17 00:00:00 2001 From: DrRivaski <48974215+DrRivaski@users.noreply.github.com> Date: Sun, 11 Aug 2024 21:36:23 +0900 Subject: [PATCH 32/39] =?UTF-8?q?[Refactor]=20=EA=B3=B5=EC=9C=A0=20url=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=ED=95=98=EB=8A=94=20api=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20(#70)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * infra: 빌드 테스트 yml 작성 * infra: DB 정보 추가 * infra: ssh-agent 버전 변경 * infra: known_hosts 추가 * infra: db port 변경 * infra: database test 설정 변경 * infra: DB 환경변수 설정 및 application.yml 생성 * infra: application.yml 동적 생성 스크립트 수정 * infra: 레디스 설정 추가 * infra: redis test 추가 * infra: redis 버전 변경 * infra: redis cli 설치 * infra: application.yml 위치 및 내용 확인 * infra: Github Actions 환경변수에 REDIS_HOST, REDIS_PORT 추가 * infra: 환경변수 확인 추가 * feat: draw_rank column 이름 수정 * infra: pull_request시 Github Actions 동작하도록 수정 * cicd test (#54) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test --------- Co-authored-by: hyeokson * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson * cicd test (#58) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * chore: ci/cd를 위한 커밋 --------- Co-authored-by: hyeokson * refactor: 공유 url 조회하는 레포지토리 변경 - ShareInfoRepository -> ShareUrlInfoRepository * refactor: 잘못 작성된 메서드 삭제 - findSharedUrlByUserId 삭제 * refactor: 사용되지 않는 shareInfoRepository 삭제 * refactor: 변수명 변경 - sharedUrl -> shareUrl * [Feat] 성공, 실패 상태 코드 수정하기 (#65) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: cors 도메인 설정 * refactor: 커스텀 코드 형식 수정 및 에러코드 수정 - '(에러를 구분하는 알파벳)3자리 숫자' 형태로 커스텀 에러 코드 관리 - 클라이언트에서 에러 코드에 의해 분기되지 않으면 하나의 에러로 관리하도록 변경 * refactor: 하나의 성공 코드로 관리하도록 변경 * rebase: 원본 develop 브랜치와 rebase * rebase: 원본 develop 브랜치 rebase * feat: cors 설정에 localhost 추가 * refactor: 함수명 변경 * refactor: 예외 코드 변경 --------- Co-authored-by: hyeokson * [Feat]Admin Api 구현 (#67) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: Admin entity 클래스 생성 * feat: Admin exception 클래스 생성 * feat: Admin 로그인 컨트롤러 구현 * feat: Admin 로그인 요청 dto 구현 * feat: Admin 로그인 서비스 클래스 구현 * feat: Admin repository 구현 * feat: 추첨 이벤트 시간 설정 요청 dto 구현 * feat: 추첨 시간 검증 클래스 구현 * feat: 추첨 당첨자 응답 dto 구현 * feat: 추첨 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 응답 dto 구현 * feat: 이벤트 페이지 컨트롤러 구현 * feat: 이벤트 페이지 service 클래스 구현 * feat: 선착순 날짜 검증 클래스 구현 * feat: 선착순 날짜 등록 요청 dto 구현 * feat: 선착순 시간 검증 클래스 구현 * feat: 선착순 당첨자 응답 dto 구현 * feat: 선착순 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 컨트롤러 클래스 구현 * feat: 이벤트 지표 service 클래스 구현 * feat: 메인 페이지 관련 컨트롤러 클래스 구현 * feat: 메인 페이지 응답 dto 구현 * feat: 메인 페이지 service 클래스 구현 * feat: password encoder 구현 * feat: 확률값을 %형태로 바꿔주는 serializer 구현 * feat: 전화번호에 '-'를 붙여주는 serializer 구현 * feat: 추첨 시간 검증 애노테이션 구현 * feat: 선착순 날짜 검증 애노테이션 구현 * feat: 선착순 시간 검증 애노테이션 구현 * feat: 당첨 관리 페이지 컨트롤러 클래스 구현 * feat: 당첨 관리 페이지 service 클래스 구현 * config: Bcrypt 의존성 설정 * refactor: winningDate 변수의 자료형 변경 * feat: Draw, User를 조회하는 메서드 구현 * refactor: 변수명 변경 * feat: Transactional 애노테이션 추가 * refactor: 자료형 변경 및 시간 관련 변수 분리 * refactor: 자료형 변경 * feat: eventDate 변수 추가 * feat: EventParticipation 조회 메서드 구현 * feat: round값으로 Fcfs 조회하는 메서드 구현 * feat: @setter 애노테이션 추가 * docs: TODO 추가 * refactor: 클래스명 변경 * refactor: 패키지 변경 * refactor: 패키지 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 변경 * refactor: Refresh Token을 삭제하는 메서드 구현 * refactor: 커스텀 코드값 변경 * refactor: 검증 관련 상수 추가 * style: 코드 형식 맞추기 --------- Co-authored-by: hyeokson * infra: 레디스 설정 추가 * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson --------- Co-authored-by: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Co-authored-by: hyeokson --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index 1437840e..451194cd 100644 --- a/build.gradle +++ b/build.gradle @@ -57,6 +57,12 @@ dependencies { //DatatypeConverter implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + // Google Simple JSON + implementation "com.googlecode.json-simple:json-simple:1.1.1" + + //DatatypeConverter + implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + // JPA 설정 implementation 'org.springframework.boot:spring-boot-starter-data-jpa' From 7c2c6e6ace5e9ca9f1e592485b92c3f1cc6cc7c5 Mon Sep 17 00:00:00 2001 From: DrRivaski <48974215+DrRivaski@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:54:01 +0900 Subject: [PATCH 33/39] =?UTF-8?q?[Refactor]=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=EC=8B=9C=20=EC=B6=94=EC=B2=A8=20?= =?UTF-8?q?=EC=B0=B8=EC=97=AC=20=EC=A0=95=EB=B3=B4,=20=EA=B3=B5=EC=9C=A0?= =?UTF-8?q?=20=EB=A7=81=ED=81=AC=20=EC=A0=95=EB=B3=B4,=20=EA=B3=B5?= =?UTF-8?q?=EC=9C=A0=20=EC=A0=95=EB=B3=B4=20=EC=83=9D=EC=84=B1=20(#78)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * infra: 빌드 테스트 yml 작성 * infra: DB 정보 추가 * infra: ssh-agent 버전 변경 * infra: known_hosts 추가 * infra: db port 변경 * infra: database test 설정 변경 * infra: DB 환경변수 설정 및 application.yml 생성 * infra: application.yml 동적 생성 스크립트 수정 * infra: 레디스 설정 추가 * infra: redis test 추가 * infra: redis 버전 변경 * infra: redis cli 설치 * infra: application.yml 위치 및 내용 확인 * infra: Github Actions 환경변수에 REDIS_HOST, REDIS_PORT 추가 * infra: 환경변수 확인 추가 * feat: draw_rank column 이름 수정 * infra: pull_request시 Github Actions 동작하도록 수정 * cicd test (#54) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test --------- Co-authored-by: hyeokson * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson * cicd test (#58) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * chore: ci/cd를 위한 커밋 --------- Co-authored-by: hyeokson * [Feat] 성공, 실패 상태 코드 수정하기 (#65) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: cors 도메인 설정 * refactor: 커스텀 코드 형식 수정 및 에러코드 수정 - '(에러를 구분하는 알파벳)3자리 숫자' 형태로 커스텀 에러 코드 관리 - 클라이언트에서 에러 코드에 의해 분기되지 않으면 하나의 에러로 관리하도록 변경 * refactor: 하나의 성공 코드로 관리하도록 변경 * rebase: 원본 develop 브랜치와 rebase * rebase: 원본 develop 브랜치 rebase * feat: cors 설정에 localhost 추가 * refactor: 함수명 변경 * refactor: 예외 코드 변경 --------- Co-authored-by: hyeokson * [Feat]Admin Api 구현 (#67) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: Admin entity 클래스 생성 * feat: Admin exception 클래스 생성 * feat: Admin 로그인 컨트롤러 구현 * feat: Admin 로그인 요청 dto 구현 * feat: Admin 로그인 서비스 클래스 구현 * feat: Admin repository 구현 * feat: 추첨 이벤트 시간 설정 요청 dto 구현 * feat: 추첨 시간 검증 클래스 구현 * feat: 추첨 당첨자 응답 dto 구현 * feat: 추첨 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 응답 dto 구현 * feat: 이벤트 페이지 컨트롤러 구현 * feat: 이벤트 페이지 service 클래스 구현 * feat: 선착순 날짜 검증 클래스 구현 * feat: 선착순 날짜 등록 요청 dto 구현 * feat: 선착순 시간 검증 클래스 구현 * feat: 선착순 당첨자 응답 dto 구현 * feat: 선착순 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 컨트롤러 클래스 구현 * feat: 이벤트 지표 service 클래스 구현 * feat: 메인 페이지 관련 컨트롤러 클래스 구현 * feat: 메인 페이지 응답 dto 구현 * feat: 메인 페이지 service 클래스 구현 * feat: password encoder 구현 * feat: 확률값을 %형태로 바꿔주는 serializer 구현 * feat: 전화번호에 '-'를 붙여주는 serializer 구현 * feat: 추첨 시간 검증 애노테이션 구현 * feat: 선착순 날짜 검증 애노테이션 구현 * feat: 선착순 시간 검증 애노테이션 구현 * feat: 당첨 관리 페이지 컨트롤러 클래스 구현 * feat: 당첨 관리 페이지 service 클래스 구현 * config: Bcrypt 의존성 설정 * refactor: winningDate 변수의 자료형 변경 * feat: Draw, User를 조회하는 메서드 구현 * refactor: 변수명 변경 * feat: Transactional 애노테이션 추가 * refactor: 자료형 변경 및 시간 관련 변수 분리 * refactor: 자료형 변경 * feat: eventDate 변수 추가 * feat: EventParticipation 조회 메서드 구현 * feat: round값으로 Fcfs 조회하는 메서드 구현 * feat: @setter 애노테이션 추가 * docs: TODO 추가 * refactor: 클래스명 변경 * refactor: 패키지 변경 * refactor: 패키지 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 변경 * refactor: Refresh Token을 삭제하는 메서드 구현 * refactor: 커스텀 코드값 변경 * refactor: 검증 관련 상수 추가 * style: 코드 형식 맞추기 --------- Co-authored-by: hyeokson * infra: 레디스 설정 추가 * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson * [Refactor] 공유 url 조회하는 api 수정 (#70) * infra: 빌드 테스트 yml 작성 * infra: DB 정보 추가 * infra: ssh-agent 버전 변경 * infra: known_hosts 추가 * infra: db port 변경 * infra: database test 설정 변경 * infra: DB 환경변수 설정 및 application.yml 생성 * infra: application.yml 동적 생성 스크립트 수정 * infra: 레디스 설정 추가 * infra: redis test 추가 * infra: redis 버전 변경 * infra: redis cli 설치 * infra: application.yml 위치 및 내용 확인 * infra: Github Actions 환경변수에 REDIS_HOST, REDIS_PORT 추가 * infra: 환경변수 확인 추가 * feat: draw_rank column 이름 수정 * infra: pull_request시 Github Actions 동작하도록 수정 * cicd test (#54) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test --------- Co-authored-by: hyeokson * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson * cicd test (#58) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * chore: ci/cd를 위한 커밋 --------- Co-authored-by: hyeokson * refactor: 공유 url 조회하는 레포지토리 변경 - ShareInfoRepository -> ShareUrlInfoRepository * refactor: 잘못 작성된 메서드 삭제 - findSharedUrlByUserId 삭제 * refactor: 사용되지 않는 shareInfoRepository 삭제 * refactor: 변수명 변경 - sharedUrl -> shareUrl * [Feat] 성공, 실패 상태 코드 수정하기 (#65) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: cors 도메인 설정 * refactor: 커스텀 코드 형식 수정 및 에러코드 수정 - '(에러를 구분하는 알파벳)3자리 숫자' 형태로 커스텀 에러 코드 관리 - 클라이언트에서 에러 코드에 의해 분기되지 않으면 하나의 에러로 관리하도록 변경 * refactor: 하나의 성공 코드로 관리하도록 변경 * rebase: 원본 develop 브랜치와 rebase * rebase: 원본 develop 브랜치 rebase * feat: cors 설정에 localhost 추가 * refactor: 함수명 변경 * refactor: 예외 코드 변경 --------- Co-authored-by: hyeokson * [Feat]Admin Api 구현 (#67) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: Admin entity 클래스 생성 * feat: Admin exception 클래스 생성 * feat: Admin 로그인 컨트롤러 구현 * feat: Admin 로그인 요청 dto 구현 * feat: Admin 로그인 서비스 클래스 구현 * feat: Admin repository 구현 * feat: 추첨 이벤트 시간 설정 요청 dto 구현 * feat: 추첨 시간 검증 클래스 구현 * feat: 추첨 당첨자 응답 dto 구현 * feat: 추첨 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 응답 dto 구현 * feat: 이벤트 페이지 컨트롤러 구현 * feat: 이벤트 페이지 service 클래스 구현 * feat: 선착순 날짜 검증 클래스 구현 * feat: 선착순 날짜 등록 요청 dto 구현 * feat: 선착순 시간 검증 클래스 구현 * feat: 선착순 당첨자 응답 dto 구현 * feat: 선착순 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 컨트롤러 클래스 구현 * feat: 이벤트 지표 service 클래스 구현 * feat: 메인 페이지 관련 컨트롤러 클래스 구현 * feat: 메인 페이지 응답 dto 구현 * feat: 메인 페이지 service 클래스 구현 * feat: password encoder 구현 * feat: 확률값을 %형태로 바꿔주는 serializer 구현 * feat: 전화번호에 '-'를 붙여주는 serializer 구현 * feat: 추첨 시간 검증 애노테이션 구현 * feat: 선착순 날짜 검증 애노테이션 구현 * feat: 선착순 시간 검증 애노테이션 구현 * feat: 당첨 관리 페이지 컨트롤러 클래스 구현 * feat: 당첨 관리 페이지 service 클래스 구현 * config: Bcrypt 의존성 설정 * refactor: winningDate 변수의 자료형 변경 * feat: Draw, User를 조회하는 메서드 구현 * refactor: 변수명 변경 * feat: Transactional 애노테이션 추가 * refactor: 자료형 변경 및 시간 관련 변수 분리 * refactor: 자료형 변경 * feat: eventDate 변수 추가 * feat: EventParticipation 조회 메서드 구현 * feat: round값으로 Fcfs 조회하는 메서드 구현 * feat: @setter 애노테이션 추가 * docs: TODO 추가 * refactor: 클래스명 변경 * refactor: 패키지 변경 * refactor: 패키지 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 변경 * refactor: Refresh Token을 삭제하는 메서드 구현 * refactor: 커스텀 코드값 변경 * refactor: 검증 관련 상수 추가 * style: 코드 형식 맞추기 --------- Co-authored-by: hyeokson * infra: 레디스 설정 추가 * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson --------- Co-authored-by: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Co-authored-by: hyeokson * feat: 유저 생성 시 공유 정보 생성하도록 수정 * feat: 유저 생성 시 추첨 이벤트 참여 정보 생성되도록 수정 * refactor: ShareUrlInfo에 빌더 어노테이션 추가 * feat: List형태로 공유 url 가져오는 메서드 추가 * feat: 중복되지 않는 공유 url 생성 후 DB에 저장하는 로직 추가 * refactor: NoArgsConstructor, AllArgsConstructor 추가 * refactor: GeneratedValue 어노테이션 삭제 * refactor: readOnly false로 변경 * [Refactor] 공유 url 조회하는 api 수정 (#70) * infra: 빌드 테스트 yml 작성 * infra: DB 정보 추가 * infra: ssh-agent 버전 변경 * infra: known_hosts 추가 * infra: db port 변경 * infra: database test 설정 변경 * infra: DB 환경변수 설정 및 application.yml 생성 * infra: application.yml 동적 생성 스크립트 수정 * infra: 레디스 설정 추가 * infra: redis test 추가 * infra: redis 버전 변경 * infra: redis cli 설치 * infra: application.yml 위치 및 내용 확인 * infra: Github Actions 환경변수에 REDIS_HOST, REDIS_PORT 추가 * infra: 환경변수 확인 추가 * feat: draw_rank column 이름 수정 * infra: pull_request시 Github Actions 동작하도록 수정 * cicd test (#54) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test --------- Co-authored-by: hyeokson * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson * cicd test (#58) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * chore: ci/cd를 위한 커밋 --------- Co-authored-by: hyeokson * refactor: 공유 url 조회하는 레포지토리 변경 - ShareInfoRepository -> ShareUrlInfoRepository * refactor: 잘못 작성된 메서드 삭제 - findSharedUrlByUserId 삭제 * refactor: 사용되지 않는 shareInfoRepository 삭제 * refactor: 변수명 변경 - sharedUrl -> shareUrl * [Feat] 성공, 실패 상태 코드 수정하기 (#65) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: cors 도메인 설정 * refactor: 커스텀 코드 형식 수정 및 에러코드 수정 - '(에러를 구분하는 알파벳)3자리 숫자' 형태로 커스텀 에러 코드 관리 - 클라이언트에서 에러 코드에 의해 분기되지 않으면 하나의 에러로 관리하도록 변경 * refactor: 하나의 성공 코드로 관리하도록 변경 * rebase: 원본 develop 브랜치와 rebase * rebase: 원본 develop 브랜치 rebase * feat: cors 설정에 localhost 추가 * refactor: 함수명 변경 * refactor: 예외 코드 변경 --------- Co-authored-by: hyeokson * [Feat]Admin Api 구현 (#67) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: Admin entity 클래스 생성 * feat: Admin exception 클래스 생성 * feat: Admin 로그인 컨트롤러 구현 * feat: Admin 로그인 요청 dto 구현 * feat: Admin 로그인 서비스 클래스 구현 * feat: Admin repository 구현 * feat: 추첨 이벤트 시간 설정 요청 dto 구현 * feat: 추첨 시간 검증 클래스 구현 * feat: 추첨 당첨자 응답 dto 구현 * feat: 추첨 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 응답 dto 구현 * feat: 이벤트 페이지 컨트롤러 구현 * feat: 이벤트 페이지 service 클래스 구현 * feat: 선착순 날짜 검증 클래스 구현 * feat: 선착순 날짜 등록 요청 dto 구현 * feat: 선착순 시간 검증 클래스 구현 * feat: 선착순 당첨자 응답 dto 구현 * feat: 선착순 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 컨트롤러 클래스 구현 * feat: 이벤트 지표 service 클래스 구현 * feat: 메인 페이지 관련 컨트롤러 클래스 구현 * feat: 메인 페이지 응답 dto 구현 * feat: 메인 페이지 service 클래스 구현 * feat: password encoder 구현 * feat: 확률값을 %형태로 바꿔주는 serializer 구현 * feat: 전화번호에 '-'를 붙여주는 serializer 구현 * feat: 추첨 시간 검증 애노테이션 구현 * feat: 선착순 날짜 검증 애노테이션 구현 * feat: 선착순 시간 검증 애노테이션 구현 * feat: 당첨 관리 페이지 컨트롤러 클래스 구현 * feat: 당첨 관리 페이지 service 클래스 구현 * config: Bcrypt 의존성 설정 * refactor: winningDate 변수의 자료형 변경 * feat: Draw, User를 조회하는 메서드 구현 * refactor: 변수명 변경 * feat: Transactional 애노테이션 추가 * refactor: 자료형 변경 및 시간 관련 변수 분리 * refactor: 자료형 변경 * feat: eventDate 변수 추가 * feat: EventParticipation 조회 메서드 구현 * feat: round값으로 Fcfs 조회하는 메서드 구현 * feat: @setter 애노테이션 추가 * docs: TODO 추가 * refactor: 클래스명 변경 * refactor: 패키지 변경 * refactor: 패키지 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 변경 * refactor: Refresh Token을 삭제하는 메서드 구현 * refactor: 커스텀 코드값 변경 * refactor: 검증 관련 상수 추가 * style: 코드 형식 맞추기 --------- Co-authored-by: hyeokson * infra: 레디스 설정 추가 * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson --------- Co-authored-by: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Co-authored-by: hyeokson * [Feature] static text를 관리하는 enum 구현 (#71) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * refactor: transactional 어노테이션 수정 * refactor: 변수명 변경 * feat: MainPage 컨트롤러 클래스 생성 * feat: MainPage service 클래스 생성 * feat: StaticResources entity 클래스 생성 * feat: StaticResources repository 클래스 생성 * feat: StaticResourcesUtil 클래스 생성 * feat: 정적 text를 관리하는 enum 생성 * refactor: 변수명 변경 * refactor: 검증 애노테이션 추가 * refactor: DayOfWeek 속성 변경 * refactor: 예외 msg를 응답객체 result에 넣도록 변경 * refactor: 변수명 변경 * refactor: DayOfWeek 속성 변경 * refactor: 검증 애노테이션 추가 * refactor: 검증 상수 추가 * refactor: 변수 타입을 래퍼타입으로 변경 * refactor: 클래스명 변경 --------- Co-authored-by: hyeokson * [Refactor] MainPageController 클래스명 변경 (#72) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * refactor: transactional 어노테이션 수정 * refactor: 변수명 변경 * feat: MainPage 컨트롤러 클래스 생성 * feat: MainPage service 클래스 생성 * feat: StaticResources entity 클래스 생성 * feat: StaticResources repository 클래스 생성 * feat: StaticResourcesUtil 클래스 생성 * feat: 정적 text를 관리하는 enum 생성 * refactor: 변수명 변경 * refactor: 검증 애노테이션 추가 * refactor: DayOfWeek 속성 변경 * refactor: 예외 msg를 응답객체 result에 넣도록 변경 * refactor: 변수명 변경 * refactor: DayOfWeek 속성 변경 * refactor: 검증 애노테이션 추가 * refactor: 검증 상수 추가 * refactor: 변수 타입을 래퍼타입으로 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * feat: final 객체 초기화 --------- Co-authored-by: hyeokson * [Feature] 메인 페이지 GET API 구현하기 (#73) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * refactor: transactional 어노테이션 수정 * refactor: 변수명 변경 * feat: MainPage 컨트롤러 클래스 생성 * feat: MainPage service 클래스 생성 * feat: StaticResources entity 클래스 생성 * feat: StaticResources repository 클래스 생성 * feat: StaticResourcesUtil 클래스 생성 * feat: 정적 text를 관리하는 enum 생성 * refactor: 변수명 변경 * refactor: 검증 애노테이션 추가 * refactor: DayOfWeek 속성 변경 * refactor: 예외 msg를 응답객체 result에 넣도록 변경 * refactor: 변수명 변경 * refactor: DayOfWeek 속성 변경 * refactor: 검증 애노테이션 추가 * refactor: 검증 상수 추가 * refactor: 변수 타입을 래퍼타입으로 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * feat: final 객체 초기화 * feat: 메인페이지 자동차 정적 정보 응답 dto 구현 * feat: 메인페이지 이벤트 정적 정보 응답 dto 구현 * refactor: 클래스 및 변수명 변경 * refactor: 클래스명 변경 * refactor: 클래스명 변경 * refactor: round 변수 삭제 * feat: 인증검사를 하지 않는 url 추가 * feat: 메인 페이지 컨트롤러 구현 * feat: 메인 페이지 service 클래스 구현 * feat: 정적자원util 클래스 초기화 메서드 구현 * refactor: enum 변수명 수정 * refactor: Fcfs 당첨자 수 수정 로직 변경 --------- Co-authored-by: hyeokson * [Feature] 어드민 회원가입 기능 구현 (#75) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: 어드민 회원가입 요청 dto 구현 * feat: swagger controller 구현 * feat: 어드민 회원가입 controller 메서드 구현 * feat: 어드민 로그인 요청 dto 수정 * feat: 어드민 회원가입 기능 구현 * feat: 메서드 추가 - 특정 account에 대한 데이터가 admin 저장소에 있는지 확인하는 메서드 구현 * feat: swagger, admin url 추가 * feat: swagger 서버 주소 변경 * feat: cors 설정 --------- Co-authored-by: hyeokson * [Feature] 특정 url에 대해 인가 검사 하지 않도록 구현 (#76) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: 어드민 회원가입 요청 dto 구현 * feat: swagger controller 구현 * feat: 어드민 회원가입 controller 메서드 구현 * feat: 어드민 로그인 요청 dto 수정 * feat: 어드민 회원가입 기능 구현 * feat: 메서드 추가 - 특정 account에 대한 데이터가 admin 저장소에 있는지 확인하는 메서드 구현 * feat: swagger, admin url 추가 * feat: swagger 서버 주소 변경 * feat: cors 설정 * feat: 특정 url에 대해서 인가 검사 하지 않도록 구현 --------- Co-authored-by: hyeokson --------- Co-authored-by: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Co-authored-by: hyeokson --- build.gradle | 18 ++++++++++++++++++ .../fo_domain/share/domain/ShareUrlInfo.java | 6 ++++-- .../repository/ShareUrlInfoRepository.java | 4 ++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 451194cd..6c545264 100644 --- a/build.gradle +++ b/build.gradle @@ -63,6 +63,24 @@ dependencies { //DatatypeConverter implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + // Google Simple JSON + implementation "com.googlecode.json-simple:json-simple:1.1.1" + + //DatatypeConverter + implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + + // Google Simple JSON + implementation "com.googlecode.json-simple:json-simple:1.1.1" + + //DatatypeConverter + implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + + // Google Simple JSON + implementation "com.googlecode.json-simple:json-simple:1.1.1" + + //DatatypeConverter + implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + // JPA 설정 implementation 'org.springframework.boot:spring-boot-starter-data-jpa' diff --git a/src/main/java/com/softeer/backend/fo_domain/share/domain/ShareUrlInfo.java b/src/main/java/com/softeer/backend/fo_domain/share/domain/ShareUrlInfo.java index a0250d5f..35f45ee3 100644 --- a/src/main/java/com/softeer/backend/fo_domain/share/domain/ShareUrlInfo.java +++ b/src/main/java/com/softeer/backend/fo_domain/share/domain/ShareUrlInfo.java @@ -1,15 +1,17 @@ package com.softeer.backend.fo_domain.share.domain; import jakarta.persistence.*; -import lombok.Getter; +import lombok.*; @Entity @Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor @Table(name = "share_url_info") public class ShareUrlInfo { @Id @Column(name = "user_id") - @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer userId; @Column(name = "share_url") diff --git a/src/main/java/com/softeer/backend/fo_domain/share/repository/ShareUrlInfoRepository.java b/src/main/java/com/softeer/backend/fo_domain/share/repository/ShareUrlInfoRepository.java index 512a91ac..eacc5869 100644 --- a/src/main/java/com/softeer/backend/fo_domain/share/repository/ShareUrlInfoRepository.java +++ b/src/main/java/com/softeer/backend/fo_domain/share/repository/ShareUrlInfoRepository.java @@ -5,10 +5,14 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.Optional; @Repository public interface ShareUrlInfoRepository extends JpaRepository { @Query("SELECT s.shareUrl FROM ShareUrlInfo s WHERE s.userId = :userId") Optional findShareUrlByUserId(Integer userId); + + @Query("SELECT s.shareUrl FROM ShareUrlInfo s") + List findAllShareUrl(); } From 9c59a7d9d5841bb4dc04ede4efbe8f78843b1e0b Mon Sep 17 00:00:00 2001 From: DrRivaski <48974215+DrRivaski@users.noreply.github.com> Date: Sun, 11 Aug 2024 21:36:23 +0900 Subject: [PATCH 34/39] =?UTF-8?q?[Refactor]=20=EA=B3=B5=EC=9C=A0=20url=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=ED=95=98=EB=8A=94=20api=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20(#70)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * infra: 빌드 테스트 yml 작성 * infra: DB 정보 추가 * infra: ssh-agent 버전 변경 * infra: known_hosts 추가 * infra: db port 변경 * infra: database test 설정 변경 * infra: DB 환경변수 설정 및 application.yml 생성 * infra: application.yml 동적 생성 스크립트 수정 * infra: 레디스 설정 추가 * infra: redis test 추가 * infra: redis 버전 변경 * infra: redis cli 설치 * infra: application.yml 위치 및 내용 확인 * infra: Github Actions 환경변수에 REDIS_HOST, REDIS_PORT 추가 * infra: 환경변수 확인 추가 * feat: draw_rank column 이름 수정 * infra: pull_request시 Github Actions 동작하도록 수정 * cicd test (#54) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test --------- Co-authored-by: hyeokson * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson * cicd test (#58) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * chore: ci/cd를 위한 커밋 --------- Co-authored-by: hyeokson * refactor: 공유 url 조회하는 레포지토리 변경 - ShareInfoRepository -> ShareUrlInfoRepository * refactor: 잘못 작성된 메서드 삭제 - findSharedUrlByUserId 삭제 * refactor: 사용되지 않는 shareInfoRepository 삭제 * refactor: 변수명 변경 - sharedUrl -> shareUrl * [Feat] 성공, 실패 상태 코드 수정하기 (#65) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: cors 도메인 설정 * refactor: 커스텀 코드 형식 수정 및 에러코드 수정 - '(에러를 구분하는 알파벳)3자리 숫자' 형태로 커스텀 에러 코드 관리 - 클라이언트에서 에러 코드에 의해 분기되지 않으면 하나의 에러로 관리하도록 변경 * refactor: 하나의 성공 코드로 관리하도록 변경 * rebase: 원본 develop 브랜치와 rebase * rebase: 원본 develop 브랜치 rebase * feat: cors 설정에 localhost 추가 * refactor: 함수명 변경 * refactor: 예외 코드 변경 --------- Co-authored-by: hyeokson * [Feat]Admin Api 구현 (#67) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: Admin entity 클래스 생성 * feat: Admin exception 클래스 생성 * feat: Admin 로그인 컨트롤러 구현 * feat: Admin 로그인 요청 dto 구현 * feat: Admin 로그인 서비스 클래스 구현 * feat: Admin repository 구현 * feat: 추첨 이벤트 시간 설정 요청 dto 구현 * feat: 추첨 시간 검증 클래스 구현 * feat: 추첨 당첨자 응답 dto 구현 * feat: 추첨 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 응답 dto 구현 * feat: 이벤트 페이지 컨트롤러 구현 * feat: 이벤트 페이지 service 클래스 구현 * feat: 선착순 날짜 검증 클래스 구현 * feat: 선착순 날짜 등록 요청 dto 구현 * feat: 선착순 시간 검증 클래스 구현 * feat: 선착순 당첨자 응답 dto 구현 * feat: 선착순 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 컨트롤러 클래스 구현 * feat: 이벤트 지표 service 클래스 구현 * feat: 메인 페이지 관련 컨트롤러 클래스 구현 * feat: 메인 페이지 응답 dto 구현 * feat: 메인 페이지 service 클래스 구현 * feat: password encoder 구현 * feat: 확률값을 %형태로 바꿔주는 serializer 구현 * feat: 전화번호에 '-'를 붙여주는 serializer 구현 * feat: 추첨 시간 검증 애노테이션 구현 * feat: 선착순 날짜 검증 애노테이션 구현 * feat: 선착순 시간 검증 애노테이션 구현 * feat: 당첨 관리 페이지 컨트롤러 클래스 구현 * feat: 당첨 관리 페이지 service 클래스 구현 * config: Bcrypt 의존성 설정 * refactor: winningDate 변수의 자료형 변경 * feat: Draw, User를 조회하는 메서드 구현 * refactor: 변수명 변경 * feat: Transactional 애노테이션 추가 * refactor: 자료형 변경 및 시간 관련 변수 분리 * refactor: 자료형 변경 * feat: eventDate 변수 추가 * feat: EventParticipation 조회 메서드 구현 * feat: round값으로 Fcfs 조회하는 메서드 구현 * feat: @setter 애노테이션 추가 * docs: TODO 추가 * refactor: 클래스명 변경 * refactor: 패키지 변경 * refactor: 패키지 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 변경 * refactor: Refresh Token을 삭제하는 메서드 구현 * refactor: 커스텀 코드값 변경 * refactor: 검증 관련 상수 추가 * style: 코드 형식 맞추기 --------- Co-authored-by: hyeokson * infra: 레디스 설정 추가 * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson --------- Co-authored-by: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Co-authored-by: hyeokson --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index 6c545264..914876b4 100644 --- a/build.gradle +++ b/build.gradle @@ -81,6 +81,12 @@ dependencies { //DatatypeConverter implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + // Google Simple JSON + implementation "com.googlecode.json-simple:json-simple:1.1.1" + + //DatatypeConverter + implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + // JPA 설정 implementation 'org.springframework.boot:spring-boot-starter-data-jpa' From 193b559e5fe4e5ed40e5324ee56b3b89badfac18 Mon Sep 17 00:00:00 2001 From: DrRivaski <48974215+DrRivaski@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:54:01 +0900 Subject: [PATCH 35/39] =?UTF-8?q?[Refactor]=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=EC=8B=9C=20=EC=B6=94=EC=B2=A8=20?= =?UTF-8?q?=EC=B0=B8=EC=97=AC=20=EC=A0=95=EB=B3=B4,=20=EA=B3=B5=EC=9C=A0?= =?UTF-8?q?=20=EB=A7=81=ED=81=AC=20=EC=A0=95=EB=B3=B4,=20=EA=B3=B5?= =?UTF-8?q?=EC=9C=A0=20=EC=A0=95=EB=B3=B4=20=EC=83=9D=EC=84=B1=20(#78)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * infra: 빌드 테스트 yml 작성 * infra: DB 정보 추가 * infra: ssh-agent 버전 변경 * infra: known_hosts 추가 * infra: db port 변경 * infra: database test 설정 변경 * infra: DB 환경변수 설정 및 application.yml 생성 * infra: application.yml 동적 생성 스크립트 수정 * infra: 레디스 설정 추가 * infra: redis test 추가 * infra: redis 버전 변경 * infra: redis cli 설치 * infra: application.yml 위치 및 내용 확인 * infra: Github Actions 환경변수에 REDIS_HOST, REDIS_PORT 추가 * infra: 환경변수 확인 추가 * feat: draw_rank column 이름 수정 * infra: pull_request시 Github Actions 동작하도록 수정 * cicd test (#54) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test --------- Co-authored-by: hyeokson * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson * cicd test (#58) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * chore: ci/cd를 위한 커밋 --------- Co-authored-by: hyeokson * [Feat] 성공, 실패 상태 코드 수정하기 (#65) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: cors 도메인 설정 * refactor: 커스텀 코드 형식 수정 및 에러코드 수정 - '(에러를 구분하는 알파벳)3자리 숫자' 형태로 커스텀 에러 코드 관리 - 클라이언트에서 에러 코드에 의해 분기되지 않으면 하나의 에러로 관리하도록 변경 * refactor: 하나의 성공 코드로 관리하도록 변경 * rebase: 원본 develop 브랜치와 rebase * rebase: 원본 develop 브랜치 rebase * feat: cors 설정에 localhost 추가 * refactor: 함수명 변경 * refactor: 예외 코드 변경 --------- Co-authored-by: hyeokson * [Feat]Admin Api 구현 (#67) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: Admin entity 클래스 생성 * feat: Admin exception 클래스 생성 * feat: Admin 로그인 컨트롤러 구현 * feat: Admin 로그인 요청 dto 구현 * feat: Admin 로그인 서비스 클래스 구현 * feat: Admin repository 구현 * feat: 추첨 이벤트 시간 설정 요청 dto 구현 * feat: 추첨 시간 검증 클래스 구현 * feat: 추첨 당첨자 응답 dto 구현 * feat: 추첨 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 응답 dto 구현 * feat: 이벤트 페이지 컨트롤러 구현 * feat: 이벤트 페이지 service 클래스 구현 * feat: 선착순 날짜 검증 클래스 구현 * feat: 선착순 날짜 등록 요청 dto 구현 * feat: 선착순 시간 검증 클래스 구현 * feat: 선착순 당첨자 응답 dto 구현 * feat: 선착순 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 컨트롤러 클래스 구현 * feat: 이벤트 지표 service 클래스 구현 * feat: 메인 페이지 관련 컨트롤러 클래스 구현 * feat: 메인 페이지 응답 dto 구현 * feat: 메인 페이지 service 클래스 구현 * feat: password encoder 구현 * feat: 확률값을 %형태로 바꿔주는 serializer 구현 * feat: 전화번호에 '-'를 붙여주는 serializer 구현 * feat: 추첨 시간 검증 애노테이션 구현 * feat: 선착순 날짜 검증 애노테이션 구현 * feat: 선착순 시간 검증 애노테이션 구현 * feat: 당첨 관리 페이지 컨트롤러 클래스 구현 * feat: 당첨 관리 페이지 service 클래스 구현 * config: Bcrypt 의존성 설정 * refactor: winningDate 변수의 자료형 변경 * feat: Draw, User를 조회하는 메서드 구현 * refactor: 변수명 변경 * feat: Transactional 애노테이션 추가 * refactor: 자료형 변경 및 시간 관련 변수 분리 * refactor: 자료형 변경 * feat: eventDate 변수 추가 * feat: EventParticipation 조회 메서드 구현 * feat: round값으로 Fcfs 조회하는 메서드 구현 * feat: @setter 애노테이션 추가 * docs: TODO 추가 * refactor: 클래스명 변경 * refactor: 패키지 변경 * refactor: 패키지 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 변경 * refactor: Refresh Token을 삭제하는 메서드 구현 * refactor: 커스텀 코드값 변경 * refactor: 검증 관련 상수 추가 * style: 코드 형식 맞추기 --------- Co-authored-by: hyeokson * infra: 레디스 설정 추가 * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson * [Refactor] 공유 url 조회하는 api 수정 (#70) * infra: 빌드 테스트 yml 작성 * infra: DB 정보 추가 * infra: ssh-agent 버전 변경 * infra: known_hosts 추가 * infra: db port 변경 * infra: database test 설정 변경 * infra: DB 환경변수 설정 및 application.yml 생성 * infra: application.yml 동적 생성 스크립트 수정 * infra: 레디스 설정 추가 * infra: redis test 추가 * infra: redis 버전 변경 * infra: redis cli 설치 * infra: application.yml 위치 및 내용 확인 * infra: Github Actions 환경변수에 REDIS_HOST, REDIS_PORT 추가 * infra: 환경변수 확인 추가 * feat: draw_rank column 이름 수정 * infra: pull_request시 Github Actions 동작하도록 수정 * cicd test (#54) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test --------- Co-authored-by: hyeokson * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson * cicd test (#58) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * chore: ci/cd를 위한 커밋 --------- Co-authored-by: hyeokson * refactor: 공유 url 조회하는 레포지토리 변경 - ShareInfoRepository -> ShareUrlInfoRepository * refactor: 잘못 작성된 메서드 삭제 - findSharedUrlByUserId 삭제 * refactor: 사용되지 않는 shareInfoRepository 삭제 * refactor: 변수명 변경 - sharedUrl -> shareUrl * [Feat] 성공, 실패 상태 코드 수정하기 (#65) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: cors 도메인 설정 * refactor: 커스텀 코드 형식 수정 및 에러코드 수정 - '(에러를 구분하는 알파벳)3자리 숫자' 형태로 커스텀 에러 코드 관리 - 클라이언트에서 에러 코드에 의해 분기되지 않으면 하나의 에러로 관리하도록 변경 * refactor: 하나의 성공 코드로 관리하도록 변경 * rebase: 원본 develop 브랜치와 rebase * rebase: 원본 develop 브랜치 rebase * feat: cors 설정에 localhost 추가 * refactor: 함수명 변경 * refactor: 예외 코드 변경 --------- Co-authored-by: hyeokson * [Feat]Admin Api 구현 (#67) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: Admin entity 클래스 생성 * feat: Admin exception 클래스 생성 * feat: Admin 로그인 컨트롤러 구현 * feat: Admin 로그인 요청 dto 구현 * feat: Admin 로그인 서비스 클래스 구현 * feat: Admin repository 구현 * feat: 추첨 이벤트 시간 설정 요청 dto 구현 * feat: 추첨 시간 검증 클래스 구현 * feat: 추첨 당첨자 응답 dto 구현 * feat: 추첨 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 응답 dto 구현 * feat: 이벤트 페이지 컨트롤러 구현 * feat: 이벤트 페이지 service 클래스 구현 * feat: 선착순 날짜 검증 클래스 구현 * feat: 선착순 날짜 등록 요청 dto 구현 * feat: 선착순 시간 검증 클래스 구현 * feat: 선착순 당첨자 응답 dto 구현 * feat: 선착순 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 컨트롤러 클래스 구현 * feat: 이벤트 지표 service 클래스 구현 * feat: 메인 페이지 관련 컨트롤러 클래스 구현 * feat: 메인 페이지 응답 dto 구현 * feat: 메인 페이지 service 클래스 구현 * feat: password encoder 구현 * feat: 확률값을 %형태로 바꿔주는 serializer 구현 * feat: 전화번호에 '-'를 붙여주는 serializer 구현 * feat: 추첨 시간 검증 애노테이션 구현 * feat: 선착순 날짜 검증 애노테이션 구현 * feat: 선착순 시간 검증 애노테이션 구현 * feat: 당첨 관리 페이지 컨트롤러 클래스 구현 * feat: 당첨 관리 페이지 service 클래스 구현 * config: Bcrypt 의존성 설정 * refactor: winningDate 변수의 자료형 변경 * feat: Draw, User를 조회하는 메서드 구현 * refactor: 변수명 변경 * feat: Transactional 애노테이션 추가 * refactor: 자료형 변경 및 시간 관련 변수 분리 * refactor: 자료형 변경 * feat: eventDate 변수 추가 * feat: EventParticipation 조회 메서드 구현 * feat: round값으로 Fcfs 조회하는 메서드 구현 * feat: @setter 애노테이션 추가 * docs: TODO 추가 * refactor: 클래스명 변경 * refactor: 패키지 변경 * refactor: 패키지 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 변경 * refactor: Refresh Token을 삭제하는 메서드 구현 * refactor: 커스텀 코드값 변경 * refactor: 검증 관련 상수 추가 * style: 코드 형식 맞추기 --------- Co-authored-by: hyeokson * infra: 레디스 설정 추가 * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson --------- Co-authored-by: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Co-authored-by: hyeokson * feat: 유저 생성 시 공유 정보 생성하도록 수정 * feat: 유저 생성 시 추첨 이벤트 참여 정보 생성되도록 수정 * refactor: ShareUrlInfo에 빌더 어노테이션 추가 * feat: List형태로 공유 url 가져오는 메서드 추가 * feat: 중복되지 않는 공유 url 생성 후 DB에 저장하는 로직 추가 * refactor: NoArgsConstructor, AllArgsConstructor 추가 * refactor: GeneratedValue 어노테이션 삭제 * refactor: readOnly false로 변경 * [Refactor] 공유 url 조회하는 api 수정 (#70) * infra: 빌드 테스트 yml 작성 * infra: DB 정보 추가 * infra: ssh-agent 버전 변경 * infra: known_hosts 추가 * infra: db port 변경 * infra: database test 설정 변경 * infra: DB 환경변수 설정 및 application.yml 생성 * infra: application.yml 동적 생성 스크립트 수정 * infra: 레디스 설정 추가 * infra: redis test 추가 * infra: redis 버전 변경 * infra: redis cli 설치 * infra: application.yml 위치 및 내용 확인 * infra: Github Actions 환경변수에 REDIS_HOST, REDIS_PORT 추가 * infra: 환경변수 확인 추가 * feat: draw_rank column 이름 수정 * infra: pull_request시 Github Actions 동작하도록 수정 * cicd test (#54) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test --------- Co-authored-by: hyeokson * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson * cicd test (#58) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * chore: ci/cd를 위한 커밋 --------- Co-authored-by: hyeokson * refactor: 공유 url 조회하는 레포지토리 변경 - ShareInfoRepository -> ShareUrlInfoRepository * refactor: 잘못 작성된 메서드 삭제 - findSharedUrlByUserId 삭제 * refactor: 사용되지 않는 shareInfoRepository 삭제 * refactor: 변수명 변경 - sharedUrl -> shareUrl * [Feat] 성공, 실패 상태 코드 수정하기 (#65) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: cors 도메인 설정 * refactor: 커스텀 코드 형식 수정 및 에러코드 수정 - '(에러를 구분하는 알파벳)3자리 숫자' 형태로 커스텀 에러 코드 관리 - 클라이언트에서 에러 코드에 의해 분기되지 않으면 하나의 에러로 관리하도록 변경 * refactor: 하나의 성공 코드로 관리하도록 변경 * rebase: 원본 develop 브랜치와 rebase * rebase: 원본 develop 브랜치 rebase * feat: cors 설정에 localhost 추가 * refactor: 함수명 변경 * refactor: 예외 코드 변경 --------- Co-authored-by: hyeokson * [Feat]Admin Api 구현 (#67) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: Admin entity 클래스 생성 * feat: Admin exception 클래스 생성 * feat: Admin 로그인 컨트롤러 구현 * feat: Admin 로그인 요청 dto 구현 * feat: Admin 로그인 서비스 클래스 구현 * feat: Admin repository 구현 * feat: 추첨 이벤트 시간 설정 요청 dto 구현 * feat: 추첨 시간 검증 클래스 구현 * feat: 추첨 당첨자 응답 dto 구현 * feat: 추첨 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 응답 dto 구현 * feat: 이벤트 페이지 컨트롤러 구현 * feat: 이벤트 페이지 service 클래스 구현 * feat: 선착순 날짜 검증 클래스 구현 * feat: 선착순 날짜 등록 요청 dto 구현 * feat: 선착순 시간 검증 클래스 구현 * feat: 선착순 당첨자 응답 dto 구현 * feat: 선착순 당첨자 수 수정 요청 dto 구현 * feat: 이벤트 지표 컨트롤러 클래스 구현 * feat: 이벤트 지표 service 클래스 구현 * feat: 메인 페이지 관련 컨트롤러 클래스 구현 * feat: 메인 페이지 응답 dto 구현 * feat: 메인 페이지 service 클래스 구현 * feat: password encoder 구현 * feat: 확률값을 %형태로 바꿔주는 serializer 구현 * feat: 전화번호에 '-'를 붙여주는 serializer 구현 * feat: 추첨 시간 검증 애노테이션 구현 * feat: 선착순 날짜 검증 애노테이션 구현 * feat: 선착순 시간 검증 애노테이션 구현 * feat: 당첨 관리 페이지 컨트롤러 클래스 구현 * feat: 당첨 관리 페이지 service 클래스 구현 * config: Bcrypt 의존성 설정 * refactor: winningDate 변수의 자료형 변경 * feat: Draw, User를 조회하는 메서드 구현 * refactor: 변수명 변경 * feat: Transactional 애노테이션 추가 * refactor: 자료형 변경 및 시간 관련 변수 분리 * refactor: 자료형 변경 * feat: eventDate 변수 추가 * feat: EventParticipation 조회 메서드 구현 * feat: round값으로 Fcfs 조회하는 메서드 구현 * feat: @setter 애노테이션 추가 * docs: TODO 추가 * refactor: 클래스명 변경 * refactor: 패키지 변경 * refactor: 패키지 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 및 변수명 변경 * refactor: 클래스명 변경 * refactor: Refresh Token을 삭제하는 메서드 구현 * refactor: 커스텀 코드값 변경 * refactor: 검증 관련 상수 추가 * style: 코드 형식 맞추기 --------- Co-authored-by: hyeokson * infra: 레디스 설정 추가 * [Feat] 기대평 기능 구현 (#57) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * cicd test (#47) * config: jwt 속성을 yml에 설정 * config: git cache 초기화 * feat: Jwt 속성 관리 클래스 생성 * feat: 로그인 컨트롤러 클래스 생성 * feat: 로그인 요청 dto 클래스 생성 * feat: 로그인 service 클래스 생성 * feat: 메서드 추가 - 전화번호에 해당하는 유저가 있는지 확인하는 메서드 - 전화번호로 유저 객체를 반환하는 메서드 * feat: 필드 추가 및 전화번호 인덱싱 설정 * feat: 로그인 성공 상태 코드 추가 * feat: 로그인 실패 상태 코드 추가 * style: 엔터한 공간 줄이기 * chore: ci/cd test --------- Co-authored-by: hyeokson * chore: ci/cd test * chore: ci/cd test * chore: ci/cd test * config: gradle 의존성 설정 * refactor: BaseEntity 삭제 * feat: if문 추가 - 인증 및 미인증 유저가 공동으로 사용하는 api를 위해서 인증을 하지 않았다면 예외가 아니라 userId값으로 null을 갖도록 변경 * feat: 댓글 예외 상태 코드 추가 * feat: Comment 엔티티 클래스 생성 * feat: Comment 컨트롤러 생성 및 구현 - 기대평 조회 및 저장 로직 구현 * feat: Comment 예외 클래스 생성 * feat: 기대평 닉네임을 관리하는 Enum 클래스 생성 * feat: Comment repository 생성 및 구현 * feat: Comment service 생성 및 구현 - SCROLL_SIZE 만큼의 기대평을 반환하는 메서드 구현 - 기대평을 저장하는 메서드 구현 * feat: Comment 조회 응답 클래스 생성 * feat: 기대평을 관리하는 Enum 클래스 생성 * feat: 컨버터 클래스 생성 - 기대평 Enum 객체와 comment 값을 서로 변환해주는 컨버터 생성 * feat: Util 클래스 생성 - 커서 기반 스크롤 기능을 사용할 수 있는 Util 클래스 생성 * refactor: jsonformat 패턴 변경 * feat: 기대평 성공 상태 코드 추가 * refactor: enum 값 변경 * refactor: 호출하는 메서드 명 변경 * refactor: 자료형 변경 * refactor: 애노테이션 변경 * refactor: claim의 id값 자료형 변경 * feat: 변수 및 메서드 추가 - Access Token이 header에 있으면 인증하고 없으면 인증하지 않는 url 설정 및 기능 구현 * feat: 자동으로 생성 시간 저장하도록 구현 * refactor: 시간값 설정 코드 삭제 --------- Co-authored-by: hyeokson --------- Co-authored-by: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Co-authored-by: hyeokson * [Feature] static text를 관리하는 enum 구현 (#71) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * refactor: transactional 어노테이션 수정 * refactor: 변수명 변경 * feat: MainPage 컨트롤러 클래스 생성 * feat: MainPage service 클래스 생성 * feat: StaticResources entity 클래스 생성 * feat: StaticResources repository 클래스 생성 * feat: StaticResourcesUtil 클래스 생성 * feat: 정적 text를 관리하는 enum 생성 * refactor: 변수명 변경 * refactor: 검증 애노테이션 추가 * refactor: DayOfWeek 속성 변경 * refactor: 예외 msg를 응답객체 result에 넣도록 변경 * refactor: 변수명 변경 * refactor: DayOfWeek 속성 변경 * refactor: 검증 애노테이션 추가 * refactor: 검증 상수 추가 * refactor: 변수 타입을 래퍼타입으로 변경 * refactor: 클래스명 변경 --------- Co-authored-by: hyeokson * [Refactor] MainPageController 클래스명 변경 (#72) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * refactor: transactional 어노테이션 수정 * refactor: 변수명 변경 * feat: MainPage 컨트롤러 클래스 생성 * feat: MainPage service 클래스 생성 * feat: StaticResources entity 클래스 생성 * feat: StaticResources repository 클래스 생성 * feat: StaticResourcesUtil 클래스 생성 * feat: 정적 text를 관리하는 enum 생성 * refactor: 변수명 변경 * refactor: 검증 애노테이션 추가 * refactor: DayOfWeek 속성 변경 * refactor: 예외 msg를 응답객체 result에 넣도록 변경 * refactor: 변수명 변경 * refactor: DayOfWeek 속성 변경 * refactor: 검증 애노테이션 추가 * refactor: 검증 상수 추가 * refactor: 변수 타입을 래퍼타입으로 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * feat: final 객체 초기화 --------- Co-authored-by: hyeokson * [Feature] 메인 페이지 GET API 구현하기 (#73) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * refactor: transactional 어노테이션 수정 * refactor: 변수명 변경 * feat: MainPage 컨트롤러 클래스 생성 * feat: MainPage service 클래스 생성 * feat: StaticResources entity 클래스 생성 * feat: StaticResources repository 클래스 생성 * feat: StaticResourcesUtil 클래스 생성 * feat: 정적 text를 관리하는 enum 생성 * refactor: 변수명 변경 * refactor: 검증 애노테이션 추가 * refactor: DayOfWeek 속성 변경 * refactor: 예외 msg를 응답객체 result에 넣도록 변경 * refactor: 변수명 변경 * refactor: DayOfWeek 속성 변경 * refactor: 검증 애노테이션 추가 * refactor: 검증 상수 추가 * refactor: 변수 타입을 래퍼타입으로 변경 * refactor: 클래스명 변경 * refactor: 클래스명 및 변수명 변경 * feat: final 객체 초기화 * feat: 메인페이지 자동차 정적 정보 응답 dto 구현 * feat: 메인페이지 이벤트 정적 정보 응답 dto 구현 * refactor: 클래스 및 변수명 변경 * refactor: 클래스명 변경 * refactor: 클래스명 변경 * refactor: round 변수 삭제 * feat: 인증검사를 하지 않는 url 추가 * feat: 메인 페이지 컨트롤러 구현 * feat: 메인 페이지 service 클래스 구현 * feat: 정적자원util 클래스 초기화 메서드 구현 * refactor: enum 변수명 수정 * refactor: Fcfs 당첨자 수 수정 로직 변경 --------- Co-authored-by: hyeokson * [Feature] 어드민 회원가입 기능 구현 (#75) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: 어드민 회원가입 요청 dto 구현 * feat: swagger controller 구현 * feat: 어드민 회원가입 controller 메서드 구현 * feat: 어드민 로그인 요청 dto 수정 * feat: 어드민 회원가입 기능 구현 * feat: 메서드 추가 - 특정 account에 대한 데이터가 admin 저장소에 있는지 확인하는 메서드 구현 * feat: swagger, admin url 추가 * feat: swagger 서버 주소 변경 * feat: cors 설정 --------- Co-authored-by: hyeokson * [Feature] 특정 url에 대해 인가 검사 하지 않도록 구현 (#76) * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: 어드민 회원가입 요청 dto 구현 * feat: swagger controller 구현 * feat: 어드민 회원가입 controller 메서드 구현 * feat: 어드민 로그인 요청 dto 수정 * feat: 어드민 회원가입 기능 구현 * feat: 메서드 추가 - 특정 account에 대한 데이터가 admin 저장소에 있는지 확인하는 메서드 구현 * feat: swagger, admin url 추가 * feat: swagger 서버 주소 변경 * feat: cors 설정 * feat: 특정 url에 대해서 인가 검사 하지 않도록 구현 --------- Co-authored-by: hyeokson --------- Co-authored-by: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Co-authored-by: hyeokson --- build.gradle | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/build.gradle b/build.gradle index 914876b4..64380413 100644 --- a/build.gradle +++ b/build.gradle @@ -87,6 +87,24 @@ dependencies { //DatatypeConverter implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + // Google Simple JSON + implementation "com.googlecode.json-simple:json-simple:1.1.1" + + //DatatypeConverter + implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + + // Google Simple JSON + implementation "com.googlecode.json-simple:json-simple:1.1.1" + + //DatatypeConverter + implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + + // Google Simple JSON + implementation "com.googlecode.json-simple:json-simple:1.1.1" + + //DatatypeConverter + implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1' + // JPA 설정 implementation 'org.springframework.boot:spring-boot-starter-data-jpa' From 21e3305adb583e7ea792755f3e11afcb160117cd Mon Sep 17 00:00:00 2001 From: Son Chanhyeok <127181634+hyeokson@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:00:14 +0900 Subject: [PATCH 36/39] =?UTF-8?q?[Refactor]=20MainPageCarResponseDto=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EB=B3=80=EA=B2=BD=20(#79)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * config: jwt 속성을 yml에 설정 * rebase: 원본 develop 브랜치와 병합 * feat: 어드민 회원가입 요청 dto 구현 * feat: swagger controller 구현 * feat: 어드민 회원가입 controller 메서드 구현 * feat: 어드민 로그인 요청 dto 수정 * feat: 어드민 회원가입 기능 구현 * feat: 메서드 추가 - 특정 account에 대한 데이터가 admin 저장소에 있는지 확인하는 메서드 구현 * feat: swagger, admin url 추가 * feat: swagger 서버 주소 변경 * feat: cors 설정 * feat: 특정 url에 대해서 인가 검사 하지 않도록 구현 * refactor: CarVideoInfo 내부클래스 삭제 * refactor: CarVideoInfo를 사용하지 않도록 변경 * refactor: TODO 삭제 --------- Co-authored-by: hyeokson --- .../mainpage/dto/MainPageCarResponseDto.java | 17 ------ .../mainpage/service/MainPageService.java | 57 +++++++++---------- .../global/config/web/WebMvcConfig.java | 2 +- 3 files changed, 28 insertions(+), 48 deletions(-) diff --git a/src/main/java/com/softeer/backend/fo_domain/mainpage/dto/MainPageCarResponseDto.java b/src/main/java/com/softeer/backend/fo_domain/mainpage/dto/MainPageCarResponseDto.java index bf89cb56..ad8aef6e 100644 --- a/src/main/java/com/softeer/backend/fo_domain/mainpage/dto/MainPageCarResponseDto.java +++ b/src/main/java/com/softeer/backend/fo_domain/mainpage/dto/MainPageCarResponseDto.java @@ -10,25 +10,8 @@ @Getter public class MainPageCarResponseDto { - private CarVideoInfo carVideoInfo; - private List carInfoList; - - @Getter - @AllArgsConstructor - @Builder - public static class CarVideoInfo{ - - private String title; - - private String subTitle; - - private String videoUrl; - - private String backgroundImgUrl; - } - @Getter @AllArgsConstructor @Builder diff --git a/src/main/java/com/softeer/backend/fo_domain/mainpage/service/MainPageService.java b/src/main/java/com/softeer/backend/fo_domain/mainpage/service/MainPageService.java index fdc230de..b18e20cd 100644 --- a/src/main/java/com/softeer/backend/fo_domain/mainpage/service/MainPageService.java +++ b/src/main/java/com/softeer/backend/fo_domain/mainpage/service/MainPageService.java @@ -44,7 +44,15 @@ public MainPageEventResponseDto getEventPage(){ public MainPageCarResponseDto getCarPage(){ - MainPageCarResponseDto.CarDetailInfo carDetailInfo1_1 = MainPageCarResponseDto.CarDetailInfo.builder() + MainPageCarResponseDto.CarInfo carInfo1 = MainPageCarResponseDto.CarInfo.builder() + .id(1) + .title(staticResourcesUtil.getData("MAIN_TITLE")) + .subTitle(staticResourcesUtil.getData("MAIN_SUBTITLE")) + .imgUrl(staticResourcesUtil.getData("ioniq_video")) + .backgroundImgUrl(staticResourcesUtil.getData("main_background_image")) + .build(); + + MainPageCarResponseDto.CarDetailInfo carDetailInfo2_1 = MainPageCarResponseDto.CarDetailInfo.builder() .id(1) .title(staticResourcesUtil.getData("INTERIOR_OPENNESS_TITLE")) .subTitle(staticResourcesUtil.getData("INTERIOR_OPENNESS_SUBTITLE")) @@ -52,7 +60,7 @@ public MainPageCarResponseDto getCarPage(){ .imgUrl(staticResourcesUtil.getData("interior_openness_image")) .build(); - MainPageCarResponseDto.CarDetailInfo carDetailInfo1_2 = MainPageCarResponseDto.CarDetailInfo.builder() + MainPageCarResponseDto.CarDetailInfo carDetailInfo2_2 = MainPageCarResponseDto.CarDetailInfo.builder() .id(2) .title(staticResourcesUtil.getData("INTERIOR_WELLNESS_TITLE")) .subTitle(staticResourcesUtil.getData("INTERIOR_WELLNESS_SUBTITLE")) @@ -60,18 +68,18 @@ public MainPageCarResponseDto getCarPage(){ .imgUrl(staticResourcesUtil.getData("interior_wellness_image")) .build(); - MainPageCarResponseDto.CarInfo carInfo1 = MainPageCarResponseDto.CarInfo.builder() - .id(1) + MainPageCarResponseDto.CarInfo carInfo2 = MainPageCarResponseDto.CarInfo.builder() + .id(2) .title(staticResourcesUtil.getData("INTERIOR_TITLE")) .subTitle(staticResourcesUtil.getData("INTERIOR_SUBTITLE")) .imgTitle(staticResourcesUtil.getData("INTERIOR_IMAGE_TITLE")) .imgContent(staticResourcesUtil.getData("INTERIOR_IMAGE_CONTENT")) .imgUrl(staticResourcesUtil.getData("interior_thumbnail_image")) .backgroundImgUrl(staticResourcesUtil.getData("interior_background_image")) - .carDetailInfoList(Arrays.asList(carDetailInfo1_1, carDetailInfo1_2)) + .carDetailInfoList(Arrays.asList(carDetailInfo2_1, carDetailInfo2_2)) .build(); - MainPageCarResponseDto.CarDetailInfo carDetailInfo2_1 = MainPageCarResponseDto.CarDetailInfo.builder() + MainPageCarResponseDto.CarDetailInfo carDetailInfo3_1 = MainPageCarResponseDto.CarDetailInfo.builder() .id(1) .title(staticResourcesUtil.getData("PERFORMANCE_BRAKING_TITLE")) .subTitle(staticResourcesUtil.getData("PERFORMANCE_BRAKING_SUBTITLE")) @@ -79,7 +87,7 @@ public MainPageCarResponseDto getCarPage(){ .imgUrl(staticResourcesUtil.getData("performance_braking_image")) .build(); - MainPageCarResponseDto.CarDetailInfo carDetailInfo2_2 = MainPageCarResponseDto.CarDetailInfo.builder() + MainPageCarResponseDto.CarDetailInfo carDetailInfo3_2 = MainPageCarResponseDto.CarDetailInfo.builder() .id(2) .title(staticResourcesUtil.getData("PERFORMANCE_DRIVING_TITLE")) .subTitle(staticResourcesUtil.getData("PERFORMANCE_DRIVING_SUBTITLE")) @@ -87,18 +95,18 @@ public MainPageCarResponseDto getCarPage(){ .imgUrl(staticResourcesUtil.getData("performance_driving_image")) .build(); - MainPageCarResponseDto.CarInfo carInfo2 = MainPageCarResponseDto.CarInfo.builder() - .id(2) + MainPageCarResponseDto.CarInfo carInfo3 = MainPageCarResponseDto.CarInfo.builder() + .id(3) .title(staticResourcesUtil.getData("PERFORMANCE_TITLE")) .subTitle(staticResourcesUtil.getData("PERFORMANCE_SUBTITLE")) .imgTitle(staticResourcesUtil.getData("PERFORMANCE_IMAGE_TITLE")) .imgContent(staticResourcesUtil.getData("PERFORMANCE_IMAGE_CONTENT")) .imgUrl(staticResourcesUtil.getData("performance_thumbnail_image")) .backgroundImgUrl(staticResourcesUtil.getData("performance_background_image")) - .carDetailInfoList(Arrays.asList(carDetailInfo2_1, carDetailInfo2_2)) + .carDetailInfoList(Arrays.asList(carDetailInfo3_1, carDetailInfo3_2)) .build(); - MainPageCarResponseDto.CarDetailInfo carDetailInfo3_1 = MainPageCarResponseDto.CarDetailInfo.builder() + MainPageCarResponseDto.CarDetailInfo carDetailInfo4_1 = MainPageCarResponseDto.CarDetailInfo.builder() .id(1) .title(staticResourcesUtil.getData("CHARGING_FAST_TITLE")) .subTitle(staticResourcesUtil.getData("CHARGING_FAST_SUBTITLE")) @@ -106,7 +114,7 @@ public MainPageCarResponseDto getCarPage(){ .imgUrl(staticResourcesUtil.getData("charging_fast_image")) .build(); - MainPageCarResponseDto.CarDetailInfo carDetailInfo3_2 = MainPageCarResponseDto.CarDetailInfo.builder() + MainPageCarResponseDto.CarDetailInfo carDetailInfo4_2 = MainPageCarResponseDto.CarDetailInfo.builder() .id(2) .title(staticResourcesUtil.getData("CHARGING_V2L_TITLE")) .subTitle(staticResourcesUtil.getData("CHARGING_V2L_SUBTITLE")) @@ -114,8 +122,8 @@ public MainPageCarResponseDto getCarPage(){ .imgUrl(staticResourcesUtil.getData("charging_v2l_image")) .build(); - MainPageCarResponseDto.CarInfo carInfo3 = MainPageCarResponseDto.CarInfo.builder() - .id(3) + MainPageCarResponseDto.CarInfo carInfo4 = MainPageCarResponseDto.CarInfo.builder() + .id(4) .title(staticResourcesUtil.getData("CHARGING_TITLE")) .subTitle(staticResourcesUtil.getData("CHARGING_SUBTITLE")) .imgTitle(staticResourcesUtil.getData("CHARGING_IMAGE_TITLE")) @@ -125,7 +133,7 @@ public MainPageCarResponseDto getCarPage(){ .carDetailInfoList(Arrays.asList(carDetailInfo3_1, carDetailInfo3_2)) .build(); - MainPageCarResponseDto.CarDetailInfo carDetailInfo4_1 = MainPageCarResponseDto.CarDetailInfo.builder() + MainPageCarResponseDto.CarDetailInfo carDetailInfo5_1 = MainPageCarResponseDto.CarDetailInfo.builder() .id(1) .title(staticResourcesUtil.getData("SAFE_DRIVING_TITLE")) .subTitle(staticResourcesUtil.getData("SAFE_DRIVING_SUBTITLE")) @@ -133,7 +141,7 @@ public MainPageCarResponseDto getCarPage(){ .imgUrl(staticResourcesUtil.getData("safe_driving_image")) .build(); - MainPageCarResponseDto.CarDetailInfo carDetailInfo4_2 = MainPageCarResponseDto.CarDetailInfo.builder() + MainPageCarResponseDto.CarDetailInfo carDetailInfo5_2 = MainPageCarResponseDto.CarDetailInfo.builder() .id(2) .title(staticResourcesUtil.getData("SAFE_ADVANCED_TITLE")) .subTitle(staticResourcesUtil.getData("SAFE_ADVANCED_SUBTITLE")) @@ -141,8 +149,8 @@ public MainPageCarResponseDto getCarPage(){ .imgUrl(staticResourcesUtil.getData("safe_advanced_image")) .build(); - MainPageCarResponseDto.CarInfo carInfo4 = MainPageCarResponseDto.CarInfo.builder() - .id(4) + MainPageCarResponseDto.CarInfo carInfo5 = MainPageCarResponseDto.CarInfo.builder() + .id(5) .title(staticResourcesUtil.getData("SAFE_TITLE")) .subTitle(staticResourcesUtil.getData("SAFE_SUBTITLE")) .imgTitle(staticResourcesUtil.getData("SAFE_IMAGE_TITLE")) @@ -152,19 +160,8 @@ public MainPageCarResponseDto getCarPage(){ .carDetailInfoList(Arrays.asList(carDetailInfo4_1, carDetailInfo4_2)) .build(); - - - - MainPageCarResponseDto.CarVideoInfo carVideoInfo = MainPageCarResponseDto.CarVideoInfo.builder() - .title(staticResourcesUtil.getData("MAIN_TITLE")) - .subTitle(staticResourcesUtil.getData("MAIN_SUBTITLE")) - .videoUrl(staticResourcesUtil.getData("ioniq_video")) - .backgroundImgUrl(staticResourcesUtil.getData("main_background_image")) - .build(); - return MainPageCarResponseDto.builder() - .carVideoInfo(carVideoInfo) - .carInfoList(Arrays.asList(carInfo1, carInfo2, carInfo3, carInfo4)) + .carInfoList(Arrays.asList(carInfo1, carInfo2, carInfo3, carInfo4, carInfo5)) .build(); } } diff --git a/src/main/java/com/softeer/backend/global/config/web/WebMvcConfig.java b/src/main/java/com/softeer/backend/global/config/web/WebMvcConfig.java index 526f3e2a..0420fecc 100644 --- a/src/main/java/com/softeer/backend/global/config/web/WebMvcConfig.java +++ b/src/main/java/com/softeer/backend/global/config/web/WebMvcConfig.java @@ -46,7 +46,7 @@ public void addArgumentResolvers(List resolvers) */ @Override public void addCorsMappings(CorsRegistry registry) { - // TODO: Origin 도메인 수정 및 헤더값 설정 + registry.addMapping("/**") .allowedOrigins("https://softeer.site", "http://localhost:5173", "https://softeer.shop") // 허용할 도메인 설정 .allowedMethods("OPTIONS", "GET", "POST", "PUT", "DELETE") // 허용할 HTTP 메서드 설정 From 0b2087c06cd466f190eaae99b59257f5e5123a3d Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Sat, 17 Aug 2024 17:26:33 +0900 Subject: [PATCH 37/39] =?UTF-8?q?refactor:=20=EA=B3=B5=EC=9C=A0=20url?= =?UTF-8?q?=EC=9D=98=20BASE=20URL=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/global/staticresources/constant/StaticText.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/softeer/backend/global/staticresources/constant/StaticText.java b/src/main/java/com/softeer/backend/global/staticresources/constant/StaticText.java index fc1fb6d8..cbbec488 100644 --- a/src/main/java/com/softeer/backend/global/staticresources/constant/StaticText.java +++ b/src/main/java/com/softeer/backend/global/staticresources/constant/StaticText.java @@ -97,7 +97,7 @@ public enum StaticText { "이벤트 당첨 이후 개인정보 제공을 거부하거나 개별 안내를 거부하는 경우, 당첨이 취소될 수 있습니다."), // 공유 url - BASE_URL("https://softeer.shop/share/"), + BASE_URL("https://softeer.site/"), NON_USER_SHARE_URL("https://softeer.site"), // 선착순 From 1423a1edc6b4b56c987c64d037e274112a9621f5 Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Sat, 17 Aug 2024 17:26:56 +0900 Subject: [PATCH 38/39] =?UTF-8?q?refactor:=20=EA=B3=B5=EC=9C=A0=20url?= =?UTF-8?q?=EC=97=90=EC=84=9C=20path=20variable=EB=A7=8C=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/fo_domain/share/controller/ShareController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/softeer/backend/fo_domain/share/controller/ShareController.java b/src/main/java/com/softeer/backend/fo_domain/share/controller/ShareController.java index 88b27ec9..fc40c55f 100644 --- a/src/main/java/com/softeer/backend/fo_domain/share/controller/ShareController.java +++ b/src/main/java/com/softeer/backend/fo_domain/share/controller/ShareController.java @@ -25,7 +25,7 @@ public ResponseDto getShortenShareUrl(@Parameter(hidden return ResponseDto.onSuccess(shareUrlInfoService.getShortenShareUrl(userId)); } - @GetMapping("/share/{shareUrl}") + @GetMapping("/{shareUrl}") public ResponseEntity redirectWithShareUrl(@PathVariable String shareUrl, HttpServletRequest request) { // session을 이용해 공유 url 저장 HttpSession session = request.getSession(); From 74c819d3e4272a68996f7d7ed7ba96ba60814f4b Mon Sep 17 00:00:00 2001 From: DrRivaski Date: Sat, 17 Aug 2024 17:48:36 +0900 Subject: [PATCH 39/39] =?UTF-8?q?refactor:=20=EA=B3=B5=EC=9C=A0=20url?= =?UTF-8?q?=EC=9D=98=20BASE=20URL=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/fo_domain/share/controller/ShareController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/softeer/backend/fo_domain/share/controller/ShareController.java b/src/main/java/com/softeer/backend/fo_domain/share/controller/ShareController.java index fc40c55f..88b27ec9 100644 --- a/src/main/java/com/softeer/backend/fo_domain/share/controller/ShareController.java +++ b/src/main/java/com/softeer/backend/fo_domain/share/controller/ShareController.java @@ -25,7 +25,7 @@ public ResponseDto getShortenShareUrl(@Parameter(hidden return ResponseDto.onSuccess(shareUrlInfoService.getShortenShareUrl(userId)); } - @GetMapping("/{shareUrl}") + @GetMapping("/share/{shareUrl}") public ResponseEntity redirectWithShareUrl(@PathVariable String shareUrl, HttpServletRequest request) { // session을 이용해 공유 url 저장 HttpSession session = request.getSession();