diff --git a/docs/error_code.md b/docs/error_code.md index 89e691d..d479ceb 100644 --- a/docs/error_code.md +++ b/docs/error_code.md @@ -58,6 +58,10 @@ - **COMMENT404: 존재하지 않는 댓글입니다.** +## ✅ **Live Session 오류** + +- **LIVE_SESSION404: 존재하지 않는 Live Session id 값입니다.** + --- ## ✅ **페이징 오류** diff --git a/src/main/java/com/woori/codeshare/room/controller/RoomController.java b/src/main/java/com/woori/codeshare/room/controller/RoomController.java index c32dac3..1668ee1 100644 --- a/src/main/java/com/woori/codeshare/room/controller/RoomController.java +++ b/src/main/java/com/woori/codeshare/room/controller/RoomController.java @@ -2,6 +2,8 @@ import com.woori.codeshare.global.response.ApiResponse; import com.woori.codeshare.global.response.ResponseCode; +import com.woori.codeshare.room.controller.dto.LiveSessionRequestDTO; +import com.woori.codeshare.room.controller.dto.LiveSessionResponseDTO; import com.woori.codeshare.room.controller.dto.RoomRequestDTO; import com.woori.codeshare.room.controller.dto.RoomResponseDTO; import com.woori.codeshare.room.service.RoomService; @@ -54,5 +56,31 @@ public ResponseEntity> enterRoom( RoomResponseDTO.RoomEnterResponse responseDTO = roomService.enterRoomByUuid(uuid, password); return ResponseEntity.ok(ApiResponse.of(ResponseCode.CONFIRM, responseDTO)); } + + /** + * 현재 코드 세션 저장 API + */ + @PostMapping("/{roomId}/live-session/save") + @Operation(summary = "현재 코드 세션 저장 API", description = "특정 방의 실시간 코드 내용을 저장합니다.") + public ResponseEntity> saveLiveSession( + @PathVariable Long roomId, + @RequestBody LiveSessionRequestDTO.LiveSessionRequest request) { + + LiveSessionResponseDTO.LiveSessionResponse response = roomService.saveLiveSession(roomId, request); + return ResponseEntity.ok(ApiResponse.of(ResponseCode.SUCCESS, response)); + } + + /** + * 현재 코드 세션 조회 API + */ + @GetMapping("/{roomId}/live-session") + @Operation(summary = "현재 코드 세션 조회 API", description = "특정 방의 실시간 코드 내용을 조회합니다.") + public ResponseEntity> getLiveSession( + @PathVariable Long roomId) { + + LiveSessionResponseDTO.LiveSessionResponse response = roomService.getLiveSession(roomId); + return ResponseEntity.ok(ApiResponse.of(ResponseCode.SUCCESS, response)); + } + } diff --git a/src/main/java/com/woori/codeshare/room/controller/dto/LiveSessionRequestDTO.java b/src/main/java/com/woori/codeshare/room/controller/dto/LiveSessionRequestDTO.java new file mode 100644 index 0000000..f85e30d --- /dev/null +++ b/src/main/java/com/woori/codeshare/room/controller/dto/LiveSessionRequestDTO.java @@ -0,0 +1,15 @@ +package com.woori.codeshare.room.controller.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +public class LiveSessionRequestDTO { + + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class LiveSessionRequest { + private String code; + } +} diff --git a/src/main/java/com/woori/codeshare/room/controller/dto/LiveSessionResponseDTO.java b/src/main/java/com/woori/codeshare/room/controller/dto/LiveSessionResponseDTO.java new file mode 100644 index 0000000..07f3e84 --- /dev/null +++ b/src/main/java/com/woori/codeshare/room/controller/dto/LiveSessionResponseDTO.java @@ -0,0 +1,21 @@ +package com.woori.codeshare.room.controller.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +public class LiveSessionResponseDTO { + + @Getter + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class LiveSessionResponse { + private Long roomId; + private String code; + private LocalDateTime updatedAt; + } +} diff --git a/src/main/java/com/woori/codeshare/room/domain/LiveSession.java b/src/main/java/com/woori/codeshare/room/domain/LiveSession.java new file mode 100644 index 0000000..2260554 --- /dev/null +++ b/src/main/java/com/woori/codeshare/room/domain/LiveSession.java @@ -0,0 +1,28 @@ +package com.woori.codeshare.room.domain; + +import com.woori.codeshare.global.config.BaseDateTimeEntity; +import jakarta.persistence.*; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Entity +@Data +@NoArgsConstructor +public class LiveSession extends BaseDateTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToOne + @JoinColumn(name = "room_id", nullable = false) + private Room room; + + @Lob + private String code; + + public LiveSession(Room room) { + this.room = room; + this.code = ""; + } +} diff --git a/src/main/java/com/woori/codeshare/room/exception/RoomErrorCode.java b/src/main/java/com/woori/codeshare/room/exception/RoomErrorCode.java index 4dd5345..09ce871 100644 --- a/src/main/java/com/woori/codeshare/room/exception/RoomErrorCode.java +++ b/src/main/java/com/woori/codeshare/room/exception/RoomErrorCode.java @@ -12,7 +12,8 @@ public enum RoomErrorCode implements BaseErrorCode { DUPLICATE_ROOM_TITLE(HttpStatus.BAD_REQUEST, "ROOM400", "이미 동일한 이름의 방이 존재합니다."), INVALID_PASSWORD(HttpStatus.FORBIDDEN, "ROOM403", "방 비밀번호가 잘못 되었습니다."), - ROOM_NOT_FOUND(HttpStatus.NOT_FOUND, "ROOM404", "존재하지 않는 방입니다."); + ROOM_NOT_FOUND(HttpStatus.NOT_FOUND, "ROOM404", "존재하지 않는 방입니다."), + LIVE_SESSION_NOT_FOUND(HttpStatus.NOT_FOUND, "LIVE_SESSION404", "존재하지 않는 Live Session id 값입니다."); private final HttpStatus status; private final String code; diff --git a/src/main/java/com/woori/codeshare/room/repository/LiveSessionRepository.java b/src/main/java/com/woori/codeshare/room/repository/LiveSessionRepository.java new file mode 100644 index 0000000..f9c0927 --- /dev/null +++ b/src/main/java/com/woori/codeshare/room/repository/LiveSessionRepository.java @@ -0,0 +1,12 @@ +package com.woori.codeshare.room.repository; + +import com.woori.codeshare.room.domain.LiveSession; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface LiveSessionRepository extends JpaRepository { + Optional findByRoom_RoomId(Long roomId); +} diff --git a/src/main/java/com/woori/codeshare/room/service/RoomService.java b/src/main/java/com/woori/codeshare/room/service/RoomService.java index 54a681e..b7f2433 100644 --- a/src/main/java/com/woori/codeshare/room/service/RoomService.java +++ b/src/main/java/com/woori/codeshare/room/service/RoomService.java @@ -1,12 +1,17 @@ package com.woori.codeshare.room.service; +import com.woori.codeshare.room.controller.dto.LiveSessionRequestDTO; +import com.woori.codeshare.room.controller.dto.LiveSessionResponseDTO; import com.woori.codeshare.room.controller.dto.RoomRequestDTO; import com.woori.codeshare.room.controller.dto.RoomResponseDTO; +import com.woori.codeshare.room.domain.LiveSession; import com.woori.codeshare.room.domain.Room; import com.woori.codeshare.room.exception.RoomErrorCode; import com.woori.codeshare.room.exception.RoomException; +import com.woori.codeshare.room.repository.LiveSessionRepository; import com.woori.codeshare.room.repository.RoomRepository; +import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; @@ -18,6 +23,7 @@ public class RoomService { private final RoomRepository roomRepository; + private final LiveSessionRepository liveSessionRepository; private final BCryptPasswordEncoder passwordEncoder; /** @@ -76,5 +82,47 @@ public RoomResponseDTO.RoomEnterResponse enterRoomByUuid(String uuid, String raw .createdAt(room.getCreatedAt()) .build(); } + + /** + * 현재 코드 세션 저장 + */ + @Transactional + public LiveSessionResponseDTO.LiveSessionResponse saveLiveSession(Long roomId, LiveSessionRequestDTO.LiveSessionRequest request) { + Room room = roomRepository.findById(roomId) + .orElseThrow(() -> new RoomException(RoomErrorCode.ROOM_NOT_FOUND)); + + // 기존 Live Session이 존재하면 업데이트, 없으면 새로 생성 + LiveSession liveSession = liveSessionRepository.findByRoom_RoomId(roomId) + .orElse(new LiveSession(room)); + + liveSession.setCode(request.getCode()); + liveSessionRepository.save(liveSession); + + + return LiveSessionResponseDTO.LiveSessionResponse.builder() + .roomId(roomId) + .code(liveSession.getCode()) + .updatedAt(liveSession.getUpdatedAt()) + .build(); + } + + /** + * 현재 코드 세션 조회 + */ + @Transactional() + public LiveSessionResponseDTO.LiveSessionResponse getLiveSession(Long roomId) { + Room room = roomRepository.findById(roomId) + .orElseThrow(() -> new RoomException(RoomErrorCode.ROOM_NOT_FOUND)); + + LiveSession liveSession = liveSessionRepository.findByRoom_RoomId(roomId) + .orElseThrow(() -> new RoomException(RoomErrorCode.LIVE_SESSION_NOT_FOUND)); + + return LiveSessionResponseDTO.LiveSessionResponse.builder() + .roomId(roomId) + .code(liveSession.getCode()) + .updatedAt(liveSession.getUpdatedAt()) + .build(); + } + }