-
Notifications
You must be signed in to change notification settings - Fork 0
Feature/13 user #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/13 user #24
Changes from all commits
851a857
b40bc2e
a14aa2e
909ee05
16e1409
380561e
4bfa55a
2de77d5
7a80575
4462cb5
5f5ce52
404fb3c
a9924b3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,35 @@ | ||||||||||||||
| package ita.tinybite.domain.auth.service; | ||||||||||||||
|
|
||||||||||||||
| import ita.tinybite.domain.user.entity.User; | ||||||||||||||
| import ita.tinybite.domain.user.repository.UserRepository; | ||||||||||||||
| import ita.tinybite.global.exception.BusinessException; | ||||||||||||||
| import ita.tinybite.global.exception.errorcode.UserErrorCode; | ||||||||||||||
| import ita.tinybite.global.exception.errorcode.CommonErrorCode; | ||||||||||||||
| import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||||||||||||||
| import org.springframework.security.core.Authentication; | ||||||||||||||
| import org.springframework.security.core.context.SecurityContextHolder; | ||||||||||||||
| import org.springframework.stereotype.Component; | ||||||||||||||
|
|
||||||||||||||
| @Component | ||||||||||||||
| public class SecurityProvider { | ||||||||||||||
|
|
||||||||||||||
| private final UserRepository userRepository; | ||||||||||||||
|
|
||||||||||||||
| public SecurityProvider(UserRepository userRepository) { | ||||||||||||||
| this.userRepository = userRepository; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| public User getCurrentUser() { | ||||||||||||||
| return getUserFromContext(); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| private User getUserFromContext() { | ||||||||||||||
| Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | ||||||||||||||
| if (!(authentication instanceof UsernamePasswordAuthenticationToken auth)) { | ||||||||||||||
| throw BusinessException.of(CommonErrorCode.UNAUTHORIZED); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| Long userId = (Long) auth.getPrincipal(); | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ์์ ํ์ง ์์ ํ์ ์บ์คํ ์ด ์์ต๋๋ค.
ํ์ ๊ฒ์ฆ์ ์ถ๊ฐํ์ธ์: - Long userId = (Long) auth.getPrincipal();
+ if (!(auth.getPrincipal() instanceof Long userId)) {
+ throw BusinessException.of(CommonErrorCode.UNAUTHORIZED);
+ }
return userRepository.findById(userId).orElseThrow(() -> BusinessException.of(UserErrorCode.USER_NOT_EXISTS));๐ Committable suggestion
Suggested change
๐ค Prompt for AI Agents |
||||||||||||||
| return userRepository.findById(userId).orElseThrow(() -> BusinessException.of(UserErrorCode.USER_NOT_EXISTS)); | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package ita.tinybite.domain.user.controller; | ||
|
|
||
| import ita.tinybite.domain.user.dto.req.UpdateUserReqDto; | ||
| import ita.tinybite.domain.user.service.UserService; | ||
| import ita.tinybite.global.response.APIResponse; | ||
| import jakarta.validation.Valid; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| import static ita.tinybite.global.response.APIResponse.success; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/api/v1/user/me") | ||
| public class UserController { | ||
|
|
||
| private final UserService userService; | ||
|
|
||
| public UserController(UserService userService) { | ||
| this.userService = userService; | ||
| } | ||
|
|
||
| @GetMapping | ||
| public APIResponse<?> getUser() { | ||
| return success(userService.getUser()); | ||
| } | ||
|
|
||
| @PatchMapping | ||
| public APIResponse<?> updateUser(@Valid @RequestBody UpdateUserReqDto req) { | ||
| userService.updateUser(req); | ||
| return success(); | ||
| } | ||
|
|
||
| @PatchMapping("/location") | ||
| public APIResponse<?> updateLocation(@RequestParam(defaultValue = "37.3623504988728") String latitude, | ||
| @RequestParam(defaultValue = "127.117057453619") String longitude) { | ||
| userService.updateLocation(latitude, longitude); | ||
| return success(); | ||
| } | ||
|
|
||
| @DeleteMapping | ||
| public APIResponse<?> deleteUser() { | ||
| userService.deleteUser(); | ||
| return success(); | ||
| } | ||
|
Comment on lines
+39
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ๐งฉ Analysis chain๐ Script executed: find . -name "*.java" -type f | grep -E "(User|user)" | head -20Repository: tinybite-2025/tinybite-server Length of output: 815 ๐ Script executed: cat -n ./src/main/java/ita/tinybite/domain/user/entity/User.javaRepository: tinybite-2025/tinybite-server Length of output: 1669 ๐ Script executed: cat -n ./src/main/java/ita/tinybite/domain/user/service/UserService.javaRepository: tinybite-2025/tinybite-server Length of output: 1944 ๐ Script executed: cat -n ./src/main/java/ita/tinybite/domain/user/constant/UserStatus.javaRepository: tinybite-2025/tinybite-server Length of output: 209 ๐ Script executed: cat -n ./src/main/java/ita/tinybite/domain/user/controller/UserController.javaRepository: tinybite-2025/tinybite-server Length of output: 1657 ๐ Script executed: cd ./src/main/java && find . -name "*.java" -type f -exec grep -l "@ManyToOne.*User\|@OneToMany.*User" {} \;Repository: tinybite-2025/tinybite-server Length of output: 55 ๐ Script executed: rg "@Entity" --type java -A 20 | head -100Repository: tinybite-2025/tinybite-server Length of output: 4308 ๐ Script executed: rg "private.*User" --type java -B 3 | grep -E "@Entity|@ManyToOne|private.*User"Repository: tinybite-2025/tinybite-server Length of output: 1269 ๐ Script executed: find ./src -name "*.java" -path "*/entity/*" -type fRepository: tinybite-2025/tinybite-server Length of output: 325 ๐ Script executed: cat -n ./src/main/java/ita/tinybite/domain/auth/entity/RefreshToken.javaRepository: tinybite-2025/tinybite-server Length of output: 1110 ๐ Script executed: cat -n ./src/main/java/ita/tinybite/domain/auth/entity/JwtTokenProvider.javaRepository: tinybite-2025/tinybite-server Length of output: 3768 ๐ Script executed: rg "deleteUser\|delete.*User" --type java -B 2 -A 2Repository: tinybite-2025/tinybite-server Length of output: 55 ๊ณ์ ์ญ์ ์์ ์ ์์ ์ฅ์น๊ฐ ํ์ํฉ๋๋ค. ํ์ฌ ๊ตฌํ์ ๋จ์ hard delete๋ก ์ฆ์ ์ญ์ ๋๋ฉฐ, ๋ณต๊ตฌ ๋ถ๊ฐ๋ฅํ ๋ฐ์ดํฐ ์์ค ์ํ์ด ์์ต๋๋ค. ๋ค์ ์ฌํญ๋ค์ ๊ฐ์ ํ์ธ์:
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| package ita.tinybite.domain.user.dto.req; | ||
|
|
||
| public record UpdateUserReqDto( | ||
| String nickname | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package ita.tinybite.domain.user.dto.res; | ||
|
|
||
| import ita.tinybite.domain.user.entity.User; | ||
|
|
||
| public record UserResDto( | ||
| Long userId, | ||
| String name, | ||
| String location | ||
| ) { | ||
|
|
||
| public static UserResDto of(User user) { | ||
| return new UserResDto(user.getUserId(), user.getNickname(), user.getLocation()); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| package ita.tinybite.domain.user.service; | ||
|
|
||
| import ita.tinybite.domain.auth.service.SecurityProvider; | ||
| import ita.tinybite.domain.user.dto.req.UpdateUserReqDto; | ||
| import ita.tinybite.domain.user.dto.res.UserResDto; | ||
| import ita.tinybite.domain.user.entity.User; | ||
| import ita.tinybite.domain.user.repository.UserRepository; | ||
| import ita.tinybite.global.location.LocationService; | ||
| import org.springframework.stereotype.Service; | ||
|
|
||
| @Service | ||
| public class UserService { | ||
|
|
||
| private final SecurityProvider securityProvider; | ||
| private final UserRepository userRepository; | ||
| private final LocationService locationService; | ||
|
|
||
| public UserService(SecurityProvider securityProvider, | ||
| UserRepository userRepository, | ||
| LocationService locationService) { | ||
| this.securityProvider = securityProvider; | ||
| this.userRepository = userRepository; | ||
| this.locationService = locationService; | ||
| } | ||
|
|
||
| public UserResDto getUser() { | ||
| User user = securityProvider.getCurrentUser(); | ||
| return UserResDto.of(user); | ||
| } | ||
|
|
||
| public void updateUser(UpdateUserReqDto req) { | ||
| User user = securityProvider.getCurrentUser(); | ||
| user.update(req); | ||
| } | ||
|
Comment on lines
+31
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ํธ๋์ญ์ ๊ด๋ฆฌ๊ฐ ๋๋ฝ๋์์ต๋๋ค.
ํด๋์ค ๋๋ ๋ฉ์๋์ +import org.springframework.transaction.annotation.Transactional;
+
@Service
+@Transactional(readOnly = true)
public class UserService {
// ... ์์ฑ์ ...
+ @Transactional(readOnly = true)
public UserResDto getUser() {
User user = securityProvider.getCurrentUser();
return UserResDto.of(user);
}
+ @Transactional
public void updateUser(UpdateUserReqDto req) {
User user = securityProvider.getCurrentUser();
user.update(req);
}
๐ค Prompt for AI Agents |
||
|
|
||
| public void updateLocation(String latitude, String longitude) { | ||
| User user = securityProvider.getCurrentUser(); | ||
| String location = locationService.getLocation(latitude, longitude); | ||
| user.updateLocation(location); | ||
| } | ||
|
Comment on lines
+36
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ํธ๋์ญ์ ๊ด๋ฆฌ๊ฐ ๋๋ฝ๋์์ต๋๋ค.
๋ฉ์๋์ + @Transactional
public void updateLocation(String latitude, String longitude) {
User user = securityProvider.getCurrentUser();
String location = locationService.getLocation(latitude, longitude);
user.updateLocation(location);
}๐ค Prompt for AI Agents |
||
|
|
||
| public void deleteUser() { | ||
| userRepository.delete(securityProvider.getCurrentUser()); | ||
| } | ||
|
Comment on lines
+42
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ๐ ๏ธ Refactor suggestion | ๐ Major ์ญ์ ์์ ์๋ ํธ๋์ญ์ ์ด ํ์ํฉ๋๋ค. ๋ช
์์ ์ธ + @Transactional
public void deleteUser() {
userRepository.delete(securityProvider.getCurrentUser());
}๐ค Prompt for AI Agents |
||
|
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redis ํฌํธ๊ฐ ์ธ๋ถ์ ๋ ธ์ถ๋์ด ์๊ณ ์ธ์ฆ์ด ์ค์ ๋์ง ์์์ต๋๋ค.
6379:6379๋ก ํธ์คํธ์ ํฌํธ๊ฐ ๋ฐ์ธ๋ฉ๋์ด ์ธ๋ถ์์ ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค. ํ๋ก๋์ ํ๊ฒฝ์์๋ ๋ณด์์ ๋ฌธ์ ๊ฐ ๋ ์ ์์ต๋๋ค.๊ถ์ฅ ์กฐ์น:
redis: container_name: redis image: redis:7.2.4 - ports: - - "6379:6379" + # ๋ค๋ฅธ ์ปจํ ์ด๋์์๋ง ์ ๊ทผ ๊ฐ๋ฅํ๋๋ก ports ๋ ธ์ถ ์ ๊ฑฐ + # ๋๋ ๋ก์ปฌ ์ ๊ทผ๋ง ํ์ฉ: "127.0.0.1:6379:6379" + command: redis-server --requirepass ${REDIS_PASSWORD} volumes: - redis_data:/data๐ค Prompt for AI Agents