Migrate to MyBatis with proper Controller→Service→Mapper layering
- Add MyBatis Spring Boot Starter with XML mappers and domain classes - Create 9 mapper interfaces + XML: Restaurant, Video, Channel, Review, User, Stats, DaemonConfig, Search, Vector - Create 10 domain classes with Lombok: Restaurant, VideoSummary, VideoDetail, VideoRestaurantLink, Channel, Review, UserInfo, DaemonConfig, SiteVisitStats, VectorSearchResult - Create 7 new service classes: RestaurantService, VideoService, ChannelService, ReviewService, UserService, StatsService, DaemonConfigService - Refactor all controllers to be thin (HTTP + auth only), delegating business logic to services - Refactor SearchService, PipelineService, DaemonScheduler, AuthService, YouTubeService to use mappers/services instead of JDBC/repositories - Add Jackson SNAKE_CASE property naming for consistent API responses - Add ClobTypeHandler for Oracle CLOB→String in MyBatis - Add IdGenerator utility for centralized UUID generation - Delete old repository/ package (6 files), JdbcConfig, LowerCaseKeyAdvice - VectorService retains JDBC for Oracle VECTOR type support Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
package com.tasteby.controller;
|
||||
|
||||
import com.tasteby.repository.ChannelRepository;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.tasteby.domain.Channel;
|
||||
import com.tasteby.security.AuthUtil;
|
||||
import com.tasteby.service.CacheService;
|
||||
import com.tasteby.service.ChannelService;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
@@ -14,26 +17,26 @@ import java.util.Map;
|
||||
@RequestMapping("/api/channels")
|
||||
public class ChannelController {
|
||||
|
||||
private final ChannelRepository repo;
|
||||
private final ChannelService channelService;
|
||||
private final CacheService cache;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
public ChannelController(ChannelRepository repo, CacheService cache) {
|
||||
this.repo = repo;
|
||||
public ChannelController(ChannelService channelService, CacheService cache, ObjectMapper objectMapper) {
|
||||
this.channelService = channelService;
|
||||
this.cache = cache;
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public List<Map<String, Object>> list() {
|
||||
public List<Channel> list() {
|
||||
String key = cache.makeKey("channels");
|
||||
String cached = cache.getRaw(key);
|
||||
if (cached != null) {
|
||||
try {
|
||||
var mapper = new com.fasterxml.jackson.databind.ObjectMapper();
|
||||
return mapper.readValue(cached,
|
||||
new com.fasterxml.jackson.core.type.TypeReference<>() {});
|
||||
return objectMapper.readValue(cached, new TypeReference<List<Channel>>() {});
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
var result = repo.findAllActive();
|
||||
var result = channelService.findAllActive();
|
||||
cache.set(key, result);
|
||||
return result;
|
||||
}
|
||||
@@ -46,7 +49,7 @@ public class ChannelController {
|
||||
String channelName = body.get("channel_name");
|
||||
String titleFilter = body.get("title_filter");
|
||||
try {
|
||||
String id = repo.create(channelId, channelName, titleFilter);
|
||||
String id = channelService.create(channelId, channelName, titleFilter);
|
||||
cache.flush();
|
||||
return Map.of("id", id, "channel_id", channelId);
|
||||
} catch (Exception e) {
|
||||
@@ -60,7 +63,7 @@ public class ChannelController {
|
||||
@DeleteMapping("/{channelId}")
|
||||
public Map<String, Object> delete(@PathVariable String channelId) {
|
||||
AuthUtil.requireAdmin();
|
||||
if (!repo.deactivate(channelId)) {
|
||||
if (!channelService.deactivate(channelId)) {
|
||||
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Channel not found");
|
||||
}
|
||||
cache.flush();
|
||||
|
||||
Reference in New Issue
Block a user