package com.goldenchart.controller; import com.goldenchart.dto.TrendSearchRequest; import com.goldenchart.dto.TrendSearchResultDto; import com.goldenchart.dto.TrendSearchResultsResponse; import com.goldenchart.service.TrendSearchService; import com.goldenchart.service.TrendSearchSnapshotService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; /** * 암호화폐 추세검색 API. * * POST /api/trend-search/scan — 조건 스캔 후 DB 스냅샷 갱신 * GET /api/trend-search/results — DB 스냅샷 조회 (자동 갱신 화면용) * GET /api/trend-search/detail — 단일 종목 상세 */ @RestController @RequestMapping("/trend-search") @RequiredArgsConstructor @Slf4j public class TrendSearchController { private final TrendSearchService trendSearchService; private final TrendSearchSnapshotService snapshotService; @PostMapping("/scan") public ResponseEntity> scan( @RequestHeader(value = "X-User-Id", required = false) String userIdHeader, @RequestHeader(value = "X-Device-Id", required = false) String deviceId, @RequestBody TrendSearchRequest request) { log.info("[TrendSearch] scan tf={} limit={}", request.getTimeframe(), request.getLimit()); Long userId = parseUserId(userIdHeader); return ResponseEntity.ok(snapshotService.scanAndPersist(userId, deviceId, request)); } @GetMapping("/results") public ResponseEntity results( @RequestHeader(value = "X-User-Id", required = false) String userIdHeader, @RequestHeader(value = "X-Device-Id", required = false) String deviceId) { Long userId = parseUserId(userIdHeader); return ResponseEntity.ok(snapshotService.getResults(userId, deviceId)); } @GetMapping("/detail") public ResponseEntity detail( @RequestParam String market, @RequestParam(required = false) String timeframe) { TrendSearchRequest req = new TrendSearchRequest(); if (timeframe != null) req.setTimeframe(timeframe); return ResponseEntity.ok(trendSearchService.detail(market, req)); } private Long parseUserId(String header) { if (header == null || header.isBlank()) return null; try { return Long.parseLong(header); } catch (NumberFormatException e) { return null; } } }