# CLAUDE.md

이 파일은 Claude Code(claude.ai/code)가 이 저장소에서 작업할 때 참고하는 가이드입니다.

## 명령어

```bash
# 애플리케이션 실행
go run main.go

# 바이너리 빌드
go build -o stockSearch .

# 전체 테스트 실행
go test ./...

# 단일 테스트 실행
go test -run TestFunctionName ./...

# 린트 실행 (golangci-lint 설치 필요)
golangci-lint run
```

## 작업 방침

- 필요한 명령어(빌드, 테스트 등)는 사용자에게 묻지 않고 직접 실행한다.
- /Users/hayato5246/GolandProjects/stockSearch/kiwoom_api_doc.txt 이 문서는 키움증권 REST API 문서입니다.
- Bash Commmand 실행 시 묻지 말고 직접 실행하고 테스트 까지 처리해서 확인한다.
- 코드 수정시 사용자에게 묻지 말고 직접 수정한다.

## 언어 설정

- 코드 주석은 **한글**로만 작성한다.
- 사용자에 대한 답변은 가능한 모든 부분을 **한글**로 작성한다.

## 프로젝트 정보

- **모듈명**: `stocksearch`
- **Go 버전**: 1.22 이상
- 키움증권 REST API 기반 주식 시세 웹서비스 (api.kiwoom.com)

## 아키텍처

```
main.go → 라우터 설정, WebSocket Hub 고루틴 시작, HTTP 서버 실행
config/         환경변수 (.env) 로딩
models/         순수 데이터 구조체 (비즈니스 로직 없음)
services/       키움 API 클라이언트, 토큰 관리, 캐시, 비즈니스 로직
handlers/       HTTP 핸들러 (HTML 렌더링 / JSON API / WebSocket)
websocket/      Hub 패턴 실시간 시세 (1초 Ticker + gorilla/websocket)
middleware/     로깅, 패닉 복구
templates/      Go html/template SSR (layout/base.html 상속)
static/         Tailwind CSS, Lightweight Charts, WebSocket 클라이언트 JS
```

**레이어 의존성**: `handlers → services → models`, `websocket → services`

**템플릿 구조**: 각 페이지별 독립 템플릿 세트 파싱 (content 블록 충돌 방지)
- `NewPageHandler()`에서 base.html + 각 페이지 html을 별도 ParseFiles로 파싱
- `render()`에서 `ExecuteTemplate(w, "base.html", data)` 호출

## 주요 설계 사항

- **토큰 관리**: `services/token_service.go` — 서버 시작 시 토큰 발급, 만료 1시간 전 자동 갱신
  - 응답 필드: `token` (access token), `expires_dt` (YYYYMMDDHHmmss)
- **캐시**: `services/cache_service.go` — sync.Map 기반 TTL 캐시 (현재가 1초, 차트 5분, 등락률 1분)
- **WebSocket Hub**: `websocket/hub.go` — 1초 Ticker로 구독 종목 시세 조회 → 클라이언트에 브로드캐스트
- **Rate Limit**: KiwoomClient에 `golang.org/x/time/rate` 적용 (초당 18건)
- **관심종목**: 클라이언트 localStorage 저장, WebSocket 실시간 구독
 
## 키움증권 REST API

- **기본 URL**: `https://api.kiwoom.com`
- **공통 요청**: POST, JSON body, 헤더에 `api-id`, `authorization: Bearer {token}`, `cont-yn`, `next-key`
- **토큰 발급**: `POST /oauth2/token` (appkey + secretkey)
- **현재가** `ka10001`: `POST /api/dostk/stkinfo` → `cur_prc`, `pred_pre`, `flu_rt`, `trde_qty`, `open_pric`, `high_pric`, `low_pric`, `stk_nm`
- **체결정보** `ka10003`: `POST /api/dostk/stkinfo` → `cntr_infr[0].cntr_str` (체결강도)
- **일봉** `ka10005`: `POST /api/dostk/mrkcond` → `stk_ddwkmm[]` (date, open_pric, high_pric, low_pric, close_pric, trde_qty)
- **등락률순위** `ka10027`: `POST /api/dostk/rkinfo` → `pred_pre_flu_rt_upper[]`

## 환경 설정

`.env` 파일 (`.gitignore`에 등록됨):
```
KIWOOM_APP_KEY=...
KIWOOM_APP_SECRET=...
KIWOOM_BASE_URL=https://api.kiwoom.com
SERVER_PORT=8080
```
