Open
Conversation
[변경사항 요약] - 제공 받은 프론트엔드 빌드 산출물을 static/ 디렉토리에 추가하여 Spring 기반 정적 리소스 서빙 구성 - OpenAPI 스펙 요구사항에 맞춰 Swagger 설정 및 DTO 필드명을 camelCase 기준으로 정리 - ChannelDto.Response의 memberIds → participantIds로 변경하여 프론트엔드 응답 필드명과 일치 - UserStatusDto의 lastActiveAt 관련 필드명을 newLastActiveAt으로 수정 - UserDto.Response의 isOnline → online으로 변경하여 프론트엔드 응답 파싱 오류 방지 - PRIVATE 채널에서 참여자가 1명만 남을 경우 프론트 크래시 방지를 위한 임시 필터링 로직 추가 ※ 정적 리소스 연동 후 화면 기반 테스트를 통해 API 응답 구조 불일치로 발생하는 런타임 오류를 보완함
- Dockerfile 제거 - Railway 환경변수(RAILPACK_JDK_VERSION)를 통한 JDK 버전 설정 - plain.jar 생성 방지를 위해 Gradle jar task 비활성화 - bootJar만 생성되도록 설정하여 Railway 실행 아티팩트 충돌 방지 ※ Docker 이미지 기반 배포에서 Railway 기본 Railpack 배포 방식으로 전환
[변경사항 요약] - BaseEntity를 entity/base 패키지로 이동하고 BaseUpdatableEntity 도입 - 엔티티 공통 필드 상속 구조 정립 - UUID 기반 참조 제거 후 객체 참조(User, Channel 등) 방식으로 전환 - Serializable 인터페이스 제거 (JPA 도입 대비) - 엔티티 구조 변경에 따른 서비스 및 Repository 계층 전반 리팩터링
[변경사항 요약] - ERD 기반으로 도메인 엔티티에 JPA 매핑 정보 반영 - @entity, @table 적용 - @column, @Enumerated 적용 - @manytoone, @OnetoOne, @onetomany 연관관계 매핑 - @joincolumn, @jointable 설정 - 부모-자식 관계 및 생명주기 경계를 고려하여 영속성 전이 정책 정의 - Aggregate 내부 관계에 cascade 적용 - 고아 객체 제거(orphanRemoval) 설정 - DB 외래키 제약 조건과 객체 그래프 간 책임 경계 정리 - 단순 참조 관계는 DB FK에 위임 - 강한 생명주기 종속 관계는 JPA 레벨에서 관리
[변경사항 요약] - FileRepository, JCFRepository 삭제 및 관련 의존성 제거 - JpaRepository 상속 및 도메인별 쿼리 메서드 적용 - 영속성 컨텍스트 특징(변경 감지, 지연 로딩) 반영 및 서비스 로직 리팩터링 - @transactional을 활용한 트랜잭션 경계 설정 및 데이터 일관성 보장"
[변경사항 요약] - 기존 Inner Record 기반 DTO 구조를 Flat 형식으로 분리 및 재구성 - MapStruct 라이브러리 도입을 통한 Entity-DTO 매핑 자동화 및 간소화 - 매퍼 컴포넌트 도입과 DTO 구조 재구성에 따른 Service, Controller 리팩터링 수행
[변경사항 요약]
- BinaryContent에서 bytes 제거 및 로컬 파일 시스템 저장 방식 도입
- BinaryContentStorage 인터페이스 및 Local 디스크 구현체 추가
- Message, ReadStatus 엔티티 생성자 기반 리팩토링 (assign 메서드 제거)
- .gitignore 수정: .idea 폴더 전체 제외 및 uploads 경로 추가
- 파일 다운로드 API 구현 (GET /api/binaryContents/{id}/download)"
[변경사항 요약] - API v1.1 명세 및 정적 리소스 v1.1.4 도입에 따른 도메인 로직 및 컨트롤러 일부 리팩터링 - 유저 상태(UserStatus) 매핑 오류 수정 및 API 규격에 맞는 데이터 응답 구조 정합성 확보
[주요 변경사항]
- N+1 문제 해결: Fetch Join 및 @EntityGraph를 활용하여 연관 엔티티 일괄 조회 최적화
- 페이지네이션 리팩토링: 기존 오프셋 방식에서 커서 기반 페이지네이션으로 전환 (v1.2 스펙 준수)
- OSIV 비활성화 대응: open-in-view: false 설정 및 서비스 레이어 조회 메서드 전용 트랜잭션 적용
- 정적 리소스 v1.2.4 호환성 이슈 보고:
* 현상: 메시지 생성 시 응답 DTO의 lastMessageAt이 null로 반환되어 프론트엔드 읽음 처리 하이라이트가 무한 반복되는 현상 식별
* 원인 분석: 메시지 저장 시점과 매퍼의 최신 메시지 조회 시점 간의 영속성 컨텍스트 불일치 의심
* 특이사항: 해당 이슈는 현재 진행 중이며, 임시 조치 대신 구조적인 해결을 위해 추가 분석 예정
- API v1.2 사양 준수: PageResponse 구조 변경 및 관련 Controller/Service/Repository 전면 리팩토링
[주요 변경사항] 1. DTO 구조 개선: ReadStatus/Message 응답 시 객체 대신 UUID 식별자 반환하도록 수정 (정적 리소스 규격 준수) 2. 연관관계 정규화: Message-BinaryContent 관계를 @manytomany에서 1:N(@onetomany) 단방향 매핑으로 변경 3. N+1 문제 해결: ChannelMapper 내 DB 조회 로직 제거 및 Service 레이어에서 Map을 활용한 Batch Fetching 적용 4. 데이터 정합성 보장: saveAndFlush() 적용으로 JPA Auditing 시점 동기화 (createdAt null 이슈 방지) 5. 페이지네이션 교정: PageResponse 내 nextCursor 값을 페이지 번호에서 마지막 요소의 createdAt(Instant)으로 수정
[주요 변경사항] 1. 커서 기반 페이징 정합성 확보 - 요청(cursor)과 응답(nextCursor) 기준을 모두 Instant로 통일하여 정합성 해결 2. N+1 문제 추가 해결 및 최적화 - 채널 조회: Channel-ReadStatus-User 연관 객체 일괄 조회를 통해 지연 로딩 방지 - 메시지 조회: Author Fetch Join 및 Attachments @batchsize 적용으로 DTO 변환 시 쿼리 폭탄 방어 - 메모리 페이징 방지: 컬렉션 Fetch Join을 제거하여 실제 DB 레벨 페이징(Limit) 활성화 3. 도메인 로직 및 매핑 규격 수정 - 채널 수정 API: Dirty Checking이 정상 동작하도록 수정하여 기능 복구 - 매핑 준수: Message-BinaryContent 관계를 조인 테이블 기반 1:N 단방향 매핑으로 유지
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.
기본 요구사항
API 명세
프론트엔드 소스 코드는 참고용으로만 활용하세요. 수정하여 활용하는 경우 이어지는 요구사항 또는 미션을 수행하는 데 어려움이 있을 수 있습니다.
데이터베이스
discodeitdiscodeit_userdiscodeit1234Spring Data JPA 적용하기
application.yaml파일에 작성하세요.application.yaml파일에 작성하세요.엔티티 정의하기
com.sprint.mission.discodeit.entity.basecreatedAt,updatedAt속성이 자동으로 설정되도록 구현하세요.@CreatedDate,@LastModifiedDate연관관계 매핑 정리
@Entity,@Table@Column,@Enumerated@OneToMany,@OneToOne,@ManyToOne@JoinColumn,@JoinTablecascade,orphanRemoval레포지토리와 서비스에 JPA 도입하기
트랜잭션,영속성 전이,변경 감지,지연로딩DTO 적극 도입하기
DTO를 도입한 이유
Entity를 그대로 노출할 경우 발생할 수 있는 문제
DTO 도입의 장점
com.sprint.mission.discodeit.mapperBinaryContent 저장 로직 고도화
데이터베이스에 이미지와 같은 파일을 저장하면 성능 상 불리한 점이 많습니다. 따라서 실제 바이너리 데이터는 별도의 공간에 저장하고, 데이터베이스에는 바이너리 데이터에 대한 메타 정보(파일명, 크기, 유형 등)만 저장하는 것이 좋습니다.
BinaryContent 엔티티는 파일의 메타 정보(
fileName,size,contentType)만 표현하도록bytes속성을 제거하세요.BinaryContent의
byte[]데이터 저장을 담당하는 인터페이스를 설계하세요.저장 매체의 확장성(로컬 저장소, 원격 저장소)을 고려해 인터페이스부터 설계합니다.
com.sprint.mission.discodeit.storageGET /api/binaryContents/{binaryContentId}/downloadResponseEntity<?>discodeit.storage.type값이local인 경우에만 Bean으로 등록되어야 합니다.Path rootdiscodeit.storage.local.root-path설정값을 정의하고, 이 값을 통해 주입합니다.void init()Path resolvePath(UUID){root}/{UUID}put,get메소드에서 호출해 일관된 파일 경로 규칙을 유지합니다.ResponseEntity<Resource> donwload(BinaryContentDto)get메소드를 통해 파일의 바이너리 데이터를 조회합니다.ResponseEntity<Resource>응답을 생성 후 반환합니다.페이징과 정렬
com.sprint.mission.discodeit.dto.responsecom.sprint.mission.discodeit.mapper심화 요구사항
N+1 문제
읽기전용 트랜잭션 활용
OSIV 비활성화하기
페이지네이션 최적화
오프셋 페이지네이션 (Offset Pagination)
특징
LIMIT과OFFSET을 활용하여 구현장점
단점
커서 페이지네이션 (Cursor Pagination)
특징
장점
단점
프론트엔드 소스 코드는 참고용으로만 활용하세요. 수정하여 활용하는 경우 이어지는 요구사항 또는 미션을 수행하는 데 어려움이 있을 수 있습니다.
MapStruct 적용