package com.hlab.yanalyst.domain.channel; import com.hlab.yanalyst.global.common.ApiResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.Map; @RestController @RequestMapping("/api/recommended-channels") @RequiredArgsConstructor @Tag(name = "Recommended Channel API", description = "자동 발굴된 추천 채널(떡상 Shorts)") public class RecommendedChannelController { private final RecommendedChannelRepository repository; private final ChannelDiscoveryService discoveryService; private final ChannelService channelService; @GetMapping @Operation(summary = "추천 채널 목록", description = "status(NEW|EXCLUDED|REGISTERED, 기본 NEW)를 배율 내림차순으로 반환") public ApiResponse> list(@RequestParam(defaultValue = "NEW") String status) { return ApiResponse.ok(repository.findByStatusOrderByRatioDesc(status)); } @PostMapping("/{id}/register") @Operation(summary = "내 채널 등록", description = "추천 채널을 내 채널로 등록하고 REGISTERED 처리") @Transactional public ApiResponse register(@PathVariable Long id) { RecommendedChannel rc = repository.findById(id) .orElseThrow(() -> new IllegalArgumentException("추천 채널을 찾을 수 없습니다: " + id)); channelService.saveChannelFromUrl("https://www.youtube.com/channel/" + rc.getChannelId()); rc.setStatus("REGISTERED"); repository.save(rc); return ApiResponse.ok(null); } @PostMapping("/{id}/exclude") @Operation(summary = "추천 제외", description = "다음 발굴에서 다시 뜨지 않게 EXCLUDED 처리") @Transactional public ApiResponse exclude(@PathVariable Long id) { RecommendedChannel rc = repository.findById(id) .orElseThrow(() -> new IllegalArgumentException("추천 채널을 찾을 수 없습니다: " + id)); rc.setStatus("EXCLUDED"); repository.save(rc); return ApiResponse.ok(null); } @PostMapping("/{id}/restore") @Operation(summary = "제외 복원", description = "EXCLUDED 를 다시 NEW(추천 목록)로 되돌린다") @Transactional public ApiResponse restore(@PathVariable Long id) { RecommendedChannel rc = repository.findById(id) .orElseThrow(() -> new IllegalArgumentException("추천 채널을 찾을 수 없습니다: " + id)); rc.setStatus("NEW"); repository.save(rc); return ApiResponse.ok(null); } @PostMapping("/run") @Operation(summary = "수동 발굴 실행", description = "스케줄과 동일한 발굴을 즉시 1회 실행") public ApiResponse> run() { return ApiResponse.ok(discoveryService.runDiscovery()); } }