Skip to content

Web app 서버 통합 - 강의 컨텐츠 수정#127

Open
hot666666 wants to merge 32 commits into
DOROEDU:developfrom
hot666666:feat-120-content-update
Open

Web app 서버 통합 - 강의 컨텐츠 수정#127
hot666666 wants to merge 32 commits into
DOROEDU:developfrom
hot666666:feat-120-content-update

Conversation

@hot666666
Copy link
Copy Markdown

@hot666666 hot666666 commented Dec 10, 2023

PR 타입(하나 이상의 PR 타입을 선택해주세요)

  • 기능 추가
  • 기능 삭제
  • 버그 수정
  • 의존성, 환경 변수, 빌드 관련 코드 업데이트

반영 브랜치

hot666666/feat-120-content-update -> DOROEDU/develop

변경 사항

강의 컨텐츠 수정

  • 기존 LectureContent 엔티티는 images필드를 통해 LectureContentImage 엔티티와 일대다 매핑
  • LectureContentImage는 S3에 올라간 url 필드를 가짐

엔티티

  • image

테스트 결과

postman 테스트

verifyAuthNum2 - 기존 메서드와 달리 인증에 사용된 번호를 세션처럼 이용
- SendAuthNumReq의 MessageType에 TEMP 추가
- VerifyAuthNumReq, VerifyAuthNumRes 수정
인증된 전화번호를 위한 세션을 생성해주는 엔드포인트 추가("message/verify2")
- MessageControllerTest.java
- MessageServiceImplTest.java
- MessageServiceTestSetup.java
세션필터는 "/education-application/**" 주소에만 적용됨
요청 헤더의 Session-Id를 통해 휴대폰 번호를 컨트롤러에 전달
- SessionFilter
- SessionFilterHandler
- SessionException
- SecurityConfig
@order을 추가해 JwtAuthenticationFilter 순서 지정
- EducationApplicationReq
- RetrieveApplicationReq
세션인증과 관련된 오류 enum 추가
세션필터를 통해 phoneNumber를 얻어 EducationApplication API에서 사용합니다
인증된 핸드폰 번호와 같은지 검사하는 로직 추가
- EducationApplicationService
- ClassGroupService
인증된 핸드폰 번호와 엔티티 아이디를 한번에 검색하는 메서드 추가
기존 테스트에서 인증된 핸드폰을 추가한 테스트 업데이트
- EducationApplicationTestSetup
- EducationApplicationApiTest
- EducationApplicationServiceTest
- ClassGroupServiceTest
LectureContentApi에서 이미지 추가 시 발생할 수 있는 오류 Code 추가
관련 없는 항목 import 삭제
- LectureContentDtoReq
  - CreateLectureContentReq
  - UpdateLectureContentReq
  - LectureContentRes
- LectureContentImageDto
  - LectureContentImageReq
  - LectureContentImageRes
이전 LectureContent에서 images 필드를 추가, 이를 통해 LectureContentImage와 매핑
- LectureContent(One-To-Many)
- LectureContentImage
- LectureContentMapper
- LectureContentImageMapper
- LectureContentService, LectureContentImageService
- LectureContentApi
ContentImageS3Service를 만들어 강의 컨텐츠와 관련한 S3 이용기능을 분리함
- ContentImageS3Service, ContentImageS3ServiceImpl
- LecturecontentService, LecturecontentImageService
- LectureContentImage
- Code.LECTURE_CONTENT_INVAILD_IMAGE_COUNT
- ContentImageS3ServiceImplTest
- ContentImageS3Service, ContentImageS3ServiceImpl
- AwsS3ServiceImpl
- LectureContentServiceTest
- LectureContentImageServiceTest
- LectureRepositoryTest
- LectureContentImageReq, LectureContentImageRes
@hot666666 hot666666 changed the title Feat 120 content update Web app 서버 통합 - 강의 컨텐츠 수정 Dec 10, 2023
Comment on lines +42 to +43
@OneToMany(cascade = CascadeType.ALL)
private List<LectureContentImage> images = new ArrayList<>();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

orpanRemove = true를 안설정한 이유가 있나요? 제가 예전에 봤던 내용이라 자세히는 기억이 안나네요 ㅎㅎ..

https://resilient-923.tistory.com/417 해당 블로그에서 cascade에 대해 잘 다루고 있는거 같아 첨부해요!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

