프론트엔드 추가 및 자동매매 로직 개선:
Some checks failed
Build Push and Restart Compose / deploy (push) Failing after 1m42s
Some checks failed
Build Push and Restart Compose / deploy (push) Failing after 1m42s
- Svelte 기반 프론트엔드 프로젝트 초기 설정 추가 (`vite`, `tailwindcss` 등 포함). - "자동매매" 주요 상태 및 규칙 관리 페이지 구현. - 1차/2차 손절 및 익절 조건 평가 로직 추가(`calcStopTargets`, `evalExitReason` 등). - 포지션 상세 로그 및 WebSocket 기반 실시간 로그 스트림 추가. - API 서비스 및 Frontend 간 Proxy 설정(Vite 서버). - 세션 체크를 위한 `CheckSession` 핸들러 추가.
This commit is contained in:
61
main.go
61
main.go
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"stocksearch/config"
|
||||
"stocksearch/handlers"
|
||||
"stocksearch/middleware"
|
||||
@@ -37,9 +38,9 @@ func main() {
|
||||
}
|
||||
|
||||
// 서비스 추가
|
||||
sessionSvc := services.GetSessionService()
|
||||
watchlistSvc := services.GetWatchlistService()
|
||||
autoTradeSvc := services.GetAutoTradeService()
|
||||
sessionSvc := services.GetSessionService()
|
||||
watchlistSvc := services.GetWatchlistService()
|
||||
autoTradeSvc := services.GetAutoTradeService()
|
||||
|
||||
// 스캐너 구독 종목 → WebSocket 내부 구독 연결
|
||||
services.GetScannerService().SetSubscribeCallback(func(codes []string) {
|
||||
@@ -52,11 +53,11 @@ func main() {
|
||||
})
|
||||
|
||||
// 핸들러 초기화
|
||||
pageHandler := handlers.NewPageHandler()
|
||||
stockHandler := handlers.NewStockHandler(watchlistSvc)
|
||||
wsHandler := handlers.NewWSHandler(hub)
|
||||
authHandler := handlers.NewAuthHandler(sessionSvc)
|
||||
orderHandler := handlers.NewOrderHandler()
|
||||
pageHandler := handlers.NewPageHandler()
|
||||
stockHandler := handlers.NewStockHandler(watchlistSvc)
|
||||
wsHandler := handlers.NewWSHandler(hub)
|
||||
authHandler := handlers.NewAuthHandler(sessionSvc)
|
||||
orderHandler := handlers.NewOrderHandler()
|
||||
autoTradeHandler := handlers.NewAutoTradeHandler(autoTradeSvc)
|
||||
|
||||
// 라우터 설정 (Go 1.22 패턴 매칭)
|
||||
@@ -66,6 +67,7 @@ func main() {
|
||||
mux.HandleFunc("GET /login", authHandler.LoginPage)
|
||||
mux.HandleFunc("POST /login", authHandler.Login)
|
||||
mux.HandleFunc("POST /logout", authHandler.Logout)
|
||||
mux.HandleFunc("GET /api/auth/check", authHandler.CheckSession)
|
||||
|
||||
// --- 페이지 라우트 ---
|
||||
mux.HandleFunc("GET /", pageHandler.IndexPage)
|
||||
@@ -105,19 +107,20 @@ func main() {
|
||||
mux.HandleFunc("GET /api/account/orderable", orderHandler.GetOrderable)
|
||||
|
||||
// --- 자동매매 API 라우트 ---
|
||||
mux.HandleFunc("GET /api/autotrade/status", autoTradeHandler.GetStatus)
|
||||
mux.HandleFunc("GET /api/autotrade/rules", autoTradeHandler.GetRules)
|
||||
mux.HandleFunc("POST /api/autotrade/rules", autoTradeHandler.AddRule)
|
||||
mux.HandleFunc("PUT /api/autotrade/rules/{id}", autoTradeHandler.UpdateRule)
|
||||
mux.HandleFunc("DELETE /api/autotrade/rules/{id}", autoTradeHandler.DeleteRule)
|
||||
mux.HandleFunc("GET /api/autotrade/status", autoTradeHandler.GetStatus)
|
||||
mux.HandleFunc("GET /api/autotrade/rules", autoTradeHandler.GetRules)
|
||||
mux.HandleFunc("POST /api/autotrade/rules", autoTradeHandler.AddRule)
|
||||
mux.HandleFunc("PUT /api/autotrade/rules/{id}", autoTradeHandler.UpdateRule)
|
||||
mux.HandleFunc("DELETE /api/autotrade/rules/{id}", autoTradeHandler.DeleteRule)
|
||||
mux.HandleFunc("POST /api/autotrade/rules/{id}/toggle", autoTradeHandler.ToggleRule)
|
||||
mux.HandleFunc("GET /api/autotrade/positions", autoTradeHandler.GetPositions)
|
||||
mux.HandleFunc("GET /api/autotrade/logs", autoTradeHandler.GetLogs)
|
||||
mux.HandleFunc("GET /api/autotrade/watch-source", autoTradeHandler.GetWatchSource)
|
||||
mux.HandleFunc("PUT /api/autotrade/watch-source", autoTradeHandler.SetWatchSource)
|
||||
mux.HandleFunc("POST /api/autotrade/start", autoTradeHandler.Start)
|
||||
mux.HandleFunc("POST /api/autotrade/stop", autoTradeHandler.Stop)
|
||||
mux.HandleFunc("POST /api/autotrade/emergency", autoTradeHandler.Emergency)
|
||||
mux.HandleFunc("GET /api/autotrade/positions", autoTradeHandler.GetPositions)
|
||||
mux.HandleFunc("GET /api/autotrade/logs", autoTradeHandler.GetLogs)
|
||||
mux.HandleFunc("GET /api/autotrade/watch-source", autoTradeHandler.GetWatchSource)
|
||||
mux.HandleFunc("PUT /api/autotrade/watch-source", autoTradeHandler.SetWatchSource)
|
||||
mux.HandleFunc("POST /api/autotrade/start", autoTradeHandler.Start)
|
||||
mux.HandleFunc("POST /api/autotrade/stop", autoTradeHandler.Stop)
|
||||
mux.HandleFunc("POST /api/autotrade/emergency", autoTradeHandler.Emergency)
|
||||
mux.HandleFunc("POST /api/autotrade/positions/{code}/close", autoTradeHandler.ClosePosition)
|
||||
|
||||
// --- WebSocket 라우트 ---
|
||||
mux.HandleFunc("GET /ws", wsHandler.ServeWS)
|
||||
@@ -125,8 +128,22 @@ func main() {
|
||||
// --- 정적 파일 ---
|
||||
mux.Handle("GET /static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
|
||||
|
||||
// 미들웨어 체인 적용 (Auth → Logger → Recovery 순)
|
||||
handler := middleware.Chain(mux, middleware.Recovery, middleware.Logger, middleware.Auth(sessionSvc))
|
||||
// --- SvelteKit 빌드 정적 서빙 (SPA fallback 포함) ---
|
||||
if _, err := os.Stat("frontend/build"); err == nil {
|
||||
spa := http.FileServer(http.Dir("frontend/build"))
|
||||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
path := "frontend/build" + r.URL.Path
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
// SPA fallback: 파일 없으면 index.html 서빙
|
||||
http.ServeFile(w, r, "frontend/build/index.html")
|
||||
return
|
||||
}
|
||||
spa.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// 미들웨어 체인 적용 (CORS → Auth → Logger → Recovery 순)
|
||||
handler := middleware.Chain(mux, middleware.Recovery, middleware.Logger, middleware.Auth(sessionSvc), middleware.CORS)
|
||||
|
||||
addr := "0.0.0.0:" + config.App.ServerPort
|
||||
log.Printf("서버 시작: http://%s", addr)
|
||||
|
||||
Reference in New Issue
Block a user