Repository navigation
refactor: 기반 코드가 사용자 도메인을 알던 자리를 끊는다 - #147
Merged
Merged
Conversation
"core 기반 패키지는 domain 을 의존하지 않는다" 위반 50건은 전부 인증·인가 기반 코드였다. 다섯 덩어리였고 각각 원인이 달랐다. - CurrentUserFacade (15): 이 클래스가 곧 사용자 도메인의 입구다 → domain/user/app - KakaoUtil (11): 카카오 응답 형식(KakaoProfile·KakaoAccount·KakaoProperties· KakaoProfileInfo·KakaoOAuthToken)이 우리 API 응답 패키지에 있었다 → external/kakao - 전역 예외 핸들러 (10): ConsentRequiredException 이 ConsentGuard 안의 중첩 클래스여서 예외를 가리키려면 서비스를 import 해야 했다 → core/exception 으로 꺼내고 동의 종류를 문자열로 담는다(열거형이면 핸들러가 다시 도메인을 알아야 한다) - CustomUserDetailsService (8): → domain/user/security, SecurityConfig 는 스프링의 UserDetailsService 인터페이스로 받는다 - JwtAuthenticationFilter (6): 필터는 토큰 검증만 필요한데 JwtService 는 로그인 응답 DTO 까지 다룬다 → AccessTokenVerifier 포트로 필요한 만큼만 끊었다 옮기는 방향이 중요했다. 셋은 core 에서 도메인으로 옮겼고(자격 증명으로 사용자를 찾는 일과 현재 사용자를 꺼내는 일은 사용자 도메인의 규칙이다), 둘은 반대로 핸들러·필터가 도메인을 보지 않도록 경계를 세웠다(토큰 서명 검증과 예외→HTTP 변환은 기반 코드의 일이고 도메인 타입을 알 필요가 없다). 카카오 DTO 가 잘못된 자리에 있던 것이 실제 문제였다. 필드명이 connected_at, thumbnail_image_url 처럼 snake_case 인 것이 카카오의 와이어 포맷이라는 증거인데, 그것이 우리가 프런트에 주는 응답을 모아 둔 domain/user/dto/response 에 섞여 있었다. 규칙도 한 줄 고쳤다. CurrentUserFacade 가 도메인으로 들어오자 "도메인은 SecurityContextHolder 를 직접 쓰지 않는다" 에 걸렸다 — 그 클래스의 존재 이유가 바로 그 접근을 혼자 하는 것인데도. 규칙의 because 가 이미 "현재 사용자는 CurrentUserFacade 로만 얻는다" 라고 적고 있으므로 파사드 자신만 예외로 뒀다. 남은 1건(CommunityService)은 계속 추적한다. 규칙 문구를 고치면 ArchUnit 이 새 키로 baseline 을 만들고 옛 파일이 고아로 남는데 자동으로 지워지지 않아 손으로 정리했다. - core 기반 → 도메인 참조 50 → 0 - ArchUnit baseline 291 → 241 (고아 baseline 1개 정리 포함) - 남은 241건 중 237건이 도메인 경계 한 규칙이다 검증: compileJava·compileTestJava 통과, ArchitectureRulesTest 통과. 전체 스위트는 다른 세션이 같은 저장소에서 테스트를 돌리는 중이라(build 디렉터리 잠금) 로컬에서 끝까지 돌리지 못했다. CI 가 깨끗한 체크아웃에서 돌린다. Refs #132
This was referenced Oct 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Refs #132 (8단계)
"core 기반 패키지는 domain 을 의존하지 않는다" 위반 50건은 전부 인증·인가 기반 코드였습니다. 다섯 덩어리였고, 각각 원인이 달랐습니다.
CurrentUserFacade(15)User,UserRepositorydomain/user/appKakaoUtil(11)KakaoOAuthToken,KakaoProfile…external/kakao로ConsentGuardConsentRequiredException이 서비스 안의 중첩 클래스여서, 예외를 가리키려면 서비스를 import 해야 했다CustomUserDetailsService(8)User,UserRepositorydomain/user/security로 옮기고SecurityConfig는 스프링의UserDetailsService인터페이스로 받는다JwtAuthenticationFilter(6)JwtServiceAccessTokenVerifier포트옮기는 방향이 중요했습니다
셋은 core → 도메인으로 옮겼고, 둘은 반대로 핸들러·필터가 도메인을 보지 않도록 경계를 세웠습니다.
기준은 "누가 그 규칙의 주인인가" 였습니다. 자격 증명으로 사용자를 찾는 일과 현재 사용자를 꺼내는 일은 사용자 도메인의 규칙입니다. 반대로 토큰 서명 검증과 예외 → HTTP 상태 변환은 기반 코드의 일이고, 그쪽이 도메인 타입을 알 필요가 없습니다.
카카오 DTO 가 잘못된 자리에 있던 것이 실제 문제였습니다
KakaoProfile·KakaoAccount·KakaoProperties·KakaoProfileInfo·KakaoOAuthToken은 카카오가 주는 JSON 모양입니다 — 필드명이connected_at,thumbnail_image_url처럼 snake_case 인 것이 그 증거입니다. 그것이domain/user/dto/response(우리가 프런트에 주는 응답을 모아 둔 패키지)에 섞여 있었습니다. 카카오가 응답을 바꾸면 우리 API 응답 패키지가 바뀌는 셈입니다.규칙도 한 줄 고쳤습니다
CurrentUserFacade가 도메인으로 들어오자 "도메인은SecurityContextHolder를 직접 쓰지 않는다" 에 걸렸습니다 — 그 클래스의 존재 이유가 바로 그 접근을 혼자 하는 것인데도요. 규칙의because가 이미 "현재 사용자는 CurrentUserFacade 로만 얻는다" 라고 적고 있으므로 파사드 자신만 예외로 두었습니다. 남은 1건(CommunityService가 직접 꺼내는 곳)은 계속 추적합니다.숫자
검증 범위 — 읽어 주세요
compileJava·compileTestJava통과,ArchitectureRulesTest통과. 전체 스위트는 로컬에서 끝까지 돌리지 못했습니다 — 다른 세션이 같은 저장소에서 테스트를 돌리고 있어build/test-results가 잠겨 있었습니다. CI 가 깨끗한 체크아웃에서 돌리므로 그 결과로 확인해 주세요.같은 이유로 이 브랜치에는 그 세션의 작업 파일 3개(
CareFacilityRepository,AdmissionCandidateService,PolicyInitializationService)를 의도적으로 담지 않았습니다.