fix: DB 타임스탬프 KST 통일 + KIS 토큰 캐시 영속화

시간대 혼재: 모델 기본값은 datetime.utcnow(UTC), 수동 매매 등 일부 경로는 _get_kst_now(KST)로
저장해 같은 테이블에 9시간 차가 섞였다(화면 매매시각 02:14 등). 조회 구간(utcnow - days)도
KST 저장분과 비교돼 어긋났고, 추가매수 쿨다운은 (UTC now - KST created_at)이 음수라 상시
발동했다. app.core.timeutil.now_kst() 도입 후 모델 기본값 27곳과 app/ 전역 utcnow() 호출을
모두 KST 기준으로 통일(잔존 0건, 테스트로 고정).

KIS 토큰 캐시(~/.cache/auto-stock)가 컨테이너에만 있어 배포마다 사라지고 토큰을 새로
발급받다 KIS가 EGW00103(유효하지 않은 AppKey)로 거부 → 502·잔고 0 유발. 볼륨 마운트로
재배포 후에도 재사용.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-23 11:24:14 +09:00
parent e2d4b607cb
commit ec2fa2b423
22 changed files with 177 additions and 69 deletions

View File

@@ -13,6 +13,7 @@ from datetime import datetime as _dt, date as _date, timedelta as _td
from app.core.config import settings
from app.core.database import AsyncSessionLocal
from app.core.timeutil import now_kst
from app.core.market_schedule import (
is_market_open, seconds_until_market_open, is_pre_market_window,
)
@@ -224,7 +225,6 @@ async def post_market_analyzer_scheduler():
)
from app.models.models import TradeHistory
from sqlalchemy import select, func, and_
from datetime import datetime as _utcnow_dt
async with AsyncSessionLocal() as db:
uncovered = await get_uncovered_trades(db, days=7)
@@ -246,7 +246,7 @@ async def post_market_analyzer_scheduler():
try:
from app.services.telegram_notifier import telegram_notifier
# 당일 SELL 체결 내역으로 PnL 계산
_today_start = _utcnow_dt.utcnow().replace(hour=0, minute=0, second=0, microsecond=0)
_today_start = now_kst().replace(hour=0, minute=0, second=0, microsecond=0)
_today_sells = await db.execute(
select(TradeHistory).where(
and_(
@@ -282,7 +282,7 @@ async def post_market_analyzer_scheduler():
except Exception as _tg_err:
logger.debug(f"[PostMarket] Telegram 리포트 전송 실패: {_tg_err}")
since_7d = _utcnow_dt.utcnow() - _td(days=7)
since_7d = now_kst() - _td(days=7)
trade_count_result = await db.execute(
select(func.count(TradeHistory.id)).where(
and_(