#275 (데몬): - DaemonConfigService.updateConfig: 정수 필드 가드 (비숫자/0/음수 → 400) - DaemonScheduler: 외부 호출(scan/process) try-finally로 updateLastX 보장 (예외 시에도 다음 cron까지 backoff) - DaemonController.getConfig: AuthUtil.requireAdmin() 추가 (운영 설정 노출 차단) #276 (캐시): - CacheService 생성자: ping을 try-with-resources로 자원 누수 차단, ConnectionFactory null 가드 - makeKey: null/빈 parts 가드 (잘못된 키 생성 방지) #274 (통계): - SiteVisitStats: int → long (21억 누적 시 오버플로 방지) - StatsMapper: getTodayVisits/getTotalVisits long 반환 - StatsService.recordVisit: 자정 경계 동시성 DataIntegrityViolationException 1회 재시도, 2회 실패 시 1건 손실 수용 (운영 영향 미미) 후속 분리: - #336 (#275 분산 락 + DTO + 테스트) - #337 (#276 SCAN + 자동복구 + 메트릭) - #338 (#274 봇/레이트리밋 + Redis INCR + 테스트) Refs: #275 #276 #274
35 lines
1.1 KiB
Java
35 lines
1.1 KiB
Java
package com.tasteby.controller;
|
|
|
|
import com.tasteby.domain.DaemonConfig;
|
|
import com.tasteby.security.AuthUtil;
|
|
import com.tasteby.service.DaemonConfigService;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
import java.util.Map;
|
|
|
|
@RestController
|
|
@RequestMapping("/api/daemon")
|
|
public class DaemonController {
|
|
|
|
private final DaemonConfigService daemonConfigService;
|
|
|
|
public DaemonController(DaemonConfigService daemonConfigService) {
|
|
this.daemonConfigService = daemonConfigService;
|
|
}
|
|
|
|
@GetMapping("/config")
|
|
public DaemonConfig getConfig() {
|
|
// #275 — 데몬 운영 설정은 admin 전용 (이전: 공개 노출 — 정보 누출 위험)
|
|
AuthUtil.requireAdmin();
|
|
DaemonConfig config = daemonConfigService.getConfig();
|
|
return config != null ? config : DaemonConfig.builder().build();
|
|
}
|
|
|
|
@PutMapping("/config")
|
|
public Map<String, Object> updateConfig(@RequestBody Map<String, Object> body) {
|
|
AuthUtil.requireAdmin();
|
|
daemonConfigService.updateConfig(body);
|
|
return Map.of("ok", true);
|
|
}
|
|
}
|