모의투자 로직 변경
This commit is contained in:
@@ -8,6 +8,8 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 백테스팅 실행 REST API.
|
||||
*
|
||||
@@ -40,42 +42,32 @@ public class BacktestingController {
|
||||
@PostMapping("/run")
|
||||
public ResponseEntity<BacktestResponse> run(
|
||||
@RequestBody BacktestRequest req,
|
||||
@RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
|
||||
@RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
|
||||
if (req.getBars() == null || req.getBars().isEmpty()) {
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
|
||||
Long userId = parseUserId(userIdHeader);
|
||||
long userId = TradingControllerSupport.requireRegisteredUser(headers);
|
||||
|
||||
// DB 저장 파라미터를 기반으로, 요청 params 로 덮어쓰기
|
||||
// (요청에 params 없으면 DB 값만 사용 → 사용자가 변경한 파라미터 항상 반영)
|
||||
if (userId != null || deviceId != null) {
|
||||
java.util.Map<String, java.util.Map<String, Object>> dbParams =
|
||||
indicatorSettingsService.getAll(userId, deviceId);
|
||||
if (!dbParams.isEmpty()) {
|
||||
java.util.Map<String, java.util.Map<String, Object>> merged =
|
||||
new java.util.HashMap<>(dbParams);
|
||||
if (req.getIndicatorParams() != null) {
|
||||
req.getIndicatorParams().forEach((type, params) ->
|
||||
merged.merge(type, params, (dbP, reqP) -> {
|
||||
java.util.Map<String, Object> m = new java.util.HashMap<>(dbP);
|
||||
m.putAll(reqP);
|
||||
return m;
|
||||
})
|
||||
);
|
||||
}
|
||||
req.setIndicatorParams(merged);
|
||||
java.util.Map<String, java.util.Map<String, Object>> dbParams =
|
||||
indicatorSettingsService.getAll(userId, null);
|
||||
if (!dbParams.isEmpty()) {
|
||||
java.util.Map<String, java.util.Map<String, Object>> merged =
|
||||
new java.util.HashMap<>(dbParams);
|
||||
if (req.getIndicatorParams() != null) {
|
||||
req.getIndicatorParams().forEach((type, params) ->
|
||||
merged.merge(type, params, (dbP, reqP) -> {
|
||||
java.util.Map<String, Object> m = new java.util.HashMap<>(dbP);
|
||||
m.putAll(reqP);
|
||||
return m;
|
||||
})
|
||||
);
|
||||
}
|
||||
req.setIndicatorParams(merged);
|
||||
}
|
||||
|
||||
BacktestResponse response = backtestingService.run(req);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
private Long parseUserId(String header) {
|
||||
if (header == null || header.isBlank()) return null;
|
||||
try { return Long.parseLong(header); } catch (NumberFormatException e) { return null; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 가상투자 — 실시간 조건 충족 현황 API.
|
||||
*
|
||||
@@ -22,14 +24,8 @@ public class LiveConditionController {
|
||||
public ResponseEntity<LiveConditionStatusDto> get(
|
||||
@RequestParam String market,
|
||||
@RequestParam long strategyId,
|
||||
@RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
|
||||
@RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
|
||||
|
||||
return ResponseEntity.ok(service.evaluate(parseUserId(userIdHeader), deviceId, market, strategyId));
|
||||
}
|
||||
|
||||
private Long parseUserId(String header) {
|
||||
if (header == null || header.isBlank()) return null;
|
||||
try { return Long.parseLong(header); } catch (NumberFormatException e) { return null; }
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(headers);
|
||||
return ResponseEntity.ok(service.evaluate(uid, null, market, strategyId));
|
||||
}
|
||||
}
|
||||
|
||||
+13
-31
@@ -8,15 +8,8 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 실시간 전략 체크 설정 REST API.
|
||||
*
|
||||
* <pre>
|
||||
* GET /api/strategy/settings?market=KRW-BTC → 현재 설정 조회
|
||||
* PUT /api/strategy/settings → 설정 저장/갱신
|
||||
* </pre>
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/strategy/settings")
|
||||
@RequiredArgsConstructor
|
||||
@@ -27,42 +20,31 @@ public class LiveStrategySettingsController {
|
||||
@GetMapping
|
||||
public ResponseEntity<LiveStrategySettingsDto> get(
|
||||
@RequestParam(value = "market", defaultValue = "KRW-BTC") String market,
|
||||
@RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
|
||||
@RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
|
||||
|
||||
return ResponseEntity.ok(service.get(parseUserId(userIdHeader), deviceId, market));
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(headers);
|
||||
return ResponseEntity.ok(service.get(uid, null, market));
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
public ResponseEntity<LiveStrategySettingsDto> put(
|
||||
@RequestBody LiveStrategySettingsDto dto,
|
||||
@RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
|
||||
@RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
|
||||
|
||||
return ResponseEntity.ok(service.save(parseUserId(userIdHeader), deviceId, dto));
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(headers);
|
||||
return ResponseEntity.ok(service.save(uid, null, dto));
|
||||
}
|
||||
|
||||
/** 실시간 체크 ON + 전략 지정된 종목 목록 (현재 디바이스/유저) */
|
||||
@GetMapping("/active")
|
||||
public ResponseEntity<List<LiveStrategySettingsDto>> listActive(
|
||||
@RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
|
||||
@RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
|
||||
|
||||
return ResponseEntity.ok(service.listActive(parseUserId(userIdHeader), deviceId));
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(headers);
|
||||
return ResponseEntity.ok(service.listActive(uid, null));
|
||||
}
|
||||
|
||||
/** 관심종목 등 여러 마켓에 동일 설정 일괄 저장 */
|
||||
@PutMapping("/bulk")
|
||||
public ResponseEntity<List<LiveStrategySettingsDto>> putBulk(
|
||||
@RequestBody LiveStrategyBulkRequest req,
|
||||
@RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
|
||||
@RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
|
||||
|
||||
return ResponseEntity.ok(service.saveBulk(parseUserId(userIdHeader), deviceId, req));
|
||||
}
|
||||
|
||||
private Long parseUserId(String header) {
|
||||
if (header == null || header.isBlank()) return null;
|
||||
try { return Long.parseLong(header); } catch (NumberFormatException e) { return null; }
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(headers);
|
||||
return ResponseEntity.ok(service.saveBulk(uid, null, req));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.goldenchart.controller;
|
||||
|
||||
import com.goldenchart.dto.LiveOrderRequest;
|
||||
import com.goldenchart.dto.LiveOrderRequest;
|
||||
import com.goldenchart.dto.LiveSummaryDto;
|
||||
import com.goldenchart.dto.LiveTradeDto;
|
||||
@@ -21,27 +20,20 @@ public class LiveTradingController {
|
||||
|
||||
@GetMapping("/summary")
|
||||
public ResponseEntity<LiveSummaryDto> summary(@RequestHeader Map<String, String> h) {
|
||||
return ResponseEntity.ok(liveTradingService.getSummary(userId(h), deviceId(h)));
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
return ResponseEntity.ok(liveTradingService.getSummary(uid));
|
||||
}
|
||||
|
||||
@GetMapping("/trades")
|
||||
public ResponseEntity<List<LiveTradeDto>> trades(@RequestHeader Map<String, String> h) {
|
||||
return ResponseEntity.ok(liveTradingService.listTrades(userId(h), deviceId(h)));
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
return ResponseEntity.ok(liveTradingService.listTrades(uid));
|
||||
}
|
||||
|
||||
@PostMapping("/orders")
|
||||
public ResponseEntity<LiveTradeDto> placeOrder(@RequestHeader Map<String, String> h,
|
||||
@RequestBody LiveOrderRequest body) {
|
||||
return ResponseEntity.ok(liveTradingService.placeManualOrder(userId(h), deviceId(h), body));
|
||||
}
|
||||
|
||||
private Long userId(Map<String, String> h) {
|
||||
String v = h.get("x-user-id");
|
||||
if (v == null || v.isBlank()) return null;
|
||||
try { return Long.parseLong(v); } catch (NumberFormatException e) { return null; }
|
||||
}
|
||||
|
||||
private String deviceId(Map<String, String> h) {
|
||||
return h.getOrDefault("x-device-id", "anonymous");
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
return ResponseEntity.ok(liveTradingService.placeManualOrder(uid, body));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,37 +19,32 @@ public class PaperTradingController {
|
||||
|
||||
private final PaperTradingService paperTradingService;
|
||||
|
||||
private Long userId(Map<String, String> h) {
|
||||
String v = h.get("x-user-id");
|
||||
return v != null ? Long.parseLong(v) : null;
|
||||
}
|
||||
|
||||
private String deviceId(Map<String, String> h) {
|
||||
return h.getOrDefault("x-device-id", "anonymous");
|
||||
}
|
||||
|
||||
@GetMapping("/summary")
|
||||
public ResponseEntity<PaperSummaryDto> summary(@RequestHeader Map<String, String> h) {
|
||||
return ResponseEntity.ok(paperTradingService.getSummary(userId(h), deviceId(h), null));
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
return ResponseEntity.ok(paperTradingService.getSummary(uid, null));
|
||||
}
|
||||
|
||||
@PostMapping("/summary")
|
||||
public ResponseEntity<PaperSummaryDto> summaryWithMarks(
|
||||
@RequestHeader Map<String, String> h,
|
||||
@RequestBody(required = false) Map<String, Double> markPrices) {
|
||||
return ResponseEntity.ok(paperTradingService.getSummary(userId(h), deviceId(h), markPrices));
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
return ResponseEntity.ok(paperTradingService.getSummary(uid, markPrices));
|
||||
}
|
||||
|
||||
@GetMapping("/allocations")
|
||||
public ResponseEntity<List<PaperAllocationDto>> allocations(@RequestHeader Map<String, String> h) {
|
||||
return ResponseEntity.ok(paperTradingService.listAllocations(userId(h), deviceId(h), null));
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
return ResponseEntity.ok(paperTradingService.listAllocations(uid, null));
|
||||
}
|
||||
|
||||
@PutMapping("/allocations/bulk")
|
||||
public ResponseEntity<List<PaperAllocationDto>> bulkAllocations(
|
||||
@RequestHeader Map<String, String> h,
|
||||
@RequestBody PaperAllocationBulkRequest body) {
|
||||
return ResponseEntity.ok(paperTradingService.bulkAllocations(userId(h), deviceId(h), body));
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
return ResponseEntity.ok(paperTradingService.bulkAllocations(uid, body));
|
||||
}
|
||||
|
||||
@PatchMapping("/allocations/{symbol}")
|
||||
@@ -57,7 +52,8 @@ public class PaperTradingController {
|
||||
@RequestHeader Map<String, String> h,
|
||||
@PathVariable String symbol,
|
||||
@RequestBody PaperAllocationPatchRequest body) {
|
||||
return ResponseEntity.ok(paperTradingService.patchAllocation(userId(h), deviceId(h), symbol, body));
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
return ResponseEntity.ok(paperTradingService.patchAllocation(uid, symbol, body));
|
||||
}
|
||||
|
||||
@GetMapping("/trades")
|
||||
@@ -70,12 +66,13 @@ public class PaperTradingController {
|
||||
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime to,
|
||||
@RequestParam(defaultValue = "0") int page,
|
||||
@RequestParam(required = false) Integer size) {
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
if (size == null && symbol == null && side == null && source == null && from == null && to == null) {
|
||||
return ResponseEntity.ok(paperTradingService.listTradesLegacy(userId(h), deviceId(h)));
|
||||
return ResponseEntity.ok(paperTradingService.listTradesLegacy(uid));
|
||||
}
|
||||
int pageSize = size != null ? size : 50;
|
||||
return ResponseEntity.ok(paperTradingService.listTrades(
|
||||
userId(h), deviceId(h), symbol, side, source, from, to, page, pageSize));
|
||||
uid, symbol, side, source, from, to, page, pageSize));
|
||||
}
|
||||
|
||||
@GetMapping("/ledger")
|
||||
@@ -85,7 +82,8 @@ public class PaperTradingController {
|
||||
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime to,
|
||||
@RequestParam(defaultValue = "0") int page,
|
||||
@RequestParam(defaultValue = "50") int size) {
|
||||
return ResponseEntity.ok(paperTradingService.listLedger(userId(h), deviceId(h), from, to, page, size));
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
return ResponseEntity.ok(paperTradingService.listLedger(uid, from, to, page, size));
|
||||
}
|
||||
|
||||
@GetMapping("/snapshots/daily")
|
||||
@@ -93,30 +91,35 @@ public class PaperTradingController {
|
||||
@RequestHeader Map<String, String> h,
|
||||
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate from,
|
||||
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate to) {
|
||||
return ResponseEntity.ok(paperTradingService.listDailySnapshots(userId(h), deviceId(h), from, to));
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
return ResponseEntity.ok(paperTradingService.listDailySnapshots(uid, from, to));
|
||||
}
|
||||
|
||||
@GetMapping("/orders")
|
||||
public ResponseEntity<List<PaperOrderDto>> pendingOrders(@RequestHeader Map<String, String> h) {
|
||||
return ResponseEntity.ok(paperTradingService.listPendingOrders(userId(h), deviceId(h)));
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
return ResponseEntity.ok(paperTradingService.listPendingOrders(uid));
|
||||
}
|
||||
|
||||
@PostMapping("/orders")
|
||||
public ResponseEntity<PaperPlaceOrderResult> placeOrder(
|
||||
@RequestHeader Map<String, String> h,
|
||||
@RequestBody PaperOrderRequest body) {
|
||||
return ResponseEntity.ok(paperTradingService.placeOrder(userId(h), deviceId(h), body));
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
return ResponseEntity.ok(paperTradingService.placeOrder(uid, body));
|
||||
}
|
||||
|
||||
@PostMapping("/orders/{id}/cancel")
|
||||
public ResponseEntity<PaperOrderDto> cancelOrder(
|
||||
@RequestHeader Map<String, String> h,
|
||||
@PathVariable Long id) {
|
||||
return ResponseEntity.ok(paperTradingService.cancelOrder(userId(h), deviceId(h), id));
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
return ResponseEntity.ok(paperTradingService.cancelOrder(uid, id));
|
||||
}
|
||||
|
||||
@PostMapping("/reset")
|
||||
public ResponseEntity<PaperSummaryDto> reset(@RequestHeader Map<String, String> h) {
|
||||
return ResponseEntity.ok(paperTradingService.resetAccount(userId(h), deviceId(h)));
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(h);
|
||||
return ResponseEntity.ok(paperTradingService.resetAccount(uid));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 투자전략 CRUD REST API.
|
||||
@@ -29,14 +30,17 @@ public class StrategyController {
|
||||
/** 전략 목록 조회 */
|
||||
@GetMapping
|
||||
public ResponseEntity<List<StrategyDto>> list(
|
||||
@RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
|
||||
@RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
|
||||
return ResponseEntity.ok(service.list(parseUserId(userIdHeader), deviceId));
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(headers);
|
||||
return ResponseEntity.ok(service.list(uid, null));
|
||||
}
|
||||
|
||||
/** 단일 전략 조회 */
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<StrategyDto> get(@PathVariable Long id) {
|
||||
public ResponseEntity<StrategyDto> get(
|
||||
@PathVariable Long id,
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
TradingControllerSupport.requireRegisteredUser(headers);
|
||||
return service.findById(id)
|
||||
.map(ResponseEntity::ok)
|
||||
.orElse(ResponseEntity.notFound().build());
|
||||
@@ -46,20 +50,26 @@ public class StrategyController {
|
||||
@PostMapping
|
||||
public ResponseEntity<StrategyDto> save(
|
||||
@RequestBody StrategyDto dto,
|
||||
@RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
|
||||
@RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
|
||||
return ResponseEntity.ok(service.save(dto, parseUserId(userIdHeader), deviceId));
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(headers);
|
||||
return ResponseEntity.ok(service.save(dto, uid, null));
|
||||
}
|
||||
|
||||
/** 전략 DSL에 포함된 평가 시간봉 목록 */
|
||||
@GetMapping("/{id}/timeframes")
|
||||
public ResponseEntity<List<String>> timeframes(@PathVariable Long id) {
|
||||
public ResponseEntity<List<String>> timeframes(
|
||||
@PathVariable Long id,
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
TradingControllerSupport.requireRegisteredUser(headers);
|
||||
return ResponseEntity.ok(conditionTimeframes.collectForStrategyList(id));
|
||||
}
|
||||
|
||||
/** TIMEFRAME 래핑 누락 DSL 보정 (3분봉 전략이 1분봉으로 평가되는 경우) */
|
||||
@PostMapping("/{id}/repair-timeframes")
|
||||
public ResponseEntity<StrategyDto> repairTimeframes(@PathVariable Long id) {
|
||||
public ResponseEntity<StrategyDto> repairTimeframes(
|
||||
@PathVariable Long id,
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
TradingControllerSupport.requireRegisteredUser(headers);
|
||||
return service.repairTimeframeWrappers(id)
|
||||
.map(ResponseEntity::ok)
|
||||
.orElse(ResponseEntity.notFound().build());
|
||||
@@ -67,13 +77,11 @@ public class StrategyController {
|
||||
|
||||
/** 전략 삭제 */
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseEntity<Void> delete(@PathVariable Long id) {
|
||||
public ResponseEntity<Void> delete(
|
||||
@PathVariable Long id,
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
TradingControllerSupport.requireRegisteredUser(headers);
|
||||
service.delete(id);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
private Long parseUserId(String header) {
|
||||
if (header == null || header.isBlank()) return null;
|
||||
try { return Long.parseLong(header); } catch (NumberFormatException e) { return null; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,18 +7,8 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 매매 시그널 이력 REST API.
|
||||
*
|
||||
* <pre>
|
||||
* GET /api/trade-signals → 전체 이력
|
||||
* GET /api/trade-signals?market= → 종목별 이력
|
||||
* DELETE /api/trade-signals/{id} → 단건 삭제
|
||||
* DELETE /api/trade-signals → 전체 삭제
|
||||
* POST /api/trade-signals/delete-batch → ID 목록 삭제
|
||||
* </pre>
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/trade-signals")
|
||||
@RequiredArgsConstructor
|
||||
@@ -29,44 +19,36 @@ public class TradeSignalController {
|
||||
@GetMapping
|
||||
public ResponseEntity<List<TradeSignalDto>> list(
|
||||
@RequestParam(required = false) String market,
|
||||
@RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
|
||||
@RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
|
||||
|
||||
Long userId = parseUserId(userIdHeader);
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(headers);
|
||||
List<TradeSignalDto> result = (market != null && !market.isBlank())
|
||||
? service.listByMarket(userId, deviceId, market)
|
||||
: service.list(userId, deviceId);
|
||||
? service.listByMarket(uid, null, market)
|
||||
: service.list(uid, null);
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseEntity<Void> deleteOne(
|
||||
@PathVariable Long id,
|
||||
@RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
|
||||
@RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
|
||||
service.deleteOne(id, parseUserId(userIdHeader), deviceId);
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(headers);
|
||||
service.deleteOne(id, uid, null);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
public ResponseEntity<java.util.Map<String, Integer>> deleteAll(
|
||||
@RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
|
||||
@RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
|
||||
int deleted = service.deleteAll(parseUserId(userIdHeader), deviceId);
|
||||
return ResponseEntity.ok(java.util.Map.of("deleted", deleted));
|
||||
public ResponseEntity<Map<String, Integer>> deleteAll(@RequestHeader Map<String, String> headers) {
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(headers);
|
||||
int deleted = service.deleteAll(uid, null);
|
||||
return ResponseEntity.ok(Map.of("deleted", deleted));
|
||||
}
|
||||
|
||||
@PostMapping("/delete-batch")
|
||||
public ResponseEntity<java.util.Map<String, Integer>> deleteBatch(
|
||||
@RequestBody java.util.List<Long> ids,
|
||||
@RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
|
||||
@RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
|
||||
int deleted = service.deleteBatch(ids, parseUserId(userIdHeader), deviceId);
|
||||
return ResponseEntity.ok(java.util.Map.of("deleted", deleted));
|
||||
}
|
||||
|
||||
private Long parseUserId(String h) {
|
||||
if (h == null || h.isBlank()) return null;
|
||||
try { return Long.parseLong(h); } catch (NumberFormatException e) { return null; }
|
||||
public ResponseEntity<Map<String, Integer>> deleteBatch(
|
||||
@RequestBody List<Long> ids,
|
||||
@RequestHeader Map<String, String> headers) {
|
||||
long uid = TradingControllerSupport.requireRegisteredUser(headers);
|
||||
int deleted = service.deleteBatch(ids, uid, null);
|
||||
return ResponseEntity.ok(Map.of("deleted", deleted));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.goldenchart.controller;
|
||||
|
||||
import com.goldenchart.trading.TradingAccess;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/** 매매·모의·전략 API — 정식 로그인(userId) 필수 */
|
||||
public final class TradingControllerSupport {
|
||||
|
||||
private TradingControllerSupport() {}
|
||||
|
||||
public static long requireRegisteredUser(Map<String, String> headers) {
|
||||
String raw = headers.get("x-user-id");
|
||||
if (raw == null || raw.isBlank()) {
|
||||
throw new com.goldenchart.trading.TradingAccessDeniedException();
|
||||
}
|
||||
try {
|
||||
return TradingAccess.requireUserId(Long.parseLong(raw.trim()));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new com.goldenchart.trading.TradingAccessDeniedException();
|
||||
}
|
||||
}
|
||||
|
||||
public static Long parseUserId(Map<String, String> headers) {
|
||||
String raw = headers.get("x-user-id");
|
||||
if (raw == null || raw.isBlank()) return null;
|
||||
try {
|
||||
return Long.parseLong(raw.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user