Commit Graph

22 Commits

Author SHA1 Message Date
claude-owner
0f89b2c042 feat(compare): 종목 비교 페이지 (/compare)
- 최대 5종목 누적수익률(%) 한 차트 비교, 기간 1M/3M/6M/1Y
- URL ?codes=A,B,C 양방향 동기화 (Suspense + useSearchParams)
- 검색 칩으로 종목 추가, ✕ 로 제거. 종목별 최종 수익률 칩 표시
- TopNav 우측에 "비교" 링크
2026-05-28 18:27:27 +09:00
claude-owner
139403c133 feat(alerts): /alerts 통합 관리 페이지 + TopNav 🔔 링크
- 종목별 그룹핑 (Map by code), 활성·발사됨 분리 카운트
- 행 단위 재무장/삭제 + 전체 삭제 (confirm)
- Notification 권한이 default 일 때만 권한 요청 배너 노출
- TopNav 우측 ★ 옆에 🔔 알람 페이지 링크 추가
2026-05-28 18:25:27 +09:00
claude-owner
fd7026ad09 feat(alerts): 가격 알람 (localStorage + 60s 폴러 + 토스트)
- lib/alerts.ts: id/code/op(gte|lte)/target/triggered 저장소, watchlist/recent 와 동일 pub/sub
- AlertsPanel: 종목 사이드바에 ≥/≤ 토글 + 목표가 입력 + 활성 알람 리스트(재무장/삭제)
- AlertsToaster: layout 전역 마운트, 미발사 알람 코드만 폴링, 조건 충족시 markTriggered + 우측 하단 토스트(6s), Notification 권한 허용 시 브라우저 알림 병행
2026-05-28 15:26:10 +09:00
claude-owner
01e5eba3c1 feat(chart): SMA(5/20/60) 토글 오버레이
- lightweight-charts addLineSeries 로 종가 기반 단순이동평균 라인 추가
- 칩 토글 (기본 MA20 ON), intraday(10분봉)에선 UI/시리즈 모두 숨김
- fitContent 는 호출 안 함 — 사용자 줌 유지
2026-05-28 15:23:34 +09:00
claude-owner
645e93e7bf feat(market): 거래대금 상위 + 52주 위치 게이지
- /api/markets/movers: by_trading_value (close*volume DESC) 카테고리 추가
- MarketsOverview: 4 컬럼 그리드 (등락 상위/하위/거래대금/거래량), 거래대금은 억·조 표기
- SymbolSidebar: 52주 범위 내 현재가 위치 게이지 (그라데이션 바 + 화이트 점)
2026-05-28 15:21:27 +09:00
claude-owner
aa58761176 feat(ui): 최근 본 종목 (localStorage + 홈 카드 + TopNav popover)
- web/lib/recent.ts: stockchart.recent KEY, push/get/clear/subscribe (storage + custom event)
- [code]/page.tsx: 페이지 진입 시 recent.push(code) — 자동 트래킹
- web/components/RecentTiles.tsx: 홈 카드 그리드 (최대 10개, 2~5컬럼)
- web/app/page.tsx: SearchBox 아래에 RecentTiles 배치 (빈 리스트면 자동 숨김)
- TopNav: 검색어 비면서 포커스 시 최근 본 종목 popover 표시 + "지우기" 버튼

토스 "최근 본 종목" 톤 — 검색 빈 상태에서도 popover 가 비어 있지 않게.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 15:14:40 +09:00
claude-owner
300f7beef0 feat(nav): 글로벌 sticky 헤더 + 컴팩트 검색
- web/components/TopNav.tsx: sticky top header
  · 좌: Stock Chart 로고 (→ /)
  · 중: 컴팩트 검색 input + popover (debounced 200ms, with_sparkline=false 빠른 응답)
  · 우: ★ 관심 (→ /watchlist)
- 바깥 클릭/Esc 로 popover 닫힘
- 결과 클릭 시 자동 닫힘 + 검색어 클리어
- web/app/layout.tsx: <body> 최상단에 <TopNav /> 부착

토스 톱바 톤. 모든 페이지에서 검색 가능 — 홈으로 돌아갈 필요 없음.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 15:10:14 +09:00
claude-owner
85da979fbe feat(peers): 동종업종(테마) 비교 패널
- backend/app/seed/themes.py: themes_for_code(code) 헬퍼 추가 (코드 → 소속 테마들)
- backend/app/api/themes.py: GET /api/themes/peer/{code} 신규
  · 종목이 속한 모든 테마의 코드 합집합을 peer 풀로
  · 단일 SQL (ROW_NUMBER OVER PARTITION BY code) 로 21영업일 누적수익률 일괄 계산
  · 본인 / peer 평균 / 상·하위 5종목 반환
