diff --git a/src/main/java/me/thinkcat/opic/practice/config/security/SecurityConfig.java b/src/main/java/me/thinkcat/opic/practice/config/security/SecurityConfig.java index fbf69c7..9dcf79b 100644 --- a/src/main/java/me/thinkcat/opic/practice/config/security/SecurityConfig.java +++ b/src/main/java/me/thinkcat/opic/practice/config/security/SecurityConfig.java @@ -38,7 +38,8 @@ public class SecurityConfig { "/actuator/**", "/api/v1/answers/internal/**", "/api/v1/questions/internal/**", - "/api/v1/drill-answers/internal/**" + "/api/v1/drill-answers/internal/**", + "/api/v1/notices/**" }; @Bean diff --git a/src/main/java/me/thinkcat/opic/practice/controller/NoticeController.java b/src/main/java/me/thinkcat/opic/practice/controller/NoticeController.java new file mode 100644 index 0000000..4582b37 --- /dev/null +++ b/src/main/java/me/thinkcat/opic/practice/controller/NoticeController.java @@ -0,0 +1,32 @@ +package me.thinkcat.opic.practice.controller; + +import lombok.RequiredArgsConstructor; +import me.thinkcat.opic.practice.dto.CommonResponse; +import me.thinkcat.opic.practice.dto.response.NoticeResponse; +import me.thinkcat.opic.practice.service.NoticeService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("/api/v1/notices") +@RequiredArgsConstructor +public class NoticeController { + + private final NoticeService noticeService; + + @GetMapping + public ResponseEntity>> getNotices() { + List notices = noticeService.getNotices(); + return ResponseEntity.ok( + CommonResponse.>builder() + .success(true) + .result(notices) + .message("Notices retrieved successfully") + .build() + ); + } +} diff --git a/src/main/java/me/thinkcat/opic/practice/dto/mapper/NoticeMapper.java b/src/main/java/me/thinkcat/opic/practice/dto/mapper/NoticeMapper.java new file mode 100644 index 0000000..2fd6cf2 --- /dev/null +++ b/src/main/java/me/thinkcat/opic/practice/dto/mapper/NoticeMapper.java @@ -0,0 +1,18 @@ +package me.thinkcat.opic.practice.dto.mapper; + +import me.thinkcat.opic.practice.dto.response.NoticeResponse; +import me.thinkcat.opic.practice.entity.Notice; + +public class NoticeMapper { + + private NoticeMapper() {} + + public static NoticeResponse toResponse(Notice notice) { + return NoticeResponse.builder() + .id(notice.getId()) + .title(notice.getTitle()) + .content(notice.getContent()) + .createdAt(notice.getCreatedAt()) + .build(); + } +} diff --git a/src/main/java/me/thinkcat/opic/practice/dto/response/NoticeResponse.java b/src/main/java/me/thinkcat/opic/practice/dto/response/NoticeResponse.java new file mode 100644 index 0000000..ca4eb77 --- /dev/null +++ b/src/main/java/me/thinkcat/opic/practice/dto/response/NoticeResponse.java @@ -0,0 +1,15 @@ +package me.thinkcat.opic.practice.dto.response; + +import lombok.Builder; +import lombok.Getter; + +import java.time.LocalDateTime; + +@Getter +@Builder +public class NoticeResponse { + private Long id; + private String title; + private String content; + private LocalDateTime createdAt; +} diff --git a/src/main/java/me/thinkcat/opic/practice/entity/Notice.java b/src/main/java/me/thinkcat/opic/practice/entity/Notice.java new file mode 100644 index 0000000..c06f157 --- /dev/null +++ b/src/main/java/me/thinkcat/opic/practice/entity/Notice.java @@ -0,0 +1,25 @@ +package me.thinkcat.opic.practice.entity; + +import jakarta.persistence.*; +import lombok.*; +import org.hibernate.annotations.Where; + +@Entity +@Table(name = "notices") +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Where(clause = "deleted_at IS NULL") +public class Notice extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, length = 200) + private String title; + + @Column(nullable = false, columnDefinition = "TEXT") + private String content; +} diff --git a/src/main/java/me/thinkcat/opic/practice/repository/NoticeRepository.java b/src/main/java/me/thinkcat/opic/practice/repository/NoticeRepository.java new file mode 100644 index 0000000..78cdfc2 --- /dev/null +++ b/src/main/java/me/thinkcat/opic/practice/repository/NoticeRepository.java @@ -0,0 +1,10 @@ +package me.thinkcat.opic.practice.repository; + +import me.thinkcat.opic.practice.entity.Notice; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface NoticeRepository extends JpaRepository { + List findAllByOrderByCreatedAtDesc(); +} diff --git a/src/main/java/me/thinkcat/opic/practice/service/NoticeService.java b/src/main/java/me/thinkcat/opic/practice/service/NoticeService.java new file mode 100644 index 0000000..b05224d --- /dev/null +++ b/src/main/java/me/thinkcat/opic/practice/service/NoticeService.java @@ -0,0 +1,25 @@ +package me.thinkcat.opic.practice.service; + +import lombok.RequiredArgsConstructor; +import me.thinkcat.opic.practice.dto.mapper.NoticeMapper; +import me.thinkcat.opic.practice.dto.response.NoticeResponse; +import me.thinkcat.opic.practice.repository.NoticeRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class NoticeService { + + private final NoticeRepository noticeRepository; + + public List getNotices() { + return noticeRepository.findAllByOrderByCreatedAtDesc() + .stream() + .map(NoticeMapper::toResponse) + .toList(); + } +}