[volume-1] 회원가입, 내 정보 조회, 비밀번호 변경 기능 구현 #47
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
📌 Summary
UserController에서X-Loopers-LoginPw헤더가 검증 없이 선언만 되어 인증 우회 가능, 생년월일 포맷팅/비밀번호 암호화 로직이 컨트롤러에 위치하여 계층 책임 혼재AuthenticationService추가로 인증 처리,UserInfoResponse.from()팩토리 메서드로 포맷팅 분리, 전체 64개 테스트 통과🧭 Context & Decision
문제 정의
getMyInfo,updatePassword에서loginPw파라미터가@NotBlank검증만 수행register에서Password.of(),passwordEncoder.encrypt()컨트롤러에서 직접 호출UserQueryService에서 생년월일yyyyMMdd포맷팅 수행선택지와 결정
AuthenticationUseCase분리 → 재사용 가능, 단일 책임AuthenticationUseCase신규 생성🏗️ Design Overview
변경 범위
commerce-api(interfaces, application, domain 레이어)AuthenticationUseCase,AuthenticationServiceUserInfoResponse.from()팩토리 메서드AuthenticationServiceTest,UserInfoResponseTestUserController에서PasswordEncoder의존성 제거RegisterUseCase시그니처 변경 (primitive 타입 수신)주요 컴포넌트 책임
UserController: 요청 검증, 응답 조립 (도메인 로직 없음)AuthenticationService: 사용자 인증 (ID/PW 검증)UserRegisterService: 회원가입 +Password생성/암호화UserInfoResponse: API 응답 포맷팅 (from()팩토리 메서드)sequenceDiagram autonumber title: 내 정보 조회 (Me) participant Client participant Controller as UserController participant Auth as AuthenticationService participant Query as UserQueryService participant DB as UserRepository Client->>Controller: GET /api/v1/users/me Note over Client,Controller: Headers: X-Loopers-Id, X-Loopers-Pw Controller->>Auth: authenticate(userId, loginPw) Auth->>DB: findById(userId) DB-->>Auth: User Entity alt 비밀번호 불일치 Auth-->>Controller: throw InvalidPasswordException Controller-->>Client: 401 Unauthorized else 인증 성공 Auth-->>Controller: Success end Controller->>Query: getUserInfo(userId) Query->>DB: findById(userId) DB-->>Query: User Entity Query-->>Controller: UserInfoResponse Note right of Controller: UserInfoResponse.from(user)<br/>LocalDate to String Controller-->>Client: 200 OK {"birthday": "19900515"}sequenceDiagram autonumber title: Main Flow - 회원가입 participant Client participant Controller as UserController participant Service as UserRegisterService participant DB as UserRepository Client->>Controller: POST /api/v1/users/register Note over Client,Controller: Body: loginId, name, password, birthday, email Controller->>Service: register(command) Note right of Service: Birthday.of(birthday) <br/>(VO Validation) Service->>Service: Password.of(rawPassword) Service->>Service: passwordEncoder.encode(password) Service->>DB: save(User Entity) DB-->>Service: void Service-->>Controller: void Controller-->>Client: 201 Created