- web/lib/api.ts: PeerCompare 타입 + api.peerCompare()
- web/components/PeerComparePanel.tsx: 테마 태그 + 3-칸 요약 (본인/평균/격차) + 상·하위 5
- [code]/page.tsx 에 PeriodReturns 아래 부착. 테마 무소속 종목은 패널 자동 숨김.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 15:07:09 +09:00
claude-owner
0b4795b03f feat(ui): AI 종합 점수 카드 (모멘텀·수급·감성·추세)
토스 "투자자 분석" 톤의 단일 카드:
- 종합 점수 반원 게이지 (conic-gradient + radial mask)
- 4개 서브 점수 (0~100, 50=중립)
  · 모멘텀: SMA5 vs SMA20 격차
  · 수급:   외국인+기관 5일 누적 net 정규화
  · 감성:   뉴스 weighted_score 7일 평균
  · 추세:   20일 종가 선형회귀 기울기
- 백엔드 호출 없음 — chart payload (ohlcv+sentiment+trading_value) 클라이언트 합성

색조: 65↑ 강세=빨강 / 35↓ 약세=파랑 / 그 사이 중립=주황.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 15:02:04 +09:00
claude-owner
9b25bc6970 feat(ui): 기간 수익률 + 거래주체 순매수 패널
- PeriodReturns: chart.ohlcv 종가로 1주/1개월/3개월/6개월/1년/전체 수익률 그리드
- TradingValuePanel: chart.trading_value 외국인/기관/개인 최근 5일 표 (억원 단위)
- [code]/page.tsx 레이아웃 재배치: 수익률 → 거래주체+메트릭 → 뉴스+공시

백엔드 변경 없음 — 기존 ChartPayload 의 미사용 시리즈를 재활용.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 14:57:40 +09:00
claude-owner
da36195cf3 feat(ui): 관심종목(localStorage) + DART 공시 패널
- web/lib/watchlist.ts: KEY=stockchart.watchlist, storage+custom event 구독
- StarButton: 종목 페이지 헤더에서 ☆/★ 토글
- /watchlist 페이지: 카드 그리드 + 현재가/전일대비 + ✕ 제거
- DisclosuresPanel: 기존 /api/news?source=dart 재사용 (백엔드 신설 없음)
- 종목 페이지 하단에 공시 패널 부착, 홈에 ★ 관심종목 링크 추가

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 14:54:43 +09:00
claude-owner
ae4f07d675 feat(home+search): KOSPI/KOSDAQ 인덱스 카드 + 검색결과 미니 sparkline
- Sparkline 컴포넌트를 PriceHero 내부에서 web/components/Sparkline.tsx 로 분리·재사용
- /api/markets/indices: macro_daily 의 kospi/kosdaq N일 시계열 + 최신값/전일대비
- 홈 IndicesPanel: 두 인덱스 카드(현재값/등락/우측 sparkline)
- /api/symbols/search?with_sparkline=true: 결과 한 번에 최근 30 종가 batch 조회
- SearchBox 결과 행에 mini sparkline + 현재가/등락률 인라인 표시

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 14:46:13 +09:00
claude-owner
66a28cc7ca feat(themes): 테마 인덱스/상세 (11 카테고리 · 111 종목)
- seed/themes.py: 반도체/2차전지/바이오/게임/엔터/자동차/금융/조선·방산/플랫폼·AI/유통·소비재/에너지 정적 매핑
- /api/themes (인덱스) + /api/themes/{slug} (종목 카드 + 최신 종가/등락)
- 홈에 ThemeTiles 그리드, /themes/{slug} 상세 페이지

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 14:29:16 +09:00
claude
21db09f65f feat(markets): /api/markets/movers + /related/{code} + 홈/종목 페이지 연동
backend:
  - 신규 라우터 app/api/markets.py
  - GET /api/markets/movers?market=ALL|KOSPI|KOSDAQ&limit=10
    → gainers / losers / by_volume 3 카테고리. ohlcv_daily 최신 2 거래일 비교.
  - GET /api/markets/related/{code}?limit=8
    → 같은 market 내 거래량 상위 (sector 컬럼은 시드 단계 NULL 다수라 제외).
  - main.py 에 라우터 include.

frontend:
  - lib/api.ts 에 Mover/MoversResponse/RelatedResponse 타입 + .movers/.related 추가.
  - components/MarketsOverview.tsx: 등락 상위 / 등락 하위 / 거래량 상위 3 컬럼.
  - components/RelatedStocks.tsx: 같은 시장 내 관련 종목 8 개.
  - 홈 페이지에 MarketsOverview 배치 (SeedTiles 아래).
  - 종목 페이지 우측 사이드바 컬럼에 RelatedStocks 추가 (SymbolSidebar 아래).

verify: py_compile clean, tsc --noEmit clean, next lint clean.
2026-05-28 01:36:13 +09:00
claude
04358469d1 feat(ui): 홈 SEED-10 타일 + 가격 헤로 sparkline
홈 페이지:
  - 텍스트 카드를 SeedTiles 컴포넌트로 교체. 10개 병렬로 /api/chart 2일치 받아
    현재가 + 전일대비 (절대값+%) 카드 그리드 (2/3/5 컬럼).
  - max-w 를 3xl → 5xl 로 확장하여 타일 5열 그리드 수용.

종목 페이지:
  - PriceHero 에 series prop 추가, 우측에 SVG sparkline (최근 30 종가) 표시.
  - 라인 색상은 전일대비 부호로 결정 (상승 빨강 / 하락 파랑).
  - lightweight-charts 인스턴스 추가 없이 인라인 SVG 만 사용 — 가벼움.

verify: tsc/next lint clean.
2026-05-28 01:27:49 +09:00
claude
832e73b5ee feat(ui): 뉴스 리스트 카드 리디자인 (감성 칩 + 출처 배지 + 상대시간)
토스 뉴스 카드 톤. 변경:
  - 감성 라벨을 chip 형식으로 (긍정=빨강, 부정=파랑, KR 관행 유지)
  - 출처를 작은 배지로 분리, 본문과 시각 구분
  - published_at 을 'N분 전 / N시간 전 / N일 전' 상대시간으로
  - 카드 hover 시 border-zinc-700 강조

썸네일은 백엔드가 og_image 미제공이라 텍스트 카드로 한정. 추후 백엔드에
컬럼 추가되면 SourceBadge 위에 16:9 썸네일 슬롯 추가.

verify: tsc/next lint clean.
2026-05-28 01:22:43 +09:00
claude
16aeba1a20 feat(ui): 우측 시세 정보 사이드바 추가 (시가/고가/저가/거래량/52주범위)
토스 종목 페이지 우측 카드와 동일 위치/구성. ChartPayload(1Y, 1d) 한 번 받아
오늘 OHLC + 1년 high/low 만 계산. 백엔드가 PER/EPS/시총 미제공이라 제외.

lg 브레이크포인트에서 chart(1fr) + sidebar(280px) 그리드.
mobile 에서는 사이드바가 chart 아래로 스택.

verify: tsc --noEmit clean, next lint clean.
2026-05-28 01:21:43 +09:00
Claude
b16f2b578d feat(ui): 예측 오버레이 캔들화 + 7탭 기간 셀렉터 + 가격 헤로
- 예측 오버레이: 라인 시리즈 3개 (median/q10/q90) 를 단일 캔들 시리즈
  하나로 합쳤다. 합성 OHLC: open=직전 close, close=point_close,
  high=ci_high, low=ci_low. 옅은 색 (up #fda4af / down #93c5fd) 으로
  실 캔들과 시각 톤은 같고 명도만 낮춰 "어우러지되 미래"임이 보이게.
- 예측 프리셋 단순화: 단기/중기/장기 + 직접입력 다 떼고 15일/30일/1년
  3개로. 백엔드 horizon cap 30 → 252 로 확장 (1년 = 240 거래일).
- PriceHero: 종목명/현재가/등락 큰 글씨 헤더. KR 관례대로 상승=빨강,
  하락=파랑.
- PeriodTabs: 1일/1주/1달/3달/1년/5년/최대 7탭. 기존 interval+days
  이중 컨트롤 제거. 5년·최대 는 자동으로 주봉/월봉으로 폴백.
- 차트 본체 캔들 색조도 KR 관례 (적/청) 로 통일.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 01:05:23 +09:00
claude-owner
44873ddb39 fix(chart): "오늘" 표시를 차트 본체 마커 → 시간축 아래 캡션으로 이동
lightweight-charts 의 timeScale tick 라벨에 직접 텍스트를 끼우는 공식 API 가
없어서, 차트 컨테이너 바로 아래에 작은 캡션 (• 오늘 · YYYY-MM-DD (요일)) 으로
표시. 사용자 요청 ("차트에 표시 말고 아래 날짜 표시하는 곳에").
2026-05-23 02:49:36 +09:00
claude-owner
e610599879 fix(chart): 10분봉 페이지네이션, 장외 캐시, 예측 horizon 캡 일치
reviewer 지적사항 반영:

1. KIS 분봉이 한 번에 30개만 와서 10분봉이 최대 3개만 나오던 문제 →
   fetch_minute_range() 추가. FID_INPUT_HOUR_1 을 30분씩 후퇴시키며
   페이지네이션, 중복 ts 자연 dedupe, max_pages=20 으로 무한루프 방지.
   _ensure_intraday_fresh 는 last_ts+1m ~ now 빈 구간만 채우므로 평소엔
   1~2 페이지로 끝남.

2. 장외/주말에 매번 KIS 를 때리던 문제 →
   - 주말: 'weekend' 반환, KIS 안 부름 (분봉 endpoint 는 당일만 지원)
   - 평일 장외 + 오늘 데이터 있음: 'cached_closed' 반환
   - 장중 + 10분 이내: 'fresh' 반환
   토큰/조회 제한 다시 밟지 않음.

3. 프론트 horizon 입력 60 vs 백엔드 30 불일치 →
   PredictionPanel 의 cap 을 30 으로 맞춤. 백엔드 predict.py 의 학습/검증
   범위와 일치. placeholder 도 '1~30' 으로 명시.
2026-05-23 01:41:43 +09:00
claude-owner
0a5c634680 feat(chart): 10m 실시간 / 일·주·월 토글 / 오늘 마커 / 예측 거래일 선택
- backend/app/api/chart.py: interval=10m|1d|1w|1mo. 10m 은 ohlcv_1m 을
  time_bucket(10min) 으로 집계, stale(>10분) 이면 KIS 분봉 fetch 후 재조회.
  1w/1mo 는 ohlcv_daily 를 date_trunc 로 집계. today 필드 추가.
- backend/app/fetch/kis.py: fetch_minute_price() 추가 (tr_id FHKST03010200).
  KIS 응답 KST 시각을 tz-aware datetime 으로 변환, 오름차순 정렬.
- web/lib/api.ts: ChartInterval 타입, getChart(interval), predict(horizons[]).
- web/components/StockChart.tsx: 10m 이면 timeVisible. 일·주·월에서 오늘
  화살표 마커 표시. ISO datetime 도 파싱.
- web/components/PredictionPanel.tsx: 단기/중기/장기 프리셋 + 사용자 직접
  지정 (예: 1,2,3,7). API 에 horizons 배열 전달.
- web/app/[code]/page.tsx: interval 칩 (10분/일/주/월). 10m 일 때 60초마다
  폴링. interval 별 기본 lookback (10m=1, 1d=180, 1w=730, 1mo=1825).
2026-05-23 01:34:29 +09:00
tkrmagid
4fb6cec383 feat(phase-6): Next.js UI + TypeScript strict + 백엔드 mypy 설정
UI:
- web/lib/api.ts: 백엔드 모든 엔드포인트의 클라이언트 + 타입 (Symbol,
  ChartPayload, PredictResponse, LatestPredictionResponse, MetricsResponse,
  NewsResponse). NEXT_PUBLIC_API_BASE 자동 정규화.
- web/components/SearchBox: 디바운스 검색, seed_only 토글, trigram + prefix.
- web/components/StockChart: lightweight-charts 캔들 + 예측 overlay
  (median dashed + q10/q90 점선). base_date 에서 target_date 까지 이어 붙임.
- web/components/PredictionPanel: "예상차트 보기" 버튼 → POST /api/predict
  → user_triggered=TRUE 저장 → onResult 콜백으로 StockChart 에 반영.
  표로 +1/+3/+5거래일 direction, prob_up/flat/down, expected_return,
  ci_low~ci_high 표시.
- web/components/MetricsPanel: 최근 30일 hit_rate / mae.
- web/components/NewsList: 최근 뉴스 + 감성 라벨/점수.
- web/app/page.tsx: 검색 페이지.
- web/app/[code]/page.tsx: 종목 상세 (차트 + 패널 + 메트릭 + 뉴스).

TypeScript 보강 (사용자 요청 "typescript도 추가해서 나중에 수정하기 쉽게"):
- tsconfig.json: strict 외에 forceConsistentCasingInFileNames,
  noFallthroughCasesInSwitch, noImplicitOverride 추가.
- package.json: typecheck (tsc --noEmit), check (typecheck + lint) 스크립트,
  eslint + eslint-config-next 14.2.3.
- .eslintrc.json: next/core-web-vitals.
- package-lock.json 커밋 (재현 가능한 dep).

백엔드:
- pyproject.toml: [tool.mypy] 추가. strict_optional, no_implicit_optional,
  check_untyped_defs. 3rd-party stub 없는 pykrx/chronos 등은 ignore.

검증: `npx tsc --noEmit` 통과 (exit=0).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 16:10:24 +09:00