From d20b2c006e12ca2f374855a9cd640c9eadde7672 Mon Sep 17 00:00:00 2001
From: JeongHeumChoi <andyc707@gmail.com>
Date: Fri, 30 Aug 2024 16:28:42 +0900
Subject: [PATCH 1/5] =?UTF-8?q?Refactor:=20jwt=20=EA=B4=80=EB=A0=A8=20?=
 =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=ED=8F=B4=EB=8D=94=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../security/handler/login/Oauth2SuccessHandler.java            | 2 +-
 .../security/handler/logout/CustomLogoutProcessHandler.java     | 2 +-
 .../java/dgu/choco_express/service/{ => jwt}/JwtService.java    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
 rename src/main/java/dgu/choco_express/service/{ => jwt}/JwtService.java (96%)

diff --git a/src/main/java/dgu/choco_express/security/handler/login/Oauth2SuccessHandler.java b/src/main/java/dgu/choco_express/security/handler/login/Oauth2SuccessHandler.java
index 28ad514..10e926b 100644
--- a/src/main/java/dgu/choco_express/security/handler/login/Oauth2SuccessHandler.java
+++ b/src/main/java/dgu/choco_express/security/handler/login/Oauth2SuccessHandler.java
@@ -4,7 +4,7 @@
 import dgu.choco_express.repository.UserRepository;
 import dgu.choco_express.security.info.AuthenticationResponse;
 import dgu.choco_express.security.info.UserPrincipal;
-import dgu.choco_express.service.JwtService;
+import dgu.choco_express.service.jwt.JwtService;
 import dgu.choco_express.util.JwtUtil;
 import jakarta.servlet.ServletException;
 import jakarta.servlet.http.HttpServletRequest;
diff --git a/src/main/java/dgu/choco_express/security/handler/logout/CustomLogoutProcessHandler.java b/src/main/java/dgu/choco_express/security/handler/logout/CustomLogoutProcessHandler.java
index e390e5a..69649f3 100644
--- a/src/main/java/dgu/choco_express/security/handler/logout/CustomLogoutProcessHandler.java
+++ b/src/main/java/dgu/choco_express/security/handler/logout/CustomLogoutProcessHandler.java
@@ -3,7 +3,7 @@
 import dgu.choco_express.constant.Constants;
 import dgu.choco_express.exception.CommonException;
 import dgu.choco_express.exception.GlobalErrorCode;
-import dgu.choco_express.service.JwtService;
+import dgu.choco_express.service.jwt.JwtService;
 import dgu.choco_express.util.HeaderUtil;
 import dgu.choco_express.util.JwtUtil;
 import io.jsonwebtoken.Claims;
diff --git a/src/main/java/dgu/choco_express/service/JwtService.java b/src/main/java/dgu/choco_express/service/jwt/JwtService.java
similarity index 96%
rename from src/main/java/dgu/choco_express/service/JwtService.java
rename to src/main/java/dgu/choco_express/service/jwt/JwtService.java
index 69ffc99..363f246 100644
--- a/src/main/java/dgu/choco_express/service/JwtService.java
+++ b/src/main/java/dgu/choco_express/service/jwt/JwtService.java
@@ -1,4 +1,4 @@
-package dgu.choco_express.service;
+package dgu.choco_express.service.jwt;
 
 import dgu.choco_express.domain.refreshToken.RefreshToken;
 import dgu.choco_express.repository.RefreshTokenRepository;

From 6e82cd7aefd5d3c9d949f84bf7eed29fcc9581b8 Mon Sep 17 00:00:00 2001
From: JeongHeumChoi <andyc707@gmail.com>
Date: Fri, 30 Aug 2024 16:29:08 +0900
Subject: [PATCH 2/5] =?UTF-8?q?Feat:=20=ED=8A=B9=EC=A0=95=20uri=EC=9D=98?=
 =?UTF-8?q?=20=EB=A9=94=EC=86=8C=EB=93=9C=EB=A7=8C=20permit?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../dgu/choco_express/security/config/SecurityConfig.java    | 2 ++
 .../security/filter/JwtAuthenticationFilter.java             | 5 +++++
 .../choco_express/security/filter/JwtExceptionFilter.java    | 5 +++++
 3 files changed, 12 insertions(+)