몰랐던 좋은 내용이네요.. 스프링에서 데이터베이스 관련해서는 아직 모르는게 많습니다
언젠가 마음을 잡는다면 공부를 할 것 같은데, 하게 된다면 수정하고 싶은게 많을 것 같네요
잘 몰라서 지금까지 작성한 코드들 보면 매핑된 엔티티에서 전부 (엔티티객체+레포지터리 업데이트) 같이 처리했었습니다...
좋은 정보 알아갑니다 😄

public LectureContentRes updateLectureContent(Long id, UpdateLectureContentReq updateLectureContentReq) {
LectureContent lectureContent = findLectureContentById(id);

modelMapper.map(updateLectureContentReq, lectureContent); // 필드있고없고차이 MapStruct와 비교
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 방식대로 하면 Req에 있는 모든 필드들이 전부 entity 로 변경되는건가요??

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

modelMapper.map(updateLectureContentReq, lectureContent)에서
두번째 인자를 기준으로 생각을 하면 편한데, 현재 설정된 ModelMapperConfig에 따르면

updateLectureContentReq과 lectureContent에 동시에 존재하는 필드라면 해당필드값이 전자의 값으로 업데이트가 일어나고
updateLectureContentReq에만 존재하는 필드라면 아무일도 일어나지 않고
lectureContent에만 존재한다면 기존 lectureContent값으로 됩니다

라고 chatGPT와 대화해봤습니다

Comment on lines +75 to +88
void validateDtoFiles(MultipartFile[] files) {
if (files == null) {
// Multipart가 한 개라도 배열에 넣어서 요청해야함
throw new BaseException(Code.JSON_SYNTAX_ERROR);
}
if (files.length > 100) {
throw new BaseException(Code.LECTURE_CONTENT_IMAGE_COUNT_OVER);
}
for (MultipartFile file : files) {
if (file.getSize() > 10485760) { // 10MB
throw new BaseException(Code.LECTURE_CONTENT_IMAGE_SIZE_OVER);
}
}
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 메서드를 서비스 계층 노출되는게 아니라 DTO 내부 메서드로 만들어서 사용하는건 어떻게 생각하나요?
혹은 DTO에서 어노테이션으로 해결은 힘들까요??

저도 확신은 없지만 이러면 어떨까 생각이 들어 comment 남겼습니다!! 😎

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DTO 내부 메서드로 만들어서 사용

이후에 리팩토링 커밋에서 여기부분 관련해서 정리했는데, 생각해보니 해당 검증과정은 DTO 메서드에 넣는게 좋을 것 같네요! 😄

Copy link
Copy Markdown
Collaborator

@weightsforfun weightsforfun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다! 새로운 기능까지 진짜 빠르게 마무리 하셨네요!!
확인하시고 오케이 하시면 머지 할게요!

String getFileNameFrom(String url) {
// UUID(36자) + .jpg(4자) = 파일명(40자)
return url.substring(40);
return url.substring(url.length() - 40);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주석으로 숫자에 대해 설명하는것도 좋고 상수를 만들어서 변수명으로 의미를 남기는 방법도 있을거 같아요!!

취향 차이지만 저는 변수명으로 최대한 풀어내려고 요즘 노력중이거든요!

private static final uuidLenght =36
private static final extenstionLength =4 이런식으로요?

이 상황에서는 애매하긴 한데 매직넘버는 유명한 안티패턴이긴 해서 언급했습니다!! 여기서는 주석이 잘 설명해줘서 괜찮은거 같아요!!

그냥 제 개인적인 취향이었습니다 😎

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋은 방법이에요! 저는 저때 빨리 작성하느라 찜찜해서 일단은 주석달고 나중에 생각하자는 마인드로 작성했었습니다! 역시 윤지용님은 안티 한 명 없는 슈퍼스타네요😎

Comment on lines +185 to +188
Object mappedValue = field.get(mappedRes);
Object originalValue = field.get(originalRes);

assertThat(mappedValue).isEqualTo(originalValue);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋은 방식인거 같네요! 저는 null 값이 없나 정도만 확인했었는데

배워갑니당 😎

@hot666666
Copy link
Copy Markdown
Author

고생하셨습니다! 새로운 기능까지 진짜 빠르게 마무리 하셨네요!! 확인하시고 오케이 하시면 머지 할게요!

기존에 언급하신 내용들에서 수정하면 말하겠습니다!

- ContentImageS3ServiceImpl
- MultipartFileUtils
- CreateLectureContentReq
- LectureContentImageReq
- LectureContentService
- LectureContentImageService
- ContentImageS3ServiceImplTest
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants