From dec696b16e63fc60fe3b050838b55405c6741ac7 Mon Sep 17 00:00:00 2001 From: gahusb Date: Thu, 9 Jul 2026 13:05:57 +0900 Subject: [PATCH] =?UTF-8?q?feat(stock):=20=EB=A7=A4=EB=A7=A4=EC=95=8C?= =?UTF-8?q?=EB=9E=8C=20=EC=B9=B4=EB=93=9C=EC=97=90=20reason(=EA=B7=BC?= =?UTF-8?q?=EA=B1=B0=20=EB=AC=B8=EC=9E=90=EC=97=B4)=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BE가 /api/stock/trade-alerts에 reason 필드 추가(사람이 읽는 조건별 근거, 텔레그램 💡 라인과 동일). AlertCard가 reason을 primary 내러티브로, formatDetail(detail)을 secondary 숫자 근거로 표시. reason은 문자열이라 안전(detail 객체는 formatDetail로 이미 크래시 방지). Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01UHXzpsZQxKG9hQmNRfZjRS --- src/pages/stock/Stock.css | 1 + src/pages/stock/components/WatchlistTab.jsx | 1 + src/pages/stock/components/WatchlistTab.test.jsx | 15 +++++++++++++++ 3 files changed, 17 insertions(+) diff --git a/src/pages/stock/Stock.css b/src/pages/stock/Stock.css index 35c4686..88f6944 100644 --- a/src/pages/stock/Stock.css +++ b/src/pages/stock/Stock.css @@ -3349,4 +3349,5 @@ } .wl-cond { font-size: 13px; font-weight: 600; } .wl-alert__price { font-size: 13px; color: var(--muted); } +.wl-alert__reason { font-size: 12.5px; line-height: 1.45; color: #cbd5e1; } .wl-alert__detail { font-size: 12px; color: var(--muted); } diff --git a/src/pages/stock/components/WatchlistTab.jsx b/src/pages/stock/components/WatchlistTab.jsx index e762597..aaf496c 100644 --- a/src/pages/stock/components/WatchlistTab.jsx +++ b/src/pages/stock/components/WatchlistTab.jsx @@ -24,6 +24,7 @@ const AlertCard = ({ a }) => { {conditionLabel(a.condition)} {a.price != null && {formatNumber(a.price)}원} + {a.reason &&
{a.reason}
} {detailText &&
{detailText}
} ); diff --git a/src/pages/stock/components/WatchlistTab.test.jsx b/src/pages/stock/components/WatchlistTab.test.jsx index a99ddf3..efc2d93 100644 --- a/src/pages/stock/components/WatchlistTab.test.jsx +++ b/src/pages/stock/components/WatchlistTab.test.jsx @@ -44,4 +44,19 @@ describe('WatchlistTab', () => { // 객체 detail이 문자열로 안전 렌더됨 (severity 값 노출) expect(screen.getByText(/normal/)).toBeInTheDocument(); }); + + it('alert.reason(근거 문자열)을 condition 라벨과 함께 렌더', () => { + const wl = { + ...baseWl, + alerts: [{ + id: 40, ticker: '000660', name: 'SK하이닉스', kind: 'sell', condition: 'sell_ma_break', + price: 2120000, detail: { ma50: 2123160, ma200: null, severity: 'normal' }, + fired_at: '2026-07-09T02:55:00Z', + reason: '주요 이평선(MA50/200) 이탈 — 추세 훼손, 보유 재검토', + }], + }; + render(); + expect(screen.getByText('주요 이평선(MA50/200) 이탈 — 추세 훼손, 보유 재검토')).toBeInTheDocument(); + expect(screen.getByText('이평선 이탈')).toBeInTheDocument(); + }); });