Repository navigation
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