d16456cb92
# 사용자별 격리 - JWT 토큰에 uid 추가 (auth.get_uid 헬퍼) - PostgreSQL — exchange_credentials/automation_config/trades/signal_events 에 user_id BIGINT - SQLite user_settings 테이블 신설 (글로벌 settings 는 옛 호환) - 모든 DB 함수 시그니처에 user_id 인자 추가 — 다른 사용자 데이터 절대 접근 불가 - alert_state — 모든 dict key 가 (user_id, ...) tuple 로 계층화 - core_logic alert_loop — 활성 사용자 순회 + 각자 settings/symbol/텔레그램 적용 - ensure_user_defaults() / ensure_user_automation() — 첫 사용 시 자동 시드 # 사용자 관리 (admin only) - users_db: delete_user / admin_reset_password / set_role - /api/users POST DELETE PUT password PUT role (본인 강등 / 마지막 admin 보호) - /admin/users 페이지 — 등록/삭제/role 토글/비번 reset 모달 - 사이드바 adminOnly 필터 — admin role 만 메뉴 노출 # 대시보드 개선 - 모바일 / 범례 토글 (모바일 60 캔들, 데스크톱 200) - 트레이드 이력: open 트레이드 실시간 PnL% (Binance ticker 호출 + 방향별 계산) - 메트릭 카드 분리 (실거래 vs 실시간 open) # 안정성 - api.ts: error.detail array/object 안전 처리 ([object Object] 방지) - Chart.tsx: Plotly yaxis title 객체 형태 + 모바일 height 동적 조정 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
67 lines
2.5 KiB
Python
67 lines
2.5 KiB
Python
"""
|
|
FastAPI 메인. 모든 라우터 + CORS + 백그라운드 알림 스레드 시작.
|
|
기존 Python 모듈 (users_db, settings_db, trades_db, exchange_keys, core_logic) 그대로 사용.
|
|
"""
|
|
import os
|
|
from fastapi import FastAPI
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
import users_db
|
|
import settings_db
|
|
import trades_db
|
|
import exchange_keys
|
|
import core_logic
|
|
import alert_state
|
|
|
|
from .routes import auth_route, settings_route, market_route, trades_route, exchange_route, automation_route, users_route
|
|
|
|
app = FastAPI(title="JUNGGOMOA Trading API", version="1.0", redirect_slashes=False)
|
|
|
|
# CORS — 같은 도메인이라도 허용 (개발 편의)
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["*"],
|
|
allow_credentials=False,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
@app.on_event("startup")
|
|
def on_startup():
|
|
settings_db.init_db_with_env_defaults()
|
|
trades_db.init_db()
|
|
exchange_keys.init_db()
|
|
users_db.init_db()
|
|
# 모든 기존 사용자에 default settings 시드 (없으면)
|
|
for u in users_db.list_users():
|
|
settings_db.ensure_user_defaults(u["id"])
|
|
# admin (id=1) 의 글로벌 settings 를 그 user_settings 로 복사 (마이그레이션)
|
|
try:
|
|
admin_us = settings_db.all_settings(user_id=1)
|
|
if not admin_us.get("telegram_token"):
|
|
globals_dict = settings_db.all_settings()
|
|
for k, v in globals_dict.items():
|
|
if not admin_us.get(k):
|
|
settings_db.set_value(k, v, user_id=1)
|
|
print("[migration] admin (id=1) 으로 글로벌 settings 복사")
|
|
except Exception as e:
|
|
print(f"[migration] settings 마이그레이션 실패: {e}")
|
|
# 백그라운드 알림 / 일일 리포트 시작
|
|
core_logic.start_background_threads()
|
|
print("[FastAPI] 모든 모듈 init OK + 백그라운드 스레드 시작")
|
|
|
|
|
|
@app.get("/api/health")
|
|
def health():
|
|
return {"ok": True}
|
|
|
|
|
|
# 라우터 등록
|
|
app.include_router(auth_route.router, prefix="/api/auth", tags=["auth"])
|
|
app.include_router(users_route.router, prefix="/api/users", tags=["users"])
|
|
app.include_router(settings_route.router, prefix="/api/settings", tags=["settings"])
|
|
app.include_router(market_route.router, prefix="/api/market", tags=["market"])
|
|
app.include_router(trades_route.router, prefix="/api/trades", tags=["trades"])
|
|
app.include_router(exchange_route.router, prefix="/api/exchange", tags=["exchange"])
|
|
app.include_router(automation_route.router, prefix="/api/automation", tags=["automation"])
|