diff --git a/src/main/java/dgu/choco_express/security/config/SecurityConfig.java b/src/main/java/dgu/choco_express/security/config/SecurityConfig.java
index 3568bf9..cb3d76c 100644
--- a/src/main/java/dgu/choco_express/security/config/SecurityConfig.java
+++ b/src/main/java/dgu/choco_express/security/config/SecurityConfig.java
@@ -15,6 +15,7 @@
 import lombok.RequiredArgsConstructor;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
@@ -47,6 +48,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
                 .authorizeHttpRequests(request ->
                         request
                                 .requestMatchers(Constants.NO_NEED_AUTH.toArray(String[]::new)).permitAll()
+                                .requestMatchers(HttpMethod.GET, "/api/box/{boxId:[0-9]+}").permitAll()
                                 .requestMatchers("/api/**").hasAnyRole("USER")
                                 .anyRequest().authenticated()
                 )
diff --git a/src/main/java/dgu/choco_express/security/filter/JwtAuthenticationFilter.java b/src/main/java/dgu/choco_express/security/filter/JwtAuthenticationFilter.java
index 9074466..ab07891 100644
--- a/src/main/java/dgu/choco_express/security/filter/JwtAuthenticationFilter.java
+++ b/src/main/java/dgu/choco_express/security/filter/JwtAuthenticationFilter.java
@@ -33,6 +33,11 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
 
     @Override
     protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException{
+        String requestURI = request.getRequestURI();
+        String requestMethod = request.getMethod();
+
+        if (requestURI.matches("/api/box/\\d+") && "GET".equalsIgnoreCase(requestMethod))
+            return true;
         return Constants.NO_NEED_AUTH.contains(request.getRequestURI());
     }
 
