728x90
https://yeopseung.tistory.com/281
무신사 2차 코딩테스트 -1
2월 8일 일요일 오후 3시, 대망의 2차 코딩테스트가 시작되었습니다. 그리고 2월 13일 오후 5시 31분, 다행히 합격 메일을 받을 수 있었습니다.이번 무신사 2차 테스트는 'AI 네이티브' 전형이라는 꽤
yeopseung.tistory.com
2편에 이어서
여러가지를 한번에 구현하면 질이 떨어지기 떄문에
Global Exception -> Student (JWT Cookie Login Logout) -> Course -> Professor 순서로 구현을 시작했습니다.
① 아키텍처 설계
AI 도구를 사용하지만, 코드의 전체적인 구조까지 AI에게 맡길 수는 없었습니다. 프롬프트를 입력하기 전, 패키지 구조와 도메인 설계는 제가 직접 먼저 수행했습니다. 제가 짠 탄탄한 뼈대 위에서 AI가 살을 붙이도록 유도해야 유지보수 가능한 코드가 나온다고 판단했기 때문입니다. + 어떤 락을 사용할지?
② 보안과 사용자 경험을 고려한 인증
요구사항엔 없었지만, 실제 수강신청 시스템에 '로그인'이 없다면 말이 안 된다고 생각했습니다. 그래서
JWT 기반의 인증 시스템을 구현하고, 보안을 위해 토큰을 쿠키 에 담아 관리하도록 하여 '내 시간표 조회'나 '수강신청' 시 학생 식별이 자연스럽게 이루어지도록 계획.
③ 객체지향적인 도메인 설계
비즈니스 로직이 서비스 계층에만 비대하게 뭉치는 것을 방지하기 위해, 도메인 엔티티가 스스로 비즈니스 규칙을 처리하도록 객체지향적으로 설계했습니다. 예를 들어, '정원 초과 여부'나 '시간표 중복 확인' 같은 로직은 도메인 객체 내부에서 판단하도록 했습니다.
④ 성능을 고려한 쿼리 튜닝
수강신청은 읽기와 쓰기가 빈번한 시스템입니다. 단순히 JPA 메서드에만 의존하면 N+1 문제나 불필요한 조회가 발생할 수 있습니다. 그래서 병목이 예상되는 복잡한 조회나 대량의 데이터 처리가 필요한 부분은 직접 쿼리를 작성하여 성능을 최적화했습니다.
⑤ 확장성을 고려한 예외 처리
수많은 예외 상황(정원 초과, 이미 신청한 강의, 학점 초과 등)을 일관성 있게 처리하기 위해 전역 예외 처리기를 도입했습니다.
익셉션을 완성했고, 그다음 JWT를 구현하는 프롬프트를 만들었습니다.
Spring Boot 기반의 '학생(Student) 인증 시스템'을 구현해줘. 이전에 만든 `GlobalException`과`AESUtil`을 적극 활용해야 해.
# Requirements
1.Authentication Flow (로그인/로그아웃)
- 로그인 성공 시 JWT(Access Token)를 발급해줘.
- 보안을 위해 토큰은 Body가 아닌
2. HttpOnly Cookie 에 담아서 응답해야 해. (XSS 방지시켜줘 )
- 로그아웃 시 해당 쿠키를 만료시켜줘.
3. Sign Up (회원가입)
-비밀번호는`PasswordEncoder` 로 해싱해줘.
- 전화번호(`phoneNumber`)는
`AESUtil` 을 사용해 암호화해서 DB에 저장하고, 조회할 때 복호화해줘.
- 유효성 검증 로직은`Service` 가 너무 비대해지지 않도록 `AuthValidator` (DB 중복 체크)와 `SignUpValidator`
(형식 체크)로 분리해줘.
4. Developer Experience (커스텀 어노테이션)
-컨트롤러에서 로그인한 사용자의 ID를 쉽게 얻고 싶어.
- `HandlerMethodArgumentResolver` 를 구현해서,
`@LoginStudent Long studentId`
형태로 파라미터를 선언하면 자동으로 토큰을 파싱해서 ID를 주입해주는 기능을 만들어줘.
4. Architecture
- Entity <-> DTO 변환은 `AuthMapper` 클래스에서 정적 메서드로 관리해줘.
- 컨트롤러는 `AuthController` , 서비스는 `AuthService` 로 구성해줘.
----- ------ ------ ------ --------------------그록 내용 -----------------------------------------------------
5. 테스트 코드 역시 구현해야하는데
5-1 JWT가 잘 반환되는지 테스트랑 실제
5-2 SignUp이 되는지
5- 3 유효한 요청일시 학생 정보를 올바르게 반환하는지
5-4 이메일 비밀번호 올바른지
5-5 쿠키가 날라갈 시 403 에러가 잘 뜨는지
5-6로그아웃이 쿠키를 제거가 되는지
5-7 만약 실 서비스에서 사용한다면 필요한 테스트들이 더있으면 구현해주고 정합성 부분 위주로 테스트해줘
---------------------------------------------추가한 프롬프트 ---------------------------------------------------
#참고로 이 구성들은 제가 사이트 제작할때 로그인을 구현하면 하는 방식입니다.
Output
위 요구사항을 충족하는 Controller, Service, Validator, Resolver, Annotation 코드를 작성해줘.
또한 여기서 나온 코드들을 GPT와 제미나이에게 전달했습니다.
문서는 마크다운으로 받기로 했고, 코드 리뷰는 프롬프트로 뽑아서 어떤 점이 수정이 필요한지를 받았습니다.
프롬프트 내용을 -> 다시 커서에게 적용할 수 있도록
XSS란?
XSS은 공격자가 취약한 웹 사이트에 악성 스크립트를 삽입하여, 해당 사이트를 방문하는 사용자들의 브라우저에서 스크립트가 실행되게 하는 공격 방식입니다. 주로 사용자 세션 탈취, 웹 페이지 변조, 피싱 공격 등에 이용되며, 입력값 검증 미흡이 주원인입니다.
요약본
Course 도메인 Entity, Repository, Service, Controller를 구현해줘
Entity Design
- Course는 Professor(N:1)와 TimeSlot(1:N)을 가진다.
- TimeSlot은 "월요일 1교시", "수요일 3교시" 같은 시간표 정보다.
- 조회 시 불필요한 쿼리가 나가지 않도록 모든 연관관계는 Lazy Loading으로 설정해줘.
일단 수강신청 로직도 구현해야 하기 때문에 Repository에는 비관적락 조회 메서드를 미리 만들어주고 쿼리까지 미리 구현해줘
조회 성능
강좌 목록 조회시 TimeSlot 정보를 함께 가져오고 페이지 처리 시 Fetch Join을 같이 쓰면 메모리 이슈가 나는 부분을 해결하기 위한 2-Step 조회를 구현할거야
코스 아이디 만 페이징으로 조회하고
조회된 Id 목록을 Fetch Join으로 상세 정보를 한 번에 가져오게 해줘
조금 다듬어가며 쓴 프롬프트
이러한 과정을 거쳐서 구현 후 시간이 조금 남았습니다.
그래서 추가적으로 통합테스트를 스스로 진행했고, Cors 및 403에러 문제가 계속해서 발생했습니다.
이것을 해결 한후
마지막으로 객체지향적인 설계가 조금 부족했던 부분이 보여서 GPT 코드 리뷰 후 직저 ㅂ수정하는 과정을 거쳤습니다.
728x90