목표물과 기조
숙지다른 캡스톤과 같은 기조입니다: 빈 폴더에서 superpowers 워크플로로 설계하고 Phase 단위로 빌드합니다. 목표물은 실존 프로젝트 stock-monitoring(FastAPI + React + Bedrock, AWS ECS 운영)을 135분 스코프로 압축한 웹 시황 데스크입니다. 실데이터이며, 45초마다 바뀝니다.
| 레이어 | 구성 | 핵심 원칙 |
|---|---|---|
| 백엔드 | FastAPI, /api/market/*, /api/stocks/*, 인메모리 TTL 캐시 | 업스트림 호출은 캐시 뒤로, 같은 키 동시 요청은 한 번만(single-flight) |
| 프런트 | React(Vite) + react-query + lightweight-charts | 화면은 우리 API만 본다, 45초 폴링, AI만 fetch 직접 |
| AI | Bedrock converse_stream, SSE(phase → delta → final) | AWS_BEARER_TOKEN_BEDROCK, 키 없으면 503과 패널 비활성 |
| 완결성 | make run 한 번으로 :8000 통합 서빙, 배포 없음 | 프록시(/proxy/8000/)로 확인, 스크린샷이 피날레 |
1. Dashboard (메인 화면)
| 기능 | 설명 |
|---|---|
| 경제지표 바 | WTI, Gold, 환율, 금리, Bitcoin 등 config의 지표를 실시간 표시 |
| 시장 지수 | S&P 500, NASDAQ, DOW / KOSPI, KOSDAQ - 카드 5장, 등락색 |
| 종목 테이블 | US/KR 탭 전환, Symbol/Name/Price/Change/%/Volume, 상승 초록/하락 빨강 |
| 자동 갱신 | react-query 45초 폴링, 장 마감 시간대는 백엔드가 600초 절전 |
2. StockDetail (종목 상세)
| 기능 | 설명 |
|---|---|
| 가격 헤더 | 현재가, 등락률, 거래량 (StockHeader) |
| 캔들 차트 | lightweight-charts, 1W/1M/3M/1Y 기간 탭 (PriceChart) |
| 수익률과 52주 | 기간 수익률 4종(ReturnsRow) + 52주 범위 내 현재 위치(Week52Bar) |
| AI 종목 분석 | 버튼 → SSE 스트리밍, 기술적 분석/투자 포인트/리스크 3절 (AIPanel) |
이 캡스톤을 마치면 다음 네 가지를 설명할 수 있고, 다시 만들 수 있습니다.
| 목표 | 검증되는 순간 |
|---|---|
| 업스트림 API를 캐시와 single-flight 뒤로 정리하는 백엔드 계약 설계 | M2에서 같은 curl 두 번, 두 번째가 즉시 도착할 때 |
| 폴링(react-query)과 스트리밍(SSE)을 구분해 쓰는 프런트 데이터 전략 | M3의 45초 폴링과 M4의 델타 누적이 다른 코드 경로로 공존할 때 |
| Bedrock 스트리밍(converse_stream)을 제품 기능으로 포장하는 법 | M4에서 phase 배지와 타자기 렌더가 동작할 때 |
| superpowers Phase 리듬으로 풀스택을 조립하는 법 | M1의 계획이 M2~M4에서 그대로 소화될 때 |
이 캡스톤은 새 기술을 가르치지 않습니다. Ch1~6에서 배운 것을 실전 배치합니다.
| 챕터 | 이 캡스톤에서 재등장하는 곳 |
|---|---|
| Ch1 설치부터 Headless까지 | M0~전체: 세션 운용, 지시 → 실행 → 검증 루프, CLAUDE.md를 존중하는 습관 |
| Ch2 Subagents | M2~M3: code-reviewer 서브에이전트로 Phase 산출물 리뷰, 백엔드/프런트 병렬 진행 |
| Ch3 Admin Setup | M0/M4: Bedrock 라우팅과 자격의 배경, Bearer 키가 조직 통제선 안에서 도는 이유 |
| Ch4 Settings, 훅과 스킬 | OPT: 하네스 성숙화, 훅과 스킬을 프로젝트 자산으로 승격하는 마무리 의식 |
| Ch5 CLI Reference | 확장 방향: 헤드리스 패턴으로 /api/health 스모크를 파이프라인화 |
| Ch6 Agent SDK | 확장 방향: 백엔드에 in-process 도구로 Claude를 심는 다음 단계의 방향 |
구현 청사진, 원작 상세 분석
참고원작 stock-monitoring의 실코드를 분석해 뽑은 구현 지도입니다. M1 설계가 이 구조로 수렴하도록 방향을 잡아 주고, 계획이 이상하게 흐르면 여기로 돌아와 대조하세요.
[폴링 경로] 45초마다 (장 마감 시 600초)
Browser ── react-query ──> FastAPI ──> TTL Cache ──(miss, single-flight)──> yfinance / pykrx
^ | |
+──── JSON 완결 응답 ──────+ (hit) 즉시 반환, 업스트림 무호출
[스트리밍 경로] 버튼 눌렀을 때만
Browser ── fetch(SSE) ──> FastAPI ── converse_stream ──> Bedrock (Sonnet 4.6)
^ |
+── phase → delta* → final + (한 글자씩, react-query를 쓰지 않는 유일한 경로)
Level 200의 핵심 구분입니다: 완결된 결과를 주기적으로 당기는 경로(폴링)와 부분 결과를 밀어 받는 경로(스트리밍)는 캐시 전략도, 프런트 도구도 다릅니다. 이 캡스톤은 둘을 한 앱에서 병용합니다.
| 화면 | 구성 컴포넌트 | 전환 |
|---|---|---|
| Dashboard | 지표 바, 지수 카드, 종목 테이블(US/KR 탭) | 종목 클릭 → StockDetail |
| StockDetail | StockHeader, FundamentalCards, PriceChart(캔들), ReturnsRow, Week52Bar, OrderBook, InvestorPanel, StockNews, AIPanel | react-router, 뒤로 가기 복귀 |
| ArticleAnalysis | 기사 본문 + AI 분석(react-markdown 렌더) | 뉴스에서 진입 |
워크샵 스코프는 핵심 구성만: StockHeader + PriceChart + ReturnsRow + Week52Bar + AIPanel. OrderBook/InvestorPanel/StockNews/ArticleAnalysis는 바이브 코딩 라운드의 확장 과제로 남깁니다.
| 라우트 | 역할 |
|---|---|
| GET /api/health | 살아있음 확인 |
| GET /api/market/overview | 지수 5종 + 경제지표 (Dashboard 상단) |
| GET /api/market/quotes | US/KR 종목 시세 일괄 |
| GET /api/stocks/{symbol} | 가격 헤더 + 기간 수익률 + 52주 범위 |
| GET /api/stocks/{symbol}/chart?range= | 캔들 OHLC (1w/1m/3m/1y, 원작은 기간별 TTL 캐시) |
| POST /api/ai/stocks/{symbol} | SSE 스트리밍 분석 (원작은 기사 분석 POST /api/ai/articles도 제공) |
| 계약 | 내용 |
|---|---|
| 갱신 주기 | 주가 45초, 뉴스 120초, 장 마감 시간대 600초 절전 (market-hours-aware) |
| 캐시 | 원작은 L1 메모리 + L2 DynamoDB 티어드(TTL: 차트 기간별, 펀더멘털 12h, AI 6h, L2 24h) + single-flight 잠금 + 60초 시세 오버레이. 워크샵은 L1 메모리 + single-flight만 |
| AI 스트리밍 | 호출 프리미티브는 converse_stream 하나(블로킹 invoke_model은 삭제됨). SSE 이벤트 phase → delta* → final, 시나리오별 maxTokens 상한 분리(잘림 신호 ai_stream_truncated) |
| 프런트 데이터 | react-query가 45초 폴링으로 화면을 살리되, AI 스트리밍만 fetch 직접: react-query는 "완결된 결과 하나"를 캐시하는 모델이라 델타 누적에 맞지 않는다(원작 주석) |
| 키의 거처 | Bedrock 인증은 boto3 기본 해석에 맡긴다 = AWS_BEARER_TOKEN_BEDROCK 환경변수를 그대로 인식. 자격 실패는 503으로 매핑, 앱은 정상 |
| 선택 | 이유 |
|---|---|
| FastAPI | 라우트 = 계약, pydantic 응답 모델로 프론트가 그대로 그린다 |
| react-query | 폴링/캐시/로딩 상태를 선언형으로, 45초 갱신이 한 줄 |
| lightweight-charts | 금융 캔들 차트의 표준, 가볍고 기간 전환이 빠르다 |
| SSE | AI 응답을 한 글자씩, WebSocket보다 단순한 단방향 스트림 |
| make run | 프론트 빌드를 backend/static에 넣어 :8000 하나로 통합 서빙 |
사전 준비
10분Python과 Node 확인, 프로젝트 폴더, 그리고 Bearer 키(.env)까지. Phase 4의 AI 스트리밍에 필요합니다.
python3 --version && node --version # Python 3.11+, Node 20+
mkdir -p ~/capstone/capstone-2 && cd ~/capstone/capstone-2
git init -q 2>/dev/null; git config user.name "capstone"; git config user.email "capstone@lab.local"
다른 캡스톤에서 이미 만들었다면 ~/capstone/.env가 있으니 1/2는 건너뛰세요.
mkdir -p ~/capstone
grep -q AWS_BEARER_TOKEN_BEDROCK ~/capstone/.env 2>/dev/null || cat >> ~/capstone/.env << 'ENVEOF'
AWS_BEARER_TOKEN_BEDROCK=<발급받은 Bedrock API 키>
ENVEOF
set -a; source ~/capstone/.env; set +a
aws bedrock-runtime converse \
--region ap-northeast-2 \
--model-id global.anthropic.claude-sonnet-4-6 \
--messages '[{"role":"user","content":[{"text":"ping"}]}]' \
--inference-config '{"maxTokens":30}' \
--query 'output.message.content[0].text' --output text
설계, 브레인스토밍
15분API 계약, 캐시, SSE 스트리밍, Phase 순서까지 요구 9조항으로 넘깁니다.
이 미션의 바탕 학습: Ch1의 세션 운용과 Capstone Setup의 superpowers 워크플로.
cd ~/capstone/capstone-2 && claude
/superpowers:brainstorming 다음 요구사항으로 "Market Desk on Web", 웹 시황 대시보드를 설계하자.
1) 구조: backend/(Python 3.11+ FastAPI, app/api 라우트, app/services 데이터, app/core/config.py 상수,
venv + requirements.txt: fastapi, uvicorn, yfinance, pykrx, httpx, boto3) +
frontend/(Vite + React + TypeScript, 의존성: @tanstack/react-query, lightweight-charts)
2) 데이터: yfinance(미국 주식 + 지수 ^GSPC/^IXIC/^DJI + 경제지표), pykrx(한국 주식, 지수는 yfinance
^KS11/^KQ11). 종목/지표 목록은 config.py 상수로, 실데이터 목록은 설계 직후 이어서 제공한다.
시작은 US 20 + KR 20으로 잘라 쓰고 전체 50 + 50은 config에서 여는 구조로.
개별 심볼 실패는 건너뛰고, US 시세는 yf.download 벌크로
3) API 계약(FastAPI 라우트): GET /api/health, GET /api/market/overview(지수 5 + 지표),
GET /api/market/quotes(US/KR 시세), GET /api/stocks/{symbol}(가격 헤더 + 기간 수익률 + 52주 범위),
GET /api/stocks/{symbol}/chart?range=1w|1m|3m|1y(캔들 OHLC). 응답은 프론트가 그대로 그릴 수 있는 JSON
4) 캐시: 인메모리 TTL 캐시 하나로 시작(시세 45초, 차트는 기간별로 길게), 같은 키 동시 요청은 한 번만
부르는 single-flight 잠금. 장 마감 시간대에는 갱신 주기를 600초로 늦춘다
5) Dashboard 화면: 상단 경제지표 바, 지수 카드 5장(등락색), 종목 테이블(US/KR 탭, Symbol/Name/Price/
Change/%/Volume, 상승 초록/하락 빨강), react-query로 45초 자동 갱신
6) StockDetail 화면: 테이블에서 클릭 진입. StockHeader(현재가, 등락률, 거래량), lightweight-charts
캔들 차트(1W/1M/3M/1Y 기간 탭), ReturnsRow(기간 수익률 4종), Week52Bar(52주 범위 내 현재 위치),
뒤로 가기로 대시보드 복귀
7) AI 분석(SSE 스트리밍): POST /api/ai/stocks/{symbol}가 Bedrock converse_stream
(global.anthropic.claude-sonnet-4-6, maxTokens 1024)으로 기술적 분석/투자 포인트/리스크를 한국어로
생성하며 text/event-stream으로 흘린다. 이벤트는 phase → delta(부분 텍스트)* → final 순서.
프론트 AIPanel은 델타를 누적해 타자기처럼 렌더하고, 이 호출만 react-query 대신 fetch를 직접 쓴다
(react-query는 완결된 결과 캐시 모델이라 점진 델타에 맞지 않는다).
인증은 환경변수 AWS_BEARER_TOKEN_BEDROCK(발급 API 키), boto3 클라이언트에 자격 인자를 넣지 않고
리전 ap-northeast-2. Bedrock IAM 정책은 만들지 않으며, 키가 없으면 503을 주고 패널만 비활성
8) UI 무드(텍스트 스펙): 다크 딥네이비, 숫자 우측 정렬, 상승 초록 ▲ / 하락 빨강 ▼,
AI 패널은 스트리밍 중 phase 배지(fetching/analyzing)를 보여준다
9) 구현 순서는 Phase 1(백엔드 코어: overview/quotes/{symbol}/chart + 캐시, uvicorn과 curl 검증) →
Phase 2(Dashboard, dev 서버로 미리보기) → Phase 3(StockDetail + 캔들 차트) →
Phase 4(AI SSE + 프론트 빌드를 backend/static으로 넣어 :8000 통합 서빙).
시간 제약 2시간: 테스트 생략, curl과 브라우저로 검증. 호가/투자자 동향/뉴스는 후순위(확장 과제로만 남긴다)
결정이 필요하면 이 범위 안에서 최소한으로만 물어봐.
이어서, 방금 설계에 쓸 config.py 실데이터야. 이 상수들을 config.py에 그대로 반영해줘.
이름 매핑(US_STOCK_NAMES)과 섹터 매핑(US_STOCK_SECTORS)은 네가 아는 대로 채워.
REFRESH_INTERVAL = 45
CLOSED_REFRESH_INTERVAL = 600 # 장 마감 시 절전 주기
NEWS_REFRESH_INTERVAL = 120
US_INDICES = {"^GSPC": "S&P 500", "^IXIC": "NASDAQ", "^DJI": "DOW"}
KR_INDICES = {"^KS11": "KOSPI", "^KQ11": "KOSDAQ"}
US_STOCKS = [
"AAPL","MSFT","GOOGL","AMZN","NVDA","META","TSLA","BRK-B","JPM","V",
"JNJ","UNH","WMT","MA","PG","HD","XOM","CVX","LLY","ABBV",
"PFE","KO","PEP","MRK","COST","AVGO","AMD","ORCL","CRM","NFLX",
"ADBE","CSCO","ACN","TXN","INTC","QCOM","INTU","AMAT","BKNG","ISRG",
"MDLZ","ADP","REGN","VRTX","GILD","PANW","LRCX","MU","KLAC","SNPS",
]
KR_STOCKS = { # 코드: 이름 (섹터는 아래 어휘로 네가 매핑)
"005930":"Samsung Electronics","000660":"SK Hynix","373220":"LG Energy Solution",
"005380":"Hyundai Motor","000270":"Kia","207940":"Samsung Biologics",
"006400":"Samsung SDI","035420":"NAVER","035720":"Kakao","005490":"POSCO Holdings",
"068270":"Celltrion","028260":"Samsung C&T","105560":"KB Financial","055550":"Shinhan Financial",
"012330":"Hyundai Mobis","066570":"LG Electronics","003670":"POSCO Future M","051910":"LG Chem",
"096770":"SK Innovation","034730":"SK","000810":"Samsung Fire","003550":"LG",
"032830":"Samsung Life","009150":"Samsung Electro","086790":"Hana Financial","010130":"Korea Zinc",
"033780":"KT&G","011200":"HMM","247540":"Ecopro BM","377300":"Kakao Pay",
"030200":"KT","017670":"SK Telecom","018260":"Samsung SDS","036570":"NCsoft",
"316140":"Woori Financial","003490":"Korea Shipbuilding","034020":"Doosan Enerbility",
"011170":"Lotte Chemical","024110":"Industrial Bank of Korea","010950":"S-Oil",
"006800":"Mirae Asset Securities","004020":"Hyundai Steel","000720":"Hyundai E&C",
"002790":"Amore Pacific","138040":"Meritz Financial","259960":"Krafton",
"326030":"SK Biopharm","323410":"Kakao Bank","361610":"SK IE Technology","352820":"Hive",
}
KR 섹터 어휘: Semiconductor, Battery, Auto, Auto Parts, Bio, Internet, Steel, Holding, Financial,
Insurance, Securities, Fintech, Electronics, Materials, Chemical, Energy, Telecom, IT Services,
Gaming, Shipbuilding, Industrial, Shipping, Construction, Cosmetics, Entertainment, Tobacco,
Non-Ferrous, Components
INDICATORS = { # 심볼: (이름, 단위)
"CL=F": ("WTI Oil","$"), "GC=F": ("Gold","$"), "SI=F": ("Silver","$"), "HG=F": ("Copper","$"),
"EURUSD=X": ("EUR/USD",""), "KRW=X": ("USD/KRW","W"), "JPY=X": ("USD/JPY",""),
"CNY=X": ("USD/CNY",""), "^TNX": ("US 10Y","%"), "BTC-USD": ("Bitcoin","$"), "ETH-USD": ("Ethereum","$"),
}
SECTOR_INDICATOR_MAP = { # 종목 섹터 -> 관련 지표 (Detail의 관련 지표 매핑)
"Technology": ["^IXIC","BTC-USD"], "Semiconductor": ["^IXIC","BTC-USD"],
"Internet": ["^IXIC","BTC-USD"], "Communication": ["^IXIC","BTC-USD"],
"Energy": ["CL=F","HG=F"], "Chemical": ["CL=F","HG=F"], "Materials": ["CL=F","HG=F"],
"Financial": ["^TNX","EURUSD=X"], "Insurance": ["^TNX","EURUSD=X"], "Fintech": ["^TNX","BTC-USD"],
"Consumer": ["GC=F","EURUSD=X"], "Auto": ["KRW=X","CL=F"], "Healthcare": ["GC=F","^TNX"],
"Bio": ["GC=F","^TNX"], "Battery": ["HG=F","SI=F"], "Steel": ["HG=F","CNY=X"],
"Telecom": ["^TNX","KRW=X"], "Holding": ["^TNX","KRW=X"], "Electronics": ["^IXIC","KRW=X"],
}
NEWS_FEEDS = {
"yahoo": "https://finance.yahoo.com/news/rssindex",
"yahoo_markets": "https://feeds.finance.yahoo.com/rss/2.0/headline?s=^GSPC®ion=US&lang=en-US",
"hankyung": "https://www.hankyung.com/feed/economy",
"mk": "https://www.mk.co.kr/rss/30100041/",
}
auto mode on을 선언해 두면 superpowers가
brainstorming → write-plan → execute-plan의 단계 전환과 승인 대기를 자동으로 이어 갑니다.
시간이 빠듯할 때 유용합니다. 단계마다 직접 검토하려면 기본(수동)을 유지하고, 되돌리려면
auto mode off입니다.
브레인스토밍 후 /superpowers:write-plan으로 계획을 만들고
Phase 4개 구성을 승인하세요. 계획이 위 구현 청사진(화면/라우트/운영 계약)과 대체로 합치하는지,
그리고 후순위 규칙(호가/투자자 동향/뉴스는 확장 과제로)이 반영됐는지 확인하세요.
Phase 1, 백엔드 코어
35분FastAPI가 overview / quotes / 종목 상세 / 차트를 캐시 뒤에서 돌려주면 이 Phase는 끝입니다.
이 미션의 바탕 학습: Ch1의 지시 → 실행 → 검증 루프. 여유가 있다면 Ch2의 code-reviewer 서브에이전트에게 캐시 모듈 리뷰를 맡겨 보세요.
/superpowers:execute-plan Phase 1만 구현하고 멈춰줘. backend venv + requirements, config.py(제공한 실데이터, US/KR 각 20개 활성), services(yfinance 벌크 + pykrx, 개별 실패 스킵), 인메모리 TTL 캐시 + single-flight, 라우트 4종(overview, quotes, stocks/{symbol}, chart?range=). uvicorn 실행과 curl 검증 방법까지.
cd backend && .venv/bin/uvicorn app.main:app --port 8000 &
sleep 3
curl -s localhost:8000/api/market/overview | head -c 300; echo
curl -s "localhost:8000/api/stocks/AAPL/chart?range=1m" | head -c 200; echo
막힐 때 열어보기, single-flight 캐시 핵심 힌트
import time, threading
_store, _locks = {}, {}
def get_or_fetch(key: str, ttl: int, fetch):
now = time.time()
hit = _store.get(key)
if hit and now - hit[0] < ttl:
return hit[1]
lock = _locks.setdefault(key, threading.Lock())
with lock: # 같은 키 동시 요청은 한 번만
hit = _store.get(key)
if hit and time.time() - hit[0] < ttl:
return hit[1]
val = fetch()
_store[key] = (time.time(), val)
return val
Phase 2 + 3, 대시보드와 상세
45분React 대시보드가 45초마다 숨 쉬고, 종목을 클릭하면 캔들 차트가 있는 상세 화면이 열립니다.
이 미션의 바탕 학습: Ch2의 병렬 감각. 프런트를 빌드하는 동안 백엔드 응답 필드 보강을 서브에이전트로 병행할 수 있습니다.
/superpowers:execute-plan Phase 2만 구현해줘. frontend(Vite React TS): 요구 5의 Dashboard(지표 바, 지수 카드 5장 등락색, US/KR 탭 종목 테이블), react-query 45초 폴링, dev 프록시(:5173 → :8000). 실행 방법을 알려줘.
cd frontend && npm run dev # 브라우저에서 /proxy/5173/
/superpowers:execute-plan Phase 3(StockDetail)을 구현해줘. 테이블 클릭 → react-router 진입: StockHeader(현재가/등락률/거래량), lightweight-charts 캔들(1W/1M/3M/1Y 기간 탭), ReturnsRow(기간 수익률 4종), Week52Bar(52주 범위 내 위치), 뒤로 가기 복귀까지.
Phase 4, AI 스트리밍과 개장
30분분석 버튼을 누르면 Bedrock의 답이 한 글자씩 흘러드는 것, 이 캡스톤의 하이라이트입니다.
이 미션의 바탕 학습: Ch3에서 본 Bedrock 라우팅과 자격의 배경, 그 위에서 도는 스트리밍 계약.
/superpowers:execute-plan Phase 4(AI SSE)를 구현해줘. POST /api/ai/stocks/{symbol}: Bedrock converse_stream(global.anthropic.claude-sonnet-4-6, maxTokens 1024, 리전 ap-northeast-2, 자격 인자 없이 환경변수 AWS_BEARER_TOKEN_BEDROCK, IAM 정책 금지)으로 기술적 분석/투자 포인트/리스크 3절을 text/event-stream으로: 이벤트 phase → delta* → final. 프론트 AIPanel은 fetch 직접 + 델타 누적 타자기 렌더 + phase 배지. 키 없으면 503과 패널 비활성. 마지막으로 npm run build 산출물을 backend/static으로 넣어 :8000 통합 서빙(make run 또는 스크립트)까지.
set -a; source ~/capstone/.env; set +a # Bearer 키 로드
make run # 프론트 빌드 → :8000 통합 서빙, 브라우저에서 /proxy/8000/
curl -N -X POST localhost:8000/api/ai/stocks/AAPL.
event: phase 한 줄, 이어서 event: delta와
data: {"text": "..."}가 반복되다가 event: final로 닫힙니다.
프런트의 타자기는 이 delta들을 이어 붙인 것뿐입니다, 마법이 아니라 계약입니다.
X-Accel-Buffering: no 헤더와 미디어타입 text/event-stream을 확인하세요.
대시보드 → 종목 상세 → 분석 스트리밍까지 한 바퀴 돌리고, 흐르는 화면의 스크린샷을 Slack에 공유하세요. 그게 개장입니다. 원작은 여기에 티어드 캐시(DynamoDB L2)와 ECS Fargate 배포까지 얹혀 운영 중입니다, 다음 단계가 궁금하다면 그 방향입니다. 그리고 Ch5의 헤드리스 패턴으로 /api/health 스모크를 파이프라인화하면 운영의 첫 발입니다.
데스크 퀄리티 강화 라운드, 기능을 올려라
+α 자유핵심 구성이 돌았다면 이제 데스크를 내 것으로 만드는 시간입니다. 원작에 실존하는 기능들을 강화 카드로 준비했습니다, 끌리는 것을 골라 하나씩 주문하세요. 요령은 같습니다: 한 번에 하나, 화면으로 확인하고, 마음에 들면 커밋.
StockDetail에 호가창(OrderBook)을 추가하자. GET /api/stocks/{symbol}/orderbook:
현재가를 중심으로 매도 10단계(파란 막대, 왼쪽으로) / 매수 10단계(빨간 막대, 오른쪽으로),
공개 실데이터가 없으니 random.seed(int(price * 100))로 가격에 고정된 그럴듯한 시뮬레이션.
프론트는 3열(매도잔량 | 가격 | 매수잔량) 레이아웃, 45초 폴링에 동참.
StockDetail에 투자자 동향(InvestorPanel)을 추가하자. GET /api/stocks/{symbol}/investors:
개인/외국인/기관의 최근 10일 순매수 추정치 표. 실데이터가 없으니 일별 거래량과 캔들 방향에서
개인 60 / 외국인 30 / 기관 10 비율로 추정하고 개인은 역방향 가정(원작 방식).
순매수 초록 / 순매도 빨강, 날짜 내림차순.
종목 뉴스(StockNews)와 기사 AI 분석 화면(ArticleAnalysis)을 추가하자.
1) GET /api/stocks/{symbol}/news: Yahoo Finance RSS에서 해당 심볼 뉴스 5건(제목, 링크, 시각)
2) 뉴스 클릭 → /article 라우트: httpx로 본문 추출(외부 URL만 허용하는 SSRF 가드) 후
POST /api/ai/articles가 SSE로 요약/시장 영향/투자 인사이트를 스트리밍(기존 delta 계약 재사용)
3) 영어 기사는 한국어 번역을 맨 앞에.
라이트/다크 듀얼 테마를 추가하자. 기본은 prefers-color-scheme, 헤더 토글로 전환,
선택은 localStorage에 기억. 색은 전부 CSS 변수로 빼서 두 테마 모두에서
등락색(초록/빨강)과 차트 캔들의 대비가 유지되게. lightweight-charts의 배경/그리드 색도 테마를 따라가게.
여기부터는 정해진 카드가 없습니다. 당신이 프로덕트 오너입니다. 시황을 보며 아쉬웠던 것 하나를 골라, 위 카드들처럼 직접 요구사항을 써서 주문하세요. 아이디어가 필요하면: 관심종목 즐겨찾기, 등락률 알림 하이라이트, 섹터 등락 바, 시장 요약(Top 상승/하락), 지표 스파크라인, 뉴스 키워드 필터.
내 데스크에 [내가 원하는 기능]을 추가하자. 규칙:
1) API 계약: [필요한 라우트와 응답 형태 한두 문장]
2) 화면: [어디에 어떻게 보이는지, 갱신 주기]
3) 데이터: [출처, 실데이터가 없으면 시뮬레이션 방식]
4) 기존 캐시/폴링/스트리밍 계약은 깨지 않는다
구현 전에 이 규칙을 네 계획으로 다시 말해주고, 승인하면 진행해.
make run으로 통합 서빙을 다시 굳혀 Slack의 스크린샷을 최신으로.
바이브 코딩 라운드, 원작을 향해
+α 자유Phase 빌드가 끝났다면 이제 바이브 코딩입니다: 완성 화면의 묘사를 주고 "이렇게 나오게 해줘"를 반복하는 루프. 아래 세 장면은 원작이 실제로 도달한 모습을 글로 옮긴 것입니다. 내 화면과 다른 점을 찾아 하나씩 주문하세요.
- 상단 경제지표 바: 지표들이 가로로 흐르고 등락은 색과 ▲▼로
- 지수 카드 5장: 값 크게, 등락률 작게, 카드 보더나 포인트 컬러가 등락을 따른다
- 종목 테이블: US/KR 탭, 숫자 전부 우측 정렬 모노 감각, 행 호버 하이라이트
- footer 또는 헤더에 "마지막 갱신 시각"과 다음 갱신까지의 감각
- StockHeader: 심볼과 이름, 현재가 크게, 등락은 색+▲▼, 거래량은 축약(1.2M)
- 캔들 차트: 기간 탭(1W/1M/3M/1Y) 중 활성 탭 하이라이트, 상승 초록/하락 빨강 캔들
- ReturnsRow: 1W/1M/3M/1Y 수익률이 한 줄에, 양수 초록/음수 빨강
- Week52Bar: 52주 저가~고가 바 위에 현재가 마커
- 확장 후보(원작에 있는 것): 호가창 OrderBook, 투자자 동향 InvestorPanel, 종목 뉴스 StockNews,
기사 AI 분석 화면 ArticleAnalysis - 끌리는 것 하나를 같은 리듬으로 추가
- 분석 버튼을 누르면 phase 배지가 fetching → analyzing 으로 바뀌고
- 본문은 delta가 도착하는 대로 타자기처럼 자라며, 마크다운(## 절, 굵은 키워드)이 살아 있다
- 스트리밍 중 다시 누르면 진행 중인 요청을 취소하고 새로 시작
- 키가 없을 때는 "AI 분석 비활성" 안내만 조용히
하네스 엔지니어링, 작품을 성숙시키고 등급을 받다
+15분 옵션지금까지 만든 것은 결과물입니다. 이 옵션은 그 결과물을 만든 작업 환경, 즉 하네스 (CLAUDE.md, hooks, skills, commands, agents)를 표준 구조로 성숙시키고(project-init), 그 품질을 6개 차원(정확성, 안전성, 완전성, 실행 가능성, 일관성, 검증 가능성)에서 채점받는(harness-eval) 단계입니다. superpowers의 3단(brainstorm, write-plan, execute-plan) 뒤에 4단 성숙화와 5단 평가를 붙이는 셈입니다. 캡스톤 공통의 마무리 의식입니다.
이 미션의 바탕 학습: Ch4의 훅과 스킬을 팀 자산으로 승격하는 감각, 그리고 Reference 3의 플러그인 생태계.
claude plugin marketplace add https://github.com/whchoi98/project-init
claude plugin install project-init@project-init
claude plugin marketplace add https://github.com/whchoi98/harness-eval
claude plugin install harness-eval@harness-eval
claude plugin list
설치 후 새 Claude 세션을 시작하세요, superpowers 때와 같은 규칙입니다.
/project-init:init-project .
이 프로젝트의 하네스는 아직 얇습니다(FastAPI 앱과 React 앱 하나씩). 기존 프로젝트 감지 모드가 있는 것은 보존하고, 없는 것(문서 스캐폴딩, 시크릿 스캔 훅, /review 커맨드, 테스트 골격 등)만 채웁니다. CLAUDE.md가 이미 있으면 덮어쓰기 전에 물어봅니다. 끝나면 이어서:
/project-init:sync-docs
## Sync Report
### Quality Scores (Before -> After)
| ./CLAUDE.md | D (48) | B (82) | +34 |
| ./backend/CLAUDE.md | F (10) | C (61) | +51 |
### Changes Made
- Files created: 4 / Files updated: 2 / Runbooks missing: 1
/harness-eval:quick
{"mode": "quick", "scores": {"overall": 7.0, "grade": "B"}, "checklist": {"pass": 12, "warn": 3, "fail": 1}}
이 캡스톤의 비자명한 지식은 스트리밍 계약입니다. "왜 AI만 fetch를 직접 쓰는가, 왜 장 마감엔 600초로 늦추는가"를 CLAUDE.md의 패턴으로 기록해 두면 sync-docs 점수가 오르고, 다음에 이 저장소를 여는 Claude가 같은 원칙으로 확장합니다. 여유가 있다면 결정을 기록으로 남기세요:
/add-adr streaming-ai-contract
/add-runbook market-web-run
미션 종료
시세는 캐시 뒤에, 키는 서버에, AI는 스트림으로. 웹 시황 데스크의 문법입니다.
| 가져가는 것 | 내용 |
|---|---|
| 캐시가 곧 예의 | 업스트림은 캐시 뒤에서 한 번만, single-flight로 동시 요청도 한 번만 |
| 스트리밍 계약 | phase → delta → final, 그리고 "점진 델타에는 react-query가 아니라 fetch"라는 도구 선택의 근거 |
| 절전 설계 | 장이 닫히면 600초로 늦춘다, 시스템은 세상의 리듬을 알아야 한다 |