#294 (리뷰/메모): - MemoService.upsert: 동시성 INSERT 시 DuplicateKeyException 폴백 → UPDATE - ReviewService.toggleFavorite: 동시성 INSERT 시 DuplicateKeyException ignored (토글 ON) - ReviewController: rating(0~5) Bean validation 헬퍼, body.rating null/비숫자 → 400 - ReviewMapper.xml getAvgRating: NVL로 0건 시에도 0.0 보장 #295 (채널): - ChannelController.create: typed DataIntegrityViolationException으로 유니크 충돌 감지 (제약명 문자열 매칭 폐기) - ChannelController.create: channel_id/channel_name null/빈값 → 400 - ChannelService.deactivate: "UC..." 형식 검증으로 명시적 분기 (이전 폴백 방식의 의도 모호함 해결) - ChannelMapper.xml findByChannelId: description/tags/sort_order까지 SELECT #290 (식당 CRUD): - RestaurantController: @PreDestroy로 virtual thread executor shutdown - RestaurantController: 캐시 역직렬화 실패를 silent ignore → log.warn + cache.del 자동 evict - RestaurantController: setTablingUrl/setCatchtableUrl URL 스킴 화이트리스트 검증 - CacheService: 단일 키 del() 메서드 추가 후속 분리: - #333 (#290 DTO 화이트리스트 + DDG 대체) - #334 (#295 cache.flush 세분화 + scan 비동기) - #335 (#294 테스트) Refs: #290 #294 #295
51 lines
1.7 KiB
Java
51 lines
1.7 KiB
Java
package com.tasteby.service;
|
|
|
|
import com.tasteby.domain.Channel;
|
|
import com.tasteby.mapper.ChannelMapper;
|
|
import com.tasteby.util.IdGenerator;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import java.util.List;
|
|
|
|
@Service
|
|
public class ChannelService {
|
|
|
|
private final ChannelMapper mapper;
|
|
|
|
public ChannelService(ChannelMapper mapper) {
|
|
this.mapper = mapper;
|
|
}
|
|
|
|
public List<Channel> findAllActive() {
|
|
return mapper.findAllActive();
|
|
}
|
|
|
|
public String create(String channelId, String channelName, String titleFilter) {
|
|
String id = IdGenerator.newId();
|
|
mapper.insert(id, channelId, channelName, titleFilter);
|
|
return id;
|
|
}
|
|
|
|
public boolean deactivate(String channelId) {
|
|
if (channelId == null || channelId.isBlank()) return false;
|
|
// #295 — 입력 형식으로 명시적 분기:
|
|
// "UC..."(24 chars) 형식 → YouTube channel_id로 비활성화
|
|
// 그 외(32-char hex UUID 등) → DB id로 비활성화
|
|
// 이전: channel_id 시도 → 0이면 id 시도. 우연히 UC가 hex와 같을 확률은 0이지만
|
|
// 가독성/의도 명확성 + 잘못된 폴백 차단을 위해 명시화.
|
|
boolean looksLikeYouTubeId = channelId.startsWith("UC") && channelId.length() == 24;
|
|
int rows = looksLikeYouTubeId
|
|
? mapper.deactivateByChannelId(channelId)
|
|
: mapper.deactivateById(channelId);
|
|
return rows > 0;
|
|
}
|
|
|
|
public Channel findByChannelId(String channelId) {
|
|
return mapper.findByChannelId(channelId);
|
|
}
|
|
|
|
public void update(String id, String description, String tags, Integer sortOrder) {
|
|
mapper.updateChannel(id, description, tags, sortOrder);
|
|
}
|
|
}
|