diff --git a/src/main/java/dgu/choco_express/security/filter/JwtExceptionFilter.java b/src/main/java/dgu/choco_express/security/filter/JwtExceptionFilter.java
index 33332d7..9675d0e 100644
--- a/src/main/java/dgu/choco_express/security/filter/JwtExceptionFilter.java
+++ b/src/main/java/dgu/choco_express/security/filter/JwtExceptionFilter.java
@@ -20,6 +20,11 @@
 public class JwtExceptionFilter extends OncePerRequestFilter {
     @Override
     protected boolean shouldNotFilter(HttpServletRequest request) {
+        String requestURI = request.getRequestURI();
+        String requestMethod = request.getMethod();
+
+        if (requestURI.matches("/api/box/\\d+") && "GET".equalsIgnoreCase(requestMethod))
+            return true;
         return Constants.NO_NEED_AUTH.contains(request.getRequestURI());
     }
 

From ad85b7d20bb301087845e0dbdab2061986fa4919 Mon Sep 17 00:00:00 2001
From: JeongHeumChoi <andyc707@gmail.com>
Date: Fri, 30 Aug 2024 16:29:31 +0900
Subject: [PATCH 3/5] =?UTF-8?q?Feat:=20Box=20domain=20=EC=83=9D=EC=84=B1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../dgu/choco_express/domain/Box/Box.java     | 63 +++++++++++++++++++
 1 file changed, 63 insertions(+)
 create mode 100644 src/main/java/dgu/choco_express/domain/Box/Box.java

diff --git a/src/main/java/dgu/choco_express/domain/Box/Box.java b/src/main/java/dgu/choco_express/domain/Box/Box.java
new file mode 100644
index 0000000..a34407c
--- /dev/null
+++ b/src/main/java/dgu/choco_express/domain/Box/Box.java
@@ -0,0 +1,63 @@
+package dgu.choco_express.domain.Box;
+
+import dgu.choco_express.domain.global.BaseTimeEntity;
+import dgu.choco_express.domain.user.User;
+import jakarta.persistence.*;
+import lombok.AccessLevel;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import org.hibernate.annotations.DynamicUpdate;
+
+@Entity
+@Getter
+@DynamicUpdate
+@Table(name = "boxes")
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+public class Box extends BaseTimeEntity {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column
+    private Long id;
+
+    @Column(name = "name")
+    private String name;
+
+    @Column(name = "type")
+    private Short type;
+
+    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
+    @JoinColumn(name = "users_id")
+    private User user;
+
+    @Builder
+    private Box(
+            final String name,
+            final Short type,
+            final User user
+    ) {
+        this.name = name;
+        this.type = type;
+        this.user = user;
+    }
+
+    public static Box from(
+            final String name,
+            final Short type,
+            final User user
+    ) {
+        return Box.builder()
+                  .name(name)
+                  .type(type)
+                  .user(user)
+                  .build();
+    }
+
+    public void updateBox(
+            final String name,
+            final Short type
+    ) {
+        this.name = name;
+        this.type = type;
+    }
+}

From 7cc742fb769adb800a844e76232ea9d4dc6f8ee7 Mon Sep 17 00:00:00 2001
From: JeongHeumChoi <andyc707@gmail.com>
Date: Fri, 30 Aug 2024 16:29:47 +0900
Subject: [PATCH 4/5] =?UTF-8?q?Feat:=20Box=20API=20=EC=83=9D=EC=84=B1=20?=
 =?UTF-8?q?=EC=99=84=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../controller/BoxController.java             | 49 ++++++++++++
 .../dto/box/request/BoxCreateRequestDto.java  | 11 +++
 .../dto/box/request/BoxPatchRequestDto.java   | 11 +++
 .../BoxCurrentUserRetrieverResponseDto.java   | 23 ++++++
 .../BoxOtherUserRetrieverResponseDto.java     | 23 ++++++
 .../choco_express/exception/BoxErrorCode.java | 20 +++++
 .../repository/BoxRepository.java             | 12 +++
 .../service/box/BoxRetriever.java             | 30 ++++++++
 .../choco_express/service/box/BoxSaver.java   | 18 +++++
 .../choco_express/service/box/BoxService.java | 75 +++++++++++++++++++
 .../choco_express/service/box/BoxUpdater.java | 20 +++++
 .../service/user/UserRetriever.java           | 19 +++++
 12 files changed, 311 insertions(+)
 create mode 100644 src/main/java/dgu/choco_express/controller/BoxController.java
 create mode 100644 src/main/java/dgu/choco_express/dto/box/request/BoxCreateRequestDto.java
 create mode 100644 src/main/java/dgu/choco_express/dto/box/request/BoxPatchRequestDto.java
 create mode 100644 src/main/java/dgu/choco_express/dto/box/response/BoxCurrentUserRetrieverResponseDto.java
 create mode 100644 src/main/java/dgu/choco_express/dto/box/response/BoxOtherUserRetrieverResponseDto.java
 create mode 100644 src/main/java/dgu/choco_express/exception/BoxErrorCode.java
 create mode 100644 src/main/java/dgu/choco_express/repository/BoxRepository.java
 create mode 100644 src/main/java/dgu/choco_express/service/box/BoxRetriever.java
 create mode 100644 src/main/java/dgu/choco_express/service/box/BoxSaver.java
 create mode 100644 src/main/java/dgu/choco_express/service/box/BoxService.java
 create mode 100644 src/main/java/dgu/choco_express/service/box/BoxUpdater.java
 create mode 100644 src/main/java/dgu/choco_express/service/user/UserRetriever.java

diff --git a/src/main/java/dgu/choco_express/controller/BoxController.java b/src/main/java/dgu/choco_express/controller/BoxController.java
new file mode 100644
index 0000000..c528b68
--- /dev/null
+++ b/src/main/java/dgu/choco_express/controller/BoxController.java
@@ -0,0 +1,49 @@
+package dgu.choco_express.controller;
+
+
+import dgu.choco_express.annotation.UserId;
+import dgu.choco_express.dto.box.request.BoxCreateRequestDto;
+import dgu.choco_express.dto.box.request.BoxPatchRequestDto;
+import dgu.choco_express.service.box.BoxService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/box")
+public class BoxController {
+    private final BoxService boxService;
+
+    @PostMapping
+    public ResponseEntity<?> createBox(
+            @UserId Long userId,
+            @RequestBody BoxCreateRequestDto boxCreateRequestDto
+    ) {
+
+        return ResponseEntity.created(
+                boxService.createBox(userId, boxCreateRequestDto)
+        ).build();
+    }
+
+    @GetMapping("/{boxId}")
+    public ResponseEntity<?> getOtherUserBox(
+            @PathVariable Long boxId
+    ) {
+        return ResponseEntity.ok(boxService.getOtherUserBox(boxId));
+    }
+
+    @PatchMapping("/{boxId}")
+    public ResponseEntity<?> updateBox(
+            @UserId Long userId,
+            @PathVariable Long boxId,
+            @RequestBody BoxPatchRequestDto boxPatchRequestDto
+    ) {
+        return ResponseEntity.ok(boxService.updateBox(userId, boxId, boxPatchRequestDto));
+    }
+
+    @GetMapping("user-box")
+    public ResponseEntity<?> getCurrentUserBox(@UserId Long userId) {
+        return ResponseEntity.ok(boxService.getCurrentUserBox(userId));
+    }
+}
diff --git a/src/main/java/dgu/choco_express/dto/box/request/BoxCreateRequestDto.java b/src/main/java/dgu/choco_express/dto/box/request/BoxCreateRequestDto.java
new file mode 100644
index 0000000..b23a817
--- /dev/null
+++ b/src/main/java/dgu/choco_express/dto/box/request/BoxCreateRequestDto.java
@@ -0,0 +1,11 @@
+package dgu.choco_express.dto.box.request;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public record BoxCreateRequestDto(
+        @JsonProperty("boxName")
+        String boxName,
+        @JsonProperty("boxType")
+        Short boxType
+) {
+}
diff --git a/src/main/java/dgu/choco_express/dto/box/request/BoxPatchRequestDto.java b/src/main/java/dgu/choco_express/dto/box/request/BoxPatchRequestDto.java
new file mode 100644
index 0000000..0d5a210
--- /dev/null
+++ b/src/main/java/dgu/choco_express/dto/box/request/BoxPatchRequestDto.java
@@ -0,0 +1,11 @@
+package dgu.choco_express.dto.box.request;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public record BoxPatchRequestDto(
+        @JsonProperty("boxName")
+        String boxName,
+        @JsonProperty("boxType")
+        Short boxType
+) {
+}
diff --git a/src/main/java/dgu/choco_express/dto/box/response/BoxCurrentUserRetrieverResponseDto.java b/src/main/java/dgu/choco_express/dto/box/response/BoxCurrentUserRetrieverResponseDto.java
new file mode 100644
index 0000000..8311e7d
--- /dev/null
+++ b/src/main/java/dgu/choco_express/dto/box/response/BoxCurrentUserRetrieverResponseDto.java
@@ -0,0 +1,23 @@
+package dgu.choco_express.dto.box.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import dgu.choco_express.domain.Box.Box;
+import lombok.Builder;
+
+@Builder
+public record BoxCurrentUserRetrieverResponseDto(
+        @JsonProperty("boxId")
+        Long boxId,
+        @JsonProperty("boxName")
+        String boxName,
+        @JsonProperty("boxType")
+        Short boxType
+) {
+    public static BoxCurrentUserRetrieverResponseDto of(Box box) {
+        return BoxCurrentUserRetrieverResponseDto.builder()
+                                                 .boxId(box.getId())
+                                                 .boxName(box.getName())
+                                                 .boxType(box.getType())
+                                                 .build();
+    }
+}
diff --git a/src/main/java/dgu/choco_express/dto/box/response/BoxOtherUserRetrieverResponseDto.java b/src/main/java/dgu/choco_express/dto/box/response/BoxOtherUserRetrieverResponseDto.java
new file mode 100644
index 0000000..8488173
--- /dev/null
+++ b/src/main/java/dgu/choco_express/dto/box/response/BoxOtherUserRetrieverResponseDto.java
@@ -0,0 +1,23 @@
+package dgu.choco_express.dto.box.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import dgu.choco_express.domain.Box.Box;
+import lombok.Builder;
+
+@Builder
+public record BoxOtherUserRetrieverResponseDto(
+        @JsonProperty("boxId")
+        Long boxId,
+        @JsonProperty("boxName")
+        String boxName,
+        @JsonProperty("boxType")
+        Short boxType
+) {
+    public static BoxOtherUserRetrieverResponseDto of(Box box) {
+        return BoxOtherUserRetrieverResponseDto.builder()
+                                            .boxId(box.getId())
+                                            .boxName(box.getName())
+                                            .boxType(box.getType())
+                                            .build();
+    }
+}
diff --git a/src/main/java/dgu/choco_express/exception/BoxErrorCode.java b/src/main/java/dgu/choco_express/exception/BoxErrorCode.java
new file mode 100644
index 0000000..340f167
--- /dev/null
+++ b/src/main/java/dgu/choco_express/exception/BoxErrorCode.java
@@ -0,0 +1,20 @@
+package dgu.choco_express.exception;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+
+@Getter
+@RequiredArgsConstructor
+public enum BoxErrorCode implements ErrorCode {
+    INVALID_BOX_TYPE(HttpStatus.BAD_REQUEST, "BOX_001", "박스 타입이 유효하지 않습니다."),
+    NOT_FOUND_BOX(HttpStatus.NOT_FOUND, "BOX_002", "해당 박스가 존재하지 않습니다."),
+    MISMATCH_USER_AND_BOX_ID(HttpStatus.BAD_REQUEST, "BOX_003", "해당 박스와 로그인 한 사용자가 일치하지 않습니다."),
+    YET_USER_HAS_BOX(HttpStatus.NOT_FOUND, "BOX_004", "해당 유저는 박스가 없습니다."),
+    INVALID_BOX_NAME(HttpStatus.BAD_REQUEST, "BOX_005", "박스 이름이 비어있습니다.")
+    ;
+
+    private final HttpStatus status;
+    private final String errorCode;
+    private final String message;
+}
diff --git a/src/main/java/dgu/choco_express/repository/BoxRepository.java b/src/main/java/dgu/choco_express/repository/BoxRepository.java
new file mode 100644
index 0000000..4620b64
--- /dev/null
+++ b/src/main/java/dgu/choco_express/repository/BoxRepository.java
@@ -0,0 +1,12 @@
+package dgu.choco_express.repository;
+
+import dgu.choco_express.domain.Box.Box;
+import dgu.choco_express.domain.user.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface BoxRepository extends JpaRepository<Box, Long> {
+    Optional<Box> findByIdAndUser(Long boxId, User user);
+    Optional<Box> findByUser(User user);
+}
diff --git a/src/main/java/dgu/choco_express/service/box/BoxRetriever.java b/src/main/java/dgu/choco_express/service/box/BoxRetriever.java
new file mode 100644
index 0000000..49cc984
--- /dev/null
+++ b/src/main/java/dgu/choco_express/service/box/BoxRetriever.java
@@ -0,0 +1,30 @@
+package dgu.choco_express.service.box;
+
+import dgu.choco_express.domain.Box.Box;
+import dgu.choco_express.domain.user.User;
+import dgu.choco_express.exception.BoxErrorCode;
+import dgu.choco_express.exception.CommonException;
+import dgu.choco_express.repository.BoxRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class BoxRetriever {
+    private final BoxRepository boxRepository;
+
+    public Box findById(Long id) {
+        return boxRepository.findById(id)
+                .orElseThrow(() -> CommonException.type(BoxErrorCode.NOT_FOUND_BOX));
+    }
+
+    public Box findByIdAndUser(Long boxId, User user) {
+        return boxRepository.findByIdAndUser(boxId, user)
+                .orElseThrow(() -> CommonException.type(BoxErrorCode.MISMATCH_USER_AND_BOX_ID));
+    }
+
+    public Box findByUser(User user) {
+        return boxRepository.findByUser(user)
+                .orElseThrow(() -> CommonException.type(BoxErrorCode.YET_USER_HAS_BOX));
+    }
+}
diff --git a/src/main/java/dgu/choco_express/service/box/BoxSaver.java b/src/main/java/dgu/choco_express/service/box/BoxSaver.java
new file mode 100644
index 0000000..979f0f9
--- /dev/null
+++ b/src/main/java/dgu/choco_express/service/box/BoxSaver.java
@@ -0,0 +1,18 @@
+package dgu.choco_express.service.box;
+
+import dgu.choco_express.domain.Box.Box;
+import dgu.choco_express.repository.BoxRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@RequiredArgsConstructor
+public class BoxSaver {
+    private final BoxRepository boxRepository;
+
+    @Transactional
+    public Box saveBox(Box box) {
+        return boxRepository.save(box);
+    }
+}
diff --git a/src/main/java/dgu/choco_express/service/box/BoxService.java b/src/main/java/dgu/choco_express/service/box/BoxService.java
new file mode 100644
index 0000000..7fae52f
--- /dev/null
+++ b/src/main/java/dgu/choco_express/service/box/BoxService.java
@@ -0,0 +1,75 @@
+package dgu.choco_express.service.box;
+
+import dgu.choco_express.domain.Box.Box;
+import dgu.choco_express.domain.user.User;
+import dgu.choco_express.dto.box.request.BoxCreateRequestDto;
+import dgu.choco_express.dto.box.request.BoxPatchRequestDto;
+import dgu.choco_express.dto.box.response.BoxCurrentUserRetrieverResponseDto;
+import dgu.choco_express.dto.box.response.BoxOtherUserRetrieverResponseDto;
+import dgu.choco_express.exception.BoxErrorCode;
+import dgu.choco_express.exception.CommonException;
+import dgu.choco_express.service.user.UserRetriever;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.net.URI;
+
+@Service
+@RequiredArgsConstructor
+public class BoxService {
+    private final BoxRetriever boxRetriever;
+    private final BoxSaver boxSaver;
+    private final UserRetriever userRetriever;
+    private final BoxUpdater boxUpdater;
+
+    public URI createBox(
+            Long userId,
+            BoxCreateRequestDto boxCreateRequestDto
+    ) {
+        User currentUser = userRetriever.findById(userId);
+
+        String boxName = boxCreateRequestDto.boxName();
+        Short boxType = boxCreateRequestDto.boxType();
+
+        if (boxName.isEmpty())
+            throw CommonException.type(BoxErrorCode.INVALID_BOX_NAME);
+        if (boxType < 1 || boxType > 6)
+            throw CommonException.type(BoxErrorCode.INVALID_BOX_TYPE);
+
+        Box createdBox = boxSaver.saveBox(
+                Box.from(boxName, boxType, currentUser)
+        );
+
+        return URI.create("/api/box/" + createdBox.getId().toString());
+    }
+
+    public BoxOtherUserRetrieverResponseDto getOtherUserBox(Long boxId) {
+        Box currentBox = boxRetriever.findById(boxId);
+
+        return BoxOtherUserRetrieverResponseDto.of(currentBox);
+    }
+
+    public Void updateBox(
+            Long userId,
+            Long boxId,
+            BoxPatchRequestDto boxPatchRequestDto
+    ) {
+        User currentUser = userRetriever.findById(userId);
+        Box currrentBox = boxRetriever.findByIdAndUser(boxId, currentUser);
+
+        String boxName = boxPatchRequestDto.boxName();
+        Short boxType = boxPatchRequestDto.boxType();
+        if (boxType < 1 || boxType > 6)
+            throw CommonException.type(BoxErrorCode.INVALID_BOX_TYPE);
+        boxUpdater.updateBox(currrentBox, boxName, boxType);
+
+        return null;
+    }
+
+    public BoxCurrentUserRetrieverResponseDto getCurrentUserBox(Long userId) {
+        User currentUser = userRetriever.findById(userId);
+        Box currentBox = boxRetriever.findByUser(currentUser);
+
+        return BoxCurrentUserRetrieverResponseDto.of(currentBox);
+    }
+}
diff --git a/src/main/java/dgu/choco_express/service/box/BoxUpdater.java b/src/main/java/dgu/choco_express/service/box/BoxUpdater.java
new file mode 100644
index 0000000..c04bd94
--- /dev/null
+++ b/src/main/java/dgu/choco_express/service/box/BoxUpdater.java
@@ -0,0 +1,20 @@
+package dgu.choco_express.service.box;
+
+import dgu.choco_express.domain.Box.Box;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+@RequiredArgsConstructor
+public class BoxUpdater {
+
+    @Transactional
+    public void updateBox(
+            Box box,
+            final String name,
+            final Short type
+    ) {
+        box.updateBox(name, type);
+    }
+}
diff --git a/src/main/java/dgu/choco_express/service/user/UserRetriever.java b/src/main/java/dgu/choco_express/service/user/UserRetriever.java
new file mode 100644
index 0000000..6accf2c
--- /dev/null
+++ b/src/main/java/dgu/choco_express/service/user/UserRetriever.java
@@ -0,0 +1,19 @@
+package dgu.choco_express.service.user;
+
+import dgu.choco_express.domain.user.User;
+import dgu.choco_express.exception.CommonException;
+import dgu.choco_express.exception.UserErrorCode;
+import dgu.choco_express.repository.UserRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class UserRetriever {
+    private final UserRepository userRepository;
+
+    public User findById(Long id) {
+        return userRepository.findById(id)
+                .orElseThrow(() -> CommonException.type(UserErrorCode.NOT_FOUND_USER));
+    }
+}

From 8aacaa61791766338e26677f6290f07eb5dda7b5 Mon Sep 17 00:00:00 2001
From: JeongHeumChoi <andyc707@gmail.com>
Date: Fri, 30 Aug 2024 16:31:08 +0900
Subject: [PATCH 5/5] =?UTF-8?q?Refactor:=20=ED=95=84=EC=9A=94=20=EC=97=86?=
 =?UTF-8?q?=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../security/handler/login/Oauth2SuccessHandler.java            | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/main/java/dgu/choco_express/security/handler/login/Oauth2SuccessHandler.java b/src/main/java/dgu/choco_express/security/handler/login/Oauth2SuccessHandler.java
index 10e926b..fd42d6a 100644
--- a/src/main/java/dgu/choco_express/security/handler/login/Oauth2SuccessHandler.java
+++ b/src/main/java/dgu/choco_express/security/handler/login/Oauth2SuccessHandler.java
@@ -1,7 +1,6 @@
 package dgu.choco_express.security.handler.login;
 
 import dgu.choco_express.dto.jwt.response.JwtDto;
-import dgu.choco_express.repository.UserRepository;
 import dgu.choco_express.security.info.AuthenticationResponse;
 import dgu.choco_express.security.info.UserPrincipal;
 import dgu.choco_express.service.jwt.JwtService;
@@ -25,7 +24,6 @@ public class Oauth2SuccessHandler implements AuthenticationSuccessHandler {
     @Value("${server.domain}")
     private String domain;
     private final JwtUtil jwtUtil;
-    private final UserRepository userRepository;
     private final JwtService jwtService;
 
     @Override