내 학습허브 — 학습 전자책
학습위키를 책으로 묶었어요. 로드맵이 서문, 주차가 챕터예요. 지금 20꼭지.
내 학습허브
AI와 함께한 한 달의 학습 기록
4주 로드맵 — 외국인에게 한국을 알리는 영상 제작 유튜브 채널 만들기
4주 뒤, 내 손에 남는 것 4가지
- 나만의 AI 학습메이트 — 나를 알고, 내 속도에 맞춰 함께 만들어주는 AI (미소)
- 확정된 내 주제 + 이 로드맵 — AI로 영상을 만들어, 해외 거주 외국인에게 한국 여행·쇼핑을 소개하는 유튜브 채널 기획
- 실제로 만든 결과물 — AI 영상 1~2개를 유튜브에 실제 업로드하고, 아마존 어소시에이츠 제휴 링크까지 삽입 완료한 상태 (이해만 한 게 아니라 진짜로 만든 것)
- 혼자서도 다음 영상을 만드는 근육 — 영상 편집을 몰라도, AI 툴로 대본부터 아바타 영상까지 스스로 다루는 힘
지금 나 vs 4주 뒤 되고 싶은 나
- 지금 나: AI 툴은 이미지 생성 정도만 써봄. 영상 편집 능력 없음. 전반적으로 아직 부족하다고 느낌.
- 되고 싶은 나: AI를 활용해서 결과물을 만드는 게 익숙한 사람.
→ 4주차 회고에서 이 둘을 다시 비교해봐요.
조사로 확인하고 반영한 것
로드맵을 짜기 전에, 실제로 어떻게들 하고 있는지 찾아봤어요.
- 외국인이 한국 콘텐츠 중 실제로 많이 보는 건 먹방·K-드라마·K-팝, 그리고 여행 팁·쇼핑 리뷰예요. 이 중 여행·쇼핑이 제휴 링크(아마존)랑 자연스럽게 이어져서 이걸로 방향을 잡았어요.
- AI로 영상을 만드는 채널은 실제로 되는 방식이고, 여행·쇼핑 니치가 수익성이 좋다고 알려져 있어요. 다만 새 채널이 자리잡는 데 보통 6~12개월 걸린다는 게 현실적인 기대치예요 — 4주 안에 “채널이 떡상”하는 게 목표가 아니라, **“만들어서 실제로 올려본 경험”**이 목표예요.
- 2026년 유튜브 정책상, AI로 만든 영상이라는 라벨(AI 콘텐츠 표시)을 꼭 붙여야 해요.
- 처음엔 쿠팡파트너스를 생각했는데, 쿠팡은 해외 배송을 공식 지원하지 않아서 해외 거주 외국인 시청자에게는 잘 안 맞는다는 걸 확인했어요. 그래서 아마존 어소시에이츠로 바꿨어요 — 한국 거주자도 가입 가능하고(정산은 기프트카드나 Payoneer), 해외 시청자가 자기 나라 아마존에서 바로 구매할 수 있어요.
1주차 — 기획
- 할 일: 학습메이트 세팅 ✅ · 인터뷰로 주제 발굴 ✅ (해외 거주 외국인 대상, AI 영상으로 한국 여행·쇼핑 소개, 아마존 제휴) · 이 로드맵 작성 ✅ · 내 사이트 로컬 미리보기·배포
- 이번 주 결과물: 이 로드맵 문서 + 내 사이트 첫 화면(랜딩)
- 사례글 예시: “오늘 내 유튜브 채널 컨셉을 정하고, 내 사이트를 처음 띄워봤다”
2주차 — 상세 계획
- 할 일:
- 채널 기획서 한 장 쓰기 (채널명, 톤앤매너, 영상 길이 — 쇼츠 vs 롱폼)
- AI 영상 제작 툴 비교·선택 (예: HeyGen, Vidnoz, D-ID 등)
- 첫 영상 주제 5개 리스트업 (예: “한국 여행 갈 때 꼭 챙길 것”, “한국에서만 파는 꿀템”)
- 대본 구조 1개 완성해보기
- 위키에 개념 쌓기: “AI 영상 제작이란”, “유튜브 알고리즘 기초”, “아마존 어소시에이츠란”
- 이번 주 결과물: 채널 기획서 1장 + 대본 1개 + 개념페이지 여러 개
- 사례글 예시: “AI 영상 제작 툴 3개를 직접 비교해봤다”
3주차 — 제작
- 할 일:
- 대본 → 실제 AI 영상으로 제작
- 유튜브 채널 개설, 첫 영상 업로드 (AI 라벨 표시)
- 아마존 어소시에이츠 가입·제휴 링크 발급받아 영상 설명란에 삽입
- 인스타 릴스용 숏폼 버전도 만들어 업로드
- 반복 작업 자동화 시도 (대본 템플릿, 썸네일 자동 생성 등)
- 이번 주 결과물: 실제 업로드된 영상 1~2개 (유튜브+인스타) + 제휴 링크 삽입 완료
- 사례글 예시: “드디어 첫 영상을 유튜브에 올렸다!“
4주차 — 회고·발표
- 할 일: 한 달 돌아보기(지금 나 vs 되고 싶은 나 비교), 발표자료 준비, 전자책 마무리(이 로드맵이 서문이 돼요)
- 이번 주 결과물: 회고 글 + 발표
- 사례글 예시: “한 달 동안 나는 어떻게 달라졌나”
4주 로드맵 — 미국 주식 AI 모의매매 에이전트 사이트 만들기
4주 뒤, 내 손에 남는 것 4가지
- 나만의 AI 학습메이트 — 이미 만들어둔 미소가, 이번엔 이 프로젝트도 함께 도와줌
- 확정된 내 주제 + 이 로드맵 — 미국 주식 소수 종목 대상, AI 모의매매 에이전트 + 성과 공개 사이트
- 실제로 만든 결과물 — 미국 주식 5~15개 종목을 두고, AI가 매일 가상(모의) 매매 판단을 내리고 그 판단·수익률을 그래프로 보여주는 웹사이트를 실제로 만들어 다른 사람도 볼 수 있게 공개한 상태
- 혼자서도 다음 걸 만드는 근육 — 뉴스·주가 데이터를 가져와 AI 판단에 연결하고, 그걸 웹사이트로 배포하는 흐름을 낯설지 않게 다루는 힘
지금 나 vs 4주 뒤 되고 싶은 나
- 지금 나: AI로 뭔가를 직접 만들어본 적이 아직 없음. 제일 걱정되는 건 “이게 얼마나 잘 구현될까”.
- 되고 싶은 나: AI를 활용해서 뭔가를 만들고 배포하는 게 익숙해져서, 다른 걸 개발하는 데도 어색함이 없는 사람.
→ 4주차 회고에서 이 둘을 다시 비교해봐요.
왜 이 프로젝트를 하나 더
- 실제 돈을 쓰지 않고도, 내 투자 전략(혹은 AI의 판단)이 괜찮은지 미리 확인해볼 수 있는 지표를 만들어보고 싶었다.
- 뉴스나 실제 사건들이 주가에 얼마나·어떻게 영향을 주는지 직접 확인해보고 싶었다.
- 나 혼자만 쓰는 게 아니라, 다른 사람도 쓸 수 있는 사이트로 만드는 게 목표.
범위를 정한 이유 — “전체 종목”이 아니라 “소수 종목”
미국 상장 종목은 수천 개라, 기술적으로는 전체를 다 가져올 수도 있지만(무료 주식 데이터 API들이 있음), 4주짜리 첫 프로젝트로는 범위가 너무 크다. 그래서 내가 고른 5~15개 종목만 우선 다루기로 했다. 나중에 잘 되면 종목 수를 늘리는 건 언제든 가능하다.
1주차 — 기획·PRD + MVP 초반 착수
- 할 일: 이 로드맵 작성 ✅ · 다룰 종목 10개 정하기 ✅ (AAPL·MSFT·NVDA·TSLA·AMZN·GOOGL·META·JPM·XOM·KO) · 어떤 주식 데이터 API를 쓸지 조사 ✅ · 프로젝트 PRD·세부계획 작성 · Finnhub API로 실제 데이터 가져오는 최소 테스트 코드 작성해보기 (MVP 첫 조각)
- 이번 주 결과물: 이 로드맵 문서 + 확정된 종목 리스트 + API 조사 결과 + PRD + API 연동 테스트 성공
API 조사 결과 — Finnhub로 결정
가격·뉴스를 하나의 API로 해결할 수 있어서 Finnhub로 정했다.
- 실시간 주가(quote) — 무료
- 회사별 뉴스 — 무료 (최근 1년치 + 실시간)
- 요청 제한 — 분당 60번, 하루 제한 없음 (종목 10개 매일 확인엔 충분)
- 신용카드 없이 가입 가능
- 단, 과거 몇 년치 시세(캔들) 데이터는 무료 플랜에 없음 → 어차피 “매일 가상 매매”라 매일 그날 가격을 직접 기록해서 내 데이터를 쌓아가면 되니 문제없음
- 사례글 예시: “미국 주식 AI 에이전트, 어떤 종목으로 시작할지 정했다”
2주차 — MVP 본격 제작
- 할 일:
- AI가 뭘 근거로 매매 판단을 내릴지 확정 (가격 흐름 기반 vs 뉴스 기반 vs 둘 다) 후 매매 판단 규칙 실제로 만들기 (예: “이 조건이면 산다/판다”)
- 매일 가상 매매 판단을 내리는 로직 실제로 만들기
- 그 판단·수익률을 보여주는 대시보드(그래프) 페이지 만들기 시작
- 위키에 개념 쌓기: “주식 API란”, “페이퍼(모의) 트레이딩이란”, “뉴스가 주가에 영향을 주는 방식”
- 이번 주 결과물: 작동하는 매매 판단 로직 + 대시보드 초안 + 개념페이지 여러 개
- 사례글 예시: “드디어 AI가 매일 가상으로 주식을 사고팔기 시작했다”
3주차 — MVP 완성·다듬기
- 할 일:
- 대시보드(그래프) 페이지 완성
- 실제로 배포해서 다른 사람도 볼 수 있게 공개
- 반복 작업 자동화 시도 (매일 자동으로 판단 돌리기)
- 전체적으로 다듬기 (버그 수정, UI 정리)
- 이번 주 결과물: 실제로 작동하는 대시보드 사이트 완성본 (공개 상태)
- 사례글 예시: “매일 자동으로 돌아가는 AI 주식 에이전트를 완성했다”
4주차 — 회고·발표
- 할 일: 한 달 돌아보기(지금 나 vs 되고 싶은 나 비교), 발표자료 준비, 전자책 마무리
- 이번 주 결과물: 회고 글 + 발표
- 사례글 예시: “한 달 동안 AI로 뭘 만들 수 있게 됐나”
PRD — 미국 주식 AI 모의매매 에이전트
1. 뭘·왜·누구를 위해 (로드맵에서 그대로)
- 뭘: 미국 주식 중 내가 고른 10개 종목(AAPL·MSFT·NVDA·TSLA·AMZN·GOOGL·META·JPM·XOM·KO)을 두고, AI가 매일 가상(모의)의 돈으로 매매 판단을 내리고, 그 판단·수익률을 그래프로 보여주는 웹사이트.
- 왜: 실제 돈을 쓰지 않고도 투자 전략(혹은 AI의 판단)이 괜찮은지 미리 확인해볼 수 있는 지표를 만들어보고 싶었고, 뉴스나 실제 사건이 주가에 얼마나·어떻게 영향을 주는지 직접 확인해보고 싶었다.
- 누구를 위해: 케빈님 본인(학습·검증 목적) + 다른 사람도 볼 수 있게 공개하는 사이트 (로그인 없이 누구나 열람).
자세한 4주 계획은 4주 로드맵 참고. 이 문서는 그중 “만들기”를 실제로 시작할 수 있게 구체화한 것.
2. 매매 판단 근거 — 가격 + 뉴스, AI 종합 판단
매일 종목별로 그날의 가격 변화 + 최신 뉴스를 함께 AI에게 주고, AI가 종합적으로 “매수 / 매도 / 보유”를 판단한다.
- 예: “TSLA는 오늘 뉴스가 긍정적이고 가격도 올랐으니 매수” 같은 식.
- 판단할 때마다 왜 그렇게 판단했는지 이유(근거)도 함께 남긴다 — 대시보드에 그대로 노출할 것이므로, “이유 없음”은 없다.
- 로드맵의 목적(“뉴스가 주가에 미치는 영향 확인”)과 가장 잘 맞는 방식.
3. 화면 구성 (대시보드)
한 화면에서 아래 3가지가 다 보여야 한다.
- 종목별 현재 상태 — 10개 종목 각각 지금 “보유중” 인지 “현금” 인지, 보유중이면 수량·평가금액
- 수익률 그래프 — 전체 포트폴리오($10,000 기준) 수익률이 날짜별로 어떻게 변해왔는지 꺾은선 그래프
- 매매 히스토리 + 이유 — “언제, 어떤 종목을, 왜 샀는지/팔았는지” 목록 (2번의 AI 판단 근거를 그대로 노출)
4. 가상 자본금
- 총 $10,000을 10개 종목에 균등 분배 → 종목당 $1,000으로 시작
- 매수 판단이 나면 그 종목에 배정된 현금 한도 내에서 매수, 매도 판단이 나면 보유분을 전량 매도해 현금으로 전환
- 종목 간 자금을 서로 옮기지는 않는다 (각 종목은 독립된 $1,000 예산으로 시작해서 각자 굴러간다 — 종목별 성과 비교가 목적이므로)
5. 실행 주기
- 매일 하루 1번, 자동 실행 (미국 장 마감 데이터 기준)
- 사람이 매일 버튼을 누를 필요 없음 — 아래 6번 기술 방법으로 완전 자동화
6. 만드는 방법 — 지금 가장 쉬운 조합 (2026년 기준 조사)
베낄 필요 없이 케빈님이 이미 쓰는 도구(GitHub, Astro) 위에서 끝나는 조합.
| 역할 | 도구 | 왜 이걸 |
|---|---|---|
| 매일 자동 실행 | GitHub Actions 예약 실행(cron) | 새 서비스 가입 없이 이미 있는 저장소에서 바로 씀. 무료. 서버 관리 불필요 |
| 데이터 저장 | JSON 파일 1개를 저장소에 계속 커밋 | 데이터베이스 없이 제일 간단. “매일 그날 기록 쌓기” 구조와 정확히 맞음 |
| 화면(대시보드) | Astro 페이지 1개 추가, 그 JSON을 읽어서 표+그래프로 렌더 | 이미 쓰는 프레임워크라 새로 배울 게 없음 |
| 배포 | Vercel 또는 Netlify 무료 요금제, GitHub 연결 | GitHub Actions가 매일 커밋 → 자동으로 사이트도 매일 다시 배포됨 (사람 개입 0) |
- 무료 요금제 기준 스케줄 실행은 하루 1번 정도가 한도인 경우가 많은데, 이 프로젝트는 원래 “하루 1번 가상 매매”라 딱 맞음.
- 더 쉬운 대안(LiteLambda, n8n 같은 노코드 자동화 서비스)도 있지만, 새 계정·새 플랫폼을 추가로 배워야 해서 이미 GitHub을 쓰고 있는 케빈님껜 GitHub Actions 조합이 더 적은 노력으로 끝나는 길임.
7. 이번엔 안 하는 것 (Out of scope)
- 실제 증권사 연동·실거래 (계속 가상 매매만)
- 로그인·회원가입 (누구나 그냥 보는 공개 페이지)
- 종목 10개 → 더 늘리기 (나중에 잘 되면 확장)
- 과거 몇 년치 시세 백테스트 (Finnhub 무료 플랜에 없음 — 매일 쌓아가는 걸로 대체, Day 4 사례 참고)
8. 다음 단계
이 PRD가 로드맵 2주차(“MVP 본격 제작”)의 설계도가 된다. 다음은:
- GitHub Actions 워크플로 파일 만들기 (매일 실행)
- Finnhub API로 가격+뉴스 가져와서 AI에게 넘기고 판단받는 스크립트 작성
- 판단 결과를 JSON에 쌓는 로직 작성
- Astro 대시보드 페이지 만들어서 그 JSON 표시
세부 실행계획 — 미국 주식 AI 에이전트 (PRD 쪼개기)
어제(PRD)에서 “뭘 만들지”를 정했다. 오늘은 “어떻게 만들지”를 하루 단위로 잘게 쪼개고, 그중 AI 판단 부분을 어떤 방법으로 호출할지 최신 기준으로 조사한 결과를 반영한다.
조사 결과 — AI 판단은 뭘로, 어떻게 부를까
PRD 6번엔 “GitHub Actions + JSON + Astro” 조합만 정해뒀고, AI에게 판단을 실제로 어떻게 물어볼지는 안 정해져 있었다. 조사한 결과는 이렇다.
| 결정할 것 | 선택 | 왜 |
|---|---|---|
| 어떤 AI 모델 | Claude Sonnet 5 | 이 작업(가격+뉴스 보고 판단+이유 쓰기)은 아주 복잡한 추론이 아니라 “일반 작업” 수준이라, 제일 비싼 모델(Opus)까진 필요 없다. 그렇다고 제일 빠르고 싼 모델(Haiku)만 쓰기엔 뉴스 해석 품질이 아쉬울 수 있어서, 그 중간인 Sonnet 5가 비용 대비 딱 맞다. |
| Node.js에서 부르는 법 | 공식 SDK(@anthropic-ai/sdk) | 직접 fetch로 API를 부르는 것보다 훨씬 짧고 안전하게 짤 수 있다. npm install로 바로 설치. |
| ”판단+이유”를 안정적으로 JSON으로 받기 | 구조화된 출력(structured output) | “매수/매도/보유 중 하나 + 이유 문장”을 매번 정확히 같은 모양의 JSON으로 강제해서 받을 수 있는 기능. 이게 없으면 AI가 가끔 형식을 다르게 답해서 코드가 깨질 수 있는데, 이 기능을 쓰면 그럴 일이 없다. |
참고로 케빈님이 지금 쓰는 Claude Code 구독(Pro)과 이 API 키는 별개예요. 스크립트에서 API를 부르려면 console.anthropic.com에서 API 키를 따로 발급받아야 해요 (사용한 만큼 별도 과금, Pro 구독료와는 무관).
Finnhub(가격·뉴스) 쪽은 문서 페이지가 자바스크립트라 자동으로는 못 읽었어요. 일반적으로 알려진 형태(GET /api/v1/quote, GET /api/v1/company-news)로 계획엔 넣어뒀지만, 실제 코드를 쓰는 2단계에서 케빈님 화면에서 문서를 열어 다시 한번 같이 확인할게요.
세부계획 (실행 단계별)
PRD의 “다음 단계”(워크플로 ✅ → AI 판단 스크립트 → JSON 저장 로직 → 대시보드)를 작은 단계로 쪼갰다. 원래는 하루에 하나씩 할 계획이었지만, 실제로는 1~3단계를 첫날(7/28, 1주차 6일차)에 다 끝냈다.
★ 여기서 쓰는 “N단계”는 작업 순서일 뿐, 챌린지의 “Day N”(달력 날짜)과는 다른 번호다. 헷갈리지 않게 사례글의 “Day N”은 항상 실제 날짜를, 이 문서의 “N단계”는 작업 순서만 가리킨다.
완료 (7/28)
-
1단계 — API 키 준비 ✅
- Finnhub API 키 실제로 발급받기 (이미 갖고 있어서 바로 확인만 함)
- Anthropic API 키 발급받기 (console.anthropic.com)
- 두 키를 내 컴퓨터에만
.env파일로 저장 (Git에 안 올라가게)
-
2단계 — 데이터 하나 가져와보기 (MVP 첫 조각) ✅
- 종목 1개(AAPL)만 골라서, Finnhub에서 오늘 가격 + 최신 뉴스 가져오는 코드 작성
- 콘솔에 출력해서 데이터가 어떤 모양으로 오는지 직접 확인
-
3단계 — AI 판단 연결 (종목 1개로 테스트) ✅
@anthropic-ai/sdk설치- 2단계의 가격·뉴스를 프롬프트로 만들어 Claude Sonnet 5에 보내고, “매수/매도/보유 + 이유”를 구조화된 출력(JSON)으로 받기
- 결과: AI가 실제로 “보유” 판단과 이유를 내려줌
남은 계획
-
4단계 — 10종목 전체 + 자산 계산
- 3단계 로직을 10종목 전체에 반복 적용
- 매수/매도 판단에 따라 종목별 현금·보유수량을 계산해서
data/trades.json갱신 - 결과물:
scripts/trade.js가 자리표시자가 아니라 진짜로 동작
-
5단계 — 매일 자동 실행 실전 연결
- Finnhub·Anthropic API 키를 GitHub Secrets에 등록
.github/workflows/daily-trade.yml이 4단계의 진짜 로직을 실행하도록 연결workflow_dispatch(수동 실행 버튼)로 한 번 실제 실행해서 확인- 결과물: 사람 개입 없이 자동으로 하루 매매가 기록됨
-
6단계 — 대시보드 뼈대: 종목별 상태
- Astro에 새 페이지(예
/dashboard) 추가 data/trades.json을 읽어서 10종목의 지금 상태(보유중/현금)를 표로 보여주기- 결과물: 브라우저에서 지금 상태를 볼 수 있음
- Astro에 새 페이지(예
-
7단계 — 대시보드: 수익률 그래프
- 전체 포트폴리오($10,000 기준) 수익률 추이를 꺾은선 그래프로 표시
- (그래프 그리는 제일 쉬운 방법은 이 단계에서 다시 한번 조사)
- 결과물: 수익률이 날짜별로 어떻게 움직였는지 한눈에 보임
-
8단계 — 대시보드: 매매 히스토리 + 이유
- “언제·어떤 종목·왜 샀는지/팔았는지” 기록을 화면에 리스트로 표시 (3~4단계의 AI 판단 이유를 그대로 노출)
- 결과물: PRD 3번(화면 구성) 3가지가 다 완성
-
9단계 — 통합 테스트 + 다듬기
- 실제 배포(Vercel)에서도 잘 보이는지 확인
- 자동 실행 → 데이터 갱신 → 사이트 반영까지 끝에서 끝까지 한 번 확인
- 자잘한 버그 수정
- 결과물: 로드맵 2주차 목표(“작동하는 매매 판단 로직 + 대시보드 초안”) 완성
다음 단계
**4단계(10종목 전체 확장 + 자산 계산)**부터 이어가면 된다.
프로젝트 소개 — 미국 주식 AI 모의매매 에이전트
1주차 회고 — 종합사례글이 “이번 주 배운 것”에 초점을 맞췄다면, 이 문서는 지금 만들고 있는 프로젝트 자체를 소개하는 자리다.
왜 이 프로젝트를 만드나
- 실제 돈을 쓰지 않고도, 내 투자 전략(또는 AI의 판단)이 괜찮은지 미리 확인해볼 수 있는 지표를 만들어보고 싶었다.
- 뉴스나 실제 사건이 주가에 얼마나·어떻게 영향을 주는지 직접 확인해보고 싶었다.
- 나 혼자만 쓰는 게 아니라, 다른 사람도 볼 수 있는 사이트로 만드는 게 목표다.
뭘 만들고 있나
미국 주식 중 업종·변동성을 골고루 섞어 고른 10개 종목(AAPL·MSFT·NVDA·TSLA·AMZN·GOOGL·META·JPM·XOM·KO)을 두고, AI가 매일 가상의 돈(총 $10,000, 종목당 $1,000)으로 매수/매도/보유 판단을 내리고, 그 판단·이유·수익률을 그래프로 보여주는 공개 웹사이트를 만들고 있다.
어떻게 만들고 있나
- 로드맵 → 뭘·왜·누구를 위해 정하기
- PRD → “실제로 만들려면 뭐가 더 필요한지” 구체화 (판단 근거, 화면 구성, 자본금, 실행 주기, 만드는 방법)
- 세부계획 → 9단계로 잘게 쪼개서 하루씩 진행
실제 기술 조합 (전부 무료·이미 쓰던 도구 위주로 선택):
| 역할 | 도구 |
|---|---|
| 가격·뉴스 데이터 | Finnhub API |
| AI 판단 | Claude API (Sonnet 5) — “구조화된 출력”으로 매번 정확한 JSON(판단+이유)을 받음 |
| 매일 자동 실행 | GitHub Actions |
| 화면·배포 | Astro + Vercel |
지금까지 진행 상황
1주차 안에 PRD·세부계획을 끝내고, 실제로 AAPL 데이터를 가져와 AI한테 “보유”라는 판단과 이유를 받아내는 데까지 성공했다 — 처음으로 “진짜 작동하는” 상태.
다음 (2주차)
10종목 전체로 확장하고, 매일 자동 실행에 실제 로직을 연결하고, 대시보드 화면을 만든다.
3주차 완성 기준 — 남은 기능 골라내기
4주 로드맵상 3주차 목표(대시보드 완성 + 배포 공개 + 자동화)는 사실 2주차 안에 이미 다 끝나 있었다. 그래서 3주차엔 “새 기능 하나 추가”부터 시작했는데(첫 번째로 종목별 필터·정렬을 만듦), 이어서 나온 후보가 여러 개라 수요일(8/12) 마감을 앞두고 뭘 반드시 끝내야 하는지 다시 정리했다.
후보 분류
| 분류 | 항목 | 이유 |
|---|---|---|
| 필수 (이것만 되면 완성) | 종목별 개별 수익률 그래프 | 필터·정렬로 “종목 하나 골라보기”까진 됐는데, 그 종목의 수익률 추이는 아직 못 봄 — 자연스러운 다음 조각. 전체 포트폴리오 그래프의 SVG 좌표 계산 코드를 거의 그대로 재사용할 수 있어서, 남은 시간 대비 확실하게 끝낼 수 있음 |
| 있으면 좋음 | 매매 히스토리 한줄요약 뱃지 | 지금 이유 문장이 다 2~3줄이라 훑어보기 불편한 건 사실. 기존 이유 문장 첫 문장만 뱃지로 보여주는 정도로 가볍게, 시간 남으면 추가 |
| 이번엔 빼는 게 나음 | AI 판단 “신뢰도” 점수 | 실제로 AI가 신뢰도를 계산해서 준 적이 없어서, 지금 넣으면 그럴듯해 보이는 가짜 숫자를 만들어 붙이는 셈. 근거 없는 지표를 대시보드에 올리는 건 오히려 신뢰를 깎아먹음 — 나중에 AI 판단 로직 자체에 신뢰도 산출을 넣을 때 같이 하는 게 맞음 |
완성 기준
지금 만들고 있는 “종목별 개별 수익률 그래프”가 대시보드에 붙어서, 필터로 고른 종목 하나의 수익률 추이를 볼 수 있게 되면 — 이번 주는 완성이다.
진행 상황 (8/10 기준)
- 종목별 필터·정렬 — 완료
- 종목별 개별 수익률 그래프 (필수) — 완료 → 완성 기준 충족
- 매매 히스토리 한줄요약 뱃지 (있으면 좋음) — 시간 남으면 추가
- AI 판단 신뢰도 점수 — 이번엔 안 함
기타
개념 — API와 MCP, 방향이 반대인 두 연결
주식 에이전트 프로젝트가 자동으로 잘 돌아가는 걸 보다가, “이거 API로 되는 거면 MCP는 언제 쓰는 거지?” 하는 의문이 들었다. 둘 다 “AI나 프로그램이 바깥과 연결되는 방법”이라 헷갈리기 쉬운데, 화살표 방향이 서로 반대라는 게 핵심이었다.
오늘 나온 개념
API — 내 프로그램 → 저쪽 서비스
API는 “내가 짠 코드가 바깥 서비스에 손을 뻗는” 연결이다. scripts/trade.js가 매일 밤 하는 일이 정확히 이거다.
내 스크립트(trade.js) → Finnhub(주가·뉴스)
내 스크립트(trade.js) → Anthropic(AI 판단)
코드가 “이 주소로 이런 데이터를 요청해줘”라고 먼저 손을 내밀고, 서비스가 응답을 돌려준다. 사람 개입 없이 자동으로 돌아가는 파이프라인엔 이 방향이 맞다 — GitHub Actions가 새벽에 혼자 이 코드를 실행하고, 아무도 지켜보지 않아도 된다.
MCP — AI ← 내 도구·데이터
MCP는 반대다. AI(케빈님이 지금 대화하고 있는 저 같은 도구)가 케빈님의 파일이나 케빈님이 쓰는 서비스에 직접 손을 뻗을 수 있게 연결해주는 규격이다.
AI(Claude) ← 케빈님의 파일·데이터베이스·다른 서비스
예를 들면 “내 캘린더 일정 좀 봐줘”, “내 슬랙 메시지 보내줘” 처럼, 대화 중인 AI가 그 자리에서 바깥에 접근해야 하는 상황에 쓴다. 지금 이 대화창에서 제가 git이나 vercel 명령어를 실행하거나 브라우저를 여는 것도 넓게 보면 이 방향(AI가 도구에 접근)에 속한다.
왜 이번 프로젝트엔 MCP가 안 나왔나
주식 에이전트는 사람 없이 혼자 도는 자동화가 목표였다. AI(Claude)가 대화 중에 실시간으로 뭔가에 손을 뻗을 필요가 없고, 그냥 정해진 스크립트가 API 두 개(Finnhub·Anthropic)를 순서대로 부르기만 하면 끝난다. MCP는 “AI가 대화하면서 내 도구에 살아있게 연결돼야 하는” 상황에 필요한 거라, 애초에 이 프로젝트 구조와는 방향이 안 맞았다.
요약
| 용어 | 방향 | 쉬운 뜻 | 이 프로젝트에서 |
|---|---|---|---|
| API | 내 프로그램 → 저쪽 서비스 | 코드가 먼저 손을 내밀어 데이터를 요청 | trade.js가 Finnhub·Anthropic을 부를 때 씀 (실제로 씀) |
| MCP | AI ← 내 도구·데이터 | AI가 대화 중에 내 파일·서비스에 직접 접근 | 자동화라 AI가 실시간으로 붙어있을 필요가 없어서 안 씀 |
1주차
AI로 짧은 영상(쇼츠) 만들기 — 개념 이해
케빈님이 가져온 사례(원문 보기)는 Claude Code로 AI 쇼츠 영상 한 편을 만들어서 유튜브에 올린 이야기예요. 여기서는 따라 만드는 방법이 아니라, 이 사례에 나온 개념들만 쉽게 풀어볼게요.
전체 그림 먼저
쇼츠 영상 한 편은 사실 여러 AI 도구가 이어붙어서 만들어져요. 순서만 보면:
스토리보드(장면 설계) → 이미지 생성 AI(장면 그림) → 영상 편집(움직임·자막) → TTS(목소리) → 유튜브 업로드
이렇게 다섯 조각이 붙어서 영상 하나가 나와요. 케빈님이 나중에 릴스·유튜브용 영상을 만들 때도 결국 이 다섯 조각 중 몇 개를 골라 쓰게 될 거예요.
개념 풀이
1. 스토리보드 — 영상의 설계도
영상을 만들기 전에 “1번 장면엔 이게 나오고, 2번 장면엔 이게 나온다”처럼 순서를 미리 정해두는 것. 이 사례에서는 AI(Claude)가 주제 하나만 던지면 6장면짜리 스토리보드를 알아서 짜줬어요.
2. 이미지 생성 AI
글로 설명하면(예: “벚꽃놀이에서 생긴 고부갈등”) 그 장면을 그림으로 그려주는 AI예요. 이 사례에서는 Google의 이미지 생성 도구(Gemini)를 API로 연결해서 썼어요.
💡 API란? 서로 다른 프로그램끼리 대화하는 약속이에요. “이미지 생성 AI한테 API로 요청한다” = “그 AI 서비스에 인터넷으로 그림을 그려달라고 부탁한다”는 뜻이에요.
3. 영상 편집 — ffmpeg와 Ken Burns 효과
- ffmpeg: 영상·음성을 자르고 합치는 무료 프로그램이에요. 화면 버튼 없이 명령어로만 다뤄서, 케빈님이 나중에 직접 쓸 땐 AI(Claude)한테 “이 영상을 이렇게 편집해줘”라고 시키는 식이 돼요.
- Ken Burns 효과: 가만히 있는 사진을 천천히 확대하거나 이동시켜서, 정지 이미지도 마치 움직이는 영상처럼 보이게 하는 기법이에요. 이 사례의 영상은 실제 촬영 없이 이미지 + 이 효과만으로 “영상처럼” 만들어졌어요.
4. TTS — AI 목소리 더빙
텍스트를 사람 목소리로 바꿔주는 기술이에요(Text-to-Speech). 성우를 따로 섭외하지 않아도, 대사만 글로 쓰면 AI가 읽어줘요. 이 사례에서는 Google Gemini의 TTS로 6장면 분량의 한국어 대사를 목소리로 만들었어요.
5. 유튜브 업로드 — OAuth2 인증과 공개 범위
- OAuth2 인증: 내 구글 계정 비밀번호를 프로그램에 직접 알려주지 않고도, 구글이 “이 프로그램이 내 유튜브에 영상을 올려도 된다”고 안전하게 허락해주는 방식이에요.
- Unlisted(공개 범위): 유튜브 영상 공개 설정 중 하나로, 링크를 아는 사람만 볼 수 있고 검색이나 구독자 피드엔 안 뜨는 상태예요. 테스트할 때 자주 씁니다.
- YouTube Shorts: 유튜브의 세로 짧은 영상 포맷이에요. 케빈님이 목표로 하는 인스타그램 릴스도 같은 성격의 세로 짧은 영상 포맷이라, 이 사례의 영상 만드는 방식(이미지+효과+TTS+자막)은 릴스에도 그대로 쓸 수 있어요. 다만 업로드하는 곳(유튜브 API vs 인스타그램)만 다를 뿐이에요.
개념 정리표
| 용어 | 쉬운 뜻 | 어디서 나왔나 |
|---|---|---|
| 스토리보드 | 영상 장면을 순서대로 미리 정해두는 설계도 | 영상 기획 단계 |
| 이미지 생성 AI | 글로 설명하면 그림을 그려주는 AI | 장면 이미지 제작 |
| API | 프로그램끼리 서로 대화하는 약속 | 이미지·TTS 요청 |
| ffmpeg | 영상·음성을 자르고 합치는 무료 프로그램 | 영상 편집 |
| Ken Burns 효과 | 사진을 천천히 확대·이동시켜 움직이게 보이는 기법 | 정지 이미지 → 영상 |
| TTS | 글자를 목소리로 바꿔주는 기술 | 더빙(대사 음성) |
| OAuth2 인증 | 비밀번호 없이 안전하게 접근 권한을 허락하는 방식 | 유튜브 업로드 연동 |
| Unlisted | 링크 아는 사람만 볼 수 있는 공개 범위 | 업로드 테스트 |
| YouTube Shorts / 릴스 | 세로 짧은 영상 포맷 (유튜브 / 인스타그램) | 최종 업로드 형태 |
원문에서 자세히 안 나온 부분
사례글에 과정이 생략된 곳들이 있어요. 나중에 실제로 따라 만들 땐 이 부분에서 막힐 수 있으니 미리 알아두면 좋아요 (지금은 개념만 보는 단계라 채우지 않았어요):
- 구글 클라우드 콘솔에서 API 키·OAuth 인증 정보를 발급받는 구체적인 화면 절차
- 실제로 사용한 ffmpeg 명령어 옵션
- Claude Code에서 만든 “스킬”을 저장해서 재사용하는 방법
- TTS 목소리의 속도·톤 설정 여부
- 인스타그램 릴스 업로드는 이 사례에 없음 (유튜브만 다룸)
개념 — 주식 데이터 API 호출 & AI 판단 받기
2~3단계 튜토리얼에서 Finnhub API로 가격·뉴스를 가져오고, 그걸 Claude API에 넘겨 AI 판단까지 받아봤다. 그 코드에 나온 낯선 개념들을 정리한다.
오늘 나온 개념
쿼리 파라미터
URL 뒤에 ?이름=값 형태로 데이터를 실어 보내는 방식. 예를 들어
https://finnhub.io/api/v1/quote?symbol=AAPL&token=내키
에서 ? 뒤의 symbol=AAPL과 token=내키가 쿼리 파라미터다. “어떤 종목(symbol)을, 무슨 자격(token)으로 달라는지”를 이 방식으로 서버에 전달한다. 여러 개를 보낼 땐 &로 이어 붙인다.
fetch
자바스크립트에 내장된, 인터넷 너머의 데이터를 가져오는 함수. fetch(주소)라고 쓰면 그 주소로 요청을 보내고, 응답이 온다.
await / 비동기 처리
fetch처럼 응답이 올 때까지 시간이 걸리는 작업은, 그 결과가 올 때까지 “기다렸다가” 다음 줄을 실행해야 한다. 코드 앞에 await를 붙이면 “이 줄이 끝날 때까지 기다린 다음 다음 줄로 가라”는 뜻이 된다. 이렇게 기다림이 필요한 처리 방식을 비동기 처리라고 부른다.
가격 데이터 필드
Finnhub의 /quote가 돌려주는 시세 데이터는 이런 약자로 되어 있다.
| 필드 | 뜻 |
|---|---|
c | 현재가 |
d | 전일 대비 변화액 |
dp | 전일 대비 변화율(%) |
h / l / o | 오늘 고가 / 저가 / 시가 |
pc | 전일 종가 |
t | 이 데이터의 기준 시각 |
실제로 확인한 결과
=== 가격 ===
{ c: 336.91, d: 3.89, dp: 1.1681, h: 339.57, l: 334.02, o: 334.54, pc: 333.02, t: 1785182400 }
=== 뉴스 ===
최근 7일간 뉴스 248개
가장 최신 뉴스: SNDK, NVDA, SKHY, ASML Stocks Extend Slide Overnight Amid China's AI Challenge, Tech Rotation
뉴스가 248개나 잡히는 건 회사 관련 전체 뉴스라 범위가 넓어서다. 실제 AI 판단엔 최신 몇 개만 추려서 썼다 (아래 3단계).
3단계 — AI 판단 받기 (구조화된 출력)
가격·뉴스 데이터를 Claude API에 넘겨서 “매수/매도/보유 + 이유”를 받아봤다.
SDK
어떤 서비스를 코드에서 쉽게 쓰게 도와주는, 미리 만들어진 도구 모음. @anthropic-ai/sdk를 설치하면 Claude API를 직접 통신 규약(HTTP 요청 형식 등)을 안 짜고도 짧은 코드로 부를 수 있다.
구조화된 출력 (structured output)
AI에게 그냥 “판단해줘”라고만 하면 답이 매번 조금씩 다른 형태로 올 수 있다. **“이 모양의 JSON으로만 답해줘”**라고 강제하는 기능이 구조화된 출력이다. 이걸 쓰면 { 판단: "매수", 이유: "..." }처럼 항상 똑같은 모양으로 받을 수 있어서, 코드가 그 값을 안정적으로 꺼내 쓸 수 있다.
Zod 스키마
“구조화된 출력”에 정확히 어떤 모양을 원하는지 알려주는 코드 도구. 예:
const DecisionSchema = z.object({
판단: z.enum(['매수', '매도', '보유']),
이유: z.string(),
});
“판단은 매수/매도/보유 중 하나여야 하고, 이유는 글자여야 한다”는 규칙을 이렇게 코드로 적어두면, AI가 이 모양을 지켜서 답하게 된다.
막힘 → 해결: zod 버전 문제
처음 실행했을 때 Cannot read properties of undefined (reading 'def')라는 에러가 났다. 원인은 설치된 zod 라이브러리가 v3에서 v4로 넘어가는 과도기 버전이라, import { z } from 'zod'로 가져오면 옛날(v3) 방식이 되는데, 구조화된 출력 기능은 새(v4) 방식을 기대해서 생긴 충돌이었다. import { z } from 'zod/v4'로 한 줄 고치니 바로 해결됐다.
실제로 확인한 AI 판단 결과
판단: 보유
이유: AAPL이 52주 신고가를 경신하며 상승세를 보이고 있으나, AI 경쟁력에 대한 의구심과 기술주 전반의
조정 압력이 존재해 추가 매수보다는 기존 포지션을 유지하며 추이를 지켜보는 것이 적절해 보입니다.
재사용 자산 — 코드
scripts/fetch-price-news.js— 가격·뉴스만 가져오는 코드 (다른 종목 쓰려면 맨 위symbol값만 변경)scripts/get-decision.js— 그 데이터로 AI 판단까지 받는 코드 (구조화된 출력 예시로 그대로 재사용 가능)
Day 3 — 명령어 한 줄도 안 치고 내 사이트를 실제로 배포했다
한 줄 요약: 터미널 명령어를 직접 친 게 하나도 없다. 그냥 “대신 해줘”라고만 했는데 내 사이트가 진짜 인터넷 주소를 갖게 됐다.
이런 분께 도움돼요: 나처럼 코딩을 전혀 모르는데, 만든 걸 GitHub에 올리고 Vercel로 배포까지 해보고 싶은 분.
Before
사이트는 로컬(내 컴퓨터)에서만 보였다. GitHub도, Vercel도 계정만 있고 뭘 어떻게 연결해야 하는지 몰랐다. “로그인/인증이 필요하면 알려줘”라고 시작했다가, 결국은 “나는 명령어를 직접 못 쳐, 네가 대신 실행해줘”로 방향을 바꿨다.
어떻게 했나
1. GitHub에 올리기
이렇게 부탁했다.
지금 이 폴더(내 학습허브 사이트)를 통째로 GitHub에 올려줘.
Git으로 해줘. 나는 코딩을 몰라서 명령어를 직접 못 쳐, 네가 대신 실행해줘.
- GitHub에 새 저장소를 하나 만들어서, 이 폴더 내용을 전부 올려줘.
- 처음이라 GitHub 로그인/인증이 필요하면, 뭘 어디서 해야 하는지 알려줘.
- 다 올라가면 GitHub에서 내 사이트 주소(저장소 링크)를 알려줘.
GitHub CLI(터미널에서 GitHub를 다루는 도구)라는 걸 설치하고, 브라우저에 뜬 8자리 코드를 입력해서 내 GitHub 계정과 터미널을 연결했다. 그다음 자동으로 저장소가 만들어지고 코드가 올라갔다.
2. Vercel로 배포하기
똑같은 방식으로 부탁했다.
방금 GitHub에 올린 이 사이트를 Vercel로 배포해줘. Vercel CLI로 해줘.
나는 코딩을 몰라서 명령어를 직접 못 쳐, 네가 대신 실행해줘.
- Vercel CLI가 없으면 "깔까요?"라고 되묻지 말고 바로 설치해줘.
- 처음이라 Vercel 로그인이 필요하면, 아까 만든 GitHub 계정으로 로그인하게 안내해줘.
- 방금 올린 그 GitHub 저장소를 배포하는 거야.
- 배포가 끝나면 내 사이트 URL(주소)을 알려줘.
막힘 → 해결
한 번 막혔다. Vercel이 내 GitHub 저장소를 연결하려는데 “저장소에 접근할 수 없다”는 오류가 났다. 알고 보니 Vercel이 GitHub 저장소에 접근하려면 Vercel용 GitHub 앱을 따로 설치·승인해줘야 했다 (계정 로그인 연결이랑, 저장소 접근 권한은 별개였다). 이 부분은 권한을 새로 주는 거라 화면을 보여주면서 “이거 눌러도 될까요?”라고 물어봐 줬고, 승인하고 나니 바로 풀렸다.
After
https://kevin-one-murex.vercel.app — 진짜 인터넷 주소가 생겼다. 이제 GitHub에 새로 커밋을 올리면 Vercel이 자동으로 다시 배포해준다.
배운 점 / 재사용 자산
- “나는 명령어를 직접 못 쳐, 네가 대신 실행해줘” 이 한 문장이 핵심이었다. AI한테 이걸 명확히 말하면, 설치부터 로그인·배포까지 알아서 진행하고, 클릭이 필요한 화면만 콕 집어서 알려준다.
- “로그인(계정 연결)“과 “저장소 접근 권한(앱 설치)“은 다른 문제라는 걸 배웠다. 로그인만 되면 다 될 줄 알았는데, 권한을 따로 승인해야 하는 경우가 있었다.
- 위 프롬프트 두 개는 그대로 복사해서 다른 프로젝트를 배포할 때도 재사용할 수 있다.
Day 4 — 두 번째 프로젝트를 하루 만에 기획부터 랜딩까지 끝냈다
한 줄 요약: 아이디어만 던졌는데, AI가 후보를 추천해주고 → 인터뷰로 로드맵을 짜주고 → 실제 API까지 조사해줘서, 하루 만에 두 번째 프로젝트가 “시작할 준비 완료” 상태가 됐다.
이런 분께 도움돼요: 새 학습 주제가 막연하게 떠올랐는데, 이걸 어떻게 구체적인 4주 계획으로 바꿔야 할지 모르겠는 분.
Before
원래 진행하던 유튜브 채널 프로젝트가 있었는데, 문득 “AI로 주식 트레이딩 하는 사이트나 에이전트를 만들어보고 싶다”는 생각이 들었다. 근데 딱 그 생각뿐이었지, 뭘 어디서부터 시작해야 할지는 몰랐다.
어떻게 했나
1. 막연한 아이디어를 구체적인 후보로
이렇게 물어봤다.
ai를 통해서 주식 트레이딩 하는 사이트 혹은 에이전트는 만들고싶어
주식 관련된것으로 만들어볼만한거 추천좀 해줘봐
AI가 “실제 돈 거는 자동매매 봇”부터 “뉴스 요약봇”까지 몇 가지 후보를 난이도·리스크와 함께 보여줬다. 그중 실제 돈 없이 해볼 수 있는 모의(가상) 매매 에이전트 + 성과를 보여주는 대시보드 사이트를 골랐다.
2. 인터뷰로 로드맵 만들기
“내 4주 로드맵 만들어줘” 하니, AI가 한 번에 하나씩 물어봤다 — 뭘 만들고 싶은지, 왜 하고 싶은지, 누구한테 필요한지, 4주 뒤 결과물은 뭔지, 지금 나는 어떤지, 4주 뒤 어떤 사람이 되고 싶은지. 이 답들을 모아서 4주짜리 로드맵 문서가 만들어졌다.
3. 범위를 현실적으로 줄이기
중간에 “이거 주식에 있는 모든 종목 정보를 다 긁어올 수 있는 거야?”라고 물어봤는데, 기술적으로는 가능하지만 4주짜리 첫 프로젝트로는 너무 크다는 답을 들었다. 그래서 종목 5~15개만 우선 다루는 걸로 범위를 줄였고, 실제로 업종·변동성을 골고루 섞은 10개(AAPL·MSFT·NVDA·TSLA·AMZN·GOOGL·META·JPM·XOM·KO)를 추천받아 그대로 확정했다.
4. 실제로 쓸 API 조사
“조사해줘”라고 하니, 여러 주식 데이터 API를 비교해서 Finnhub를 추천받았다 — 가격·뉴스를 하나로 무료로 해결할 수 있어서였다.
막힘 → 해결
Finnhub 무료 플랜엔 과거 몇 년치 시세(차트) 데이터가 빠져있다는 걸 알게 됐다. 처음엔 “이거 쓸 수 있는 거 맞나” 싶었는데, 생각해보니 이 프로젝트는 어차피 “매일 가상으로 매매 판단”을 내리는 거라 과거 데이터를 통째로 가져올 필요가 없었다 — 매일 그날 가격을 하나씩 직접 기록해서 내 데이터를 쌓아가면 되는 구조라 오히려 딱 맞았다.
After
하루 만에 이만큼이 갖춰졌다.
- 4주 로드맵 문서
- 프로젝트 소개 페이지
- 다룰 종목 10개 확정
- 쓸 API(Finnhub) 확정
- 랜딩페이지(홈 화면 소개글)까지 이 프로젝트 내용으로 교체
이제 API 키 발급받는 것부터 시작하면 된다.
배운 점 / 재사용 자산
- 막연한 아이디어 → 후보 추천 → 인터뷰로 로드맵 → 범위 좁히기 → 도구 조사 이 순서가 새 프로젝트를 시작할 때 그대로 재사용할 수 있는 흐름이었다.
- “이거 다 가능한 거야?”처럼 궁금한 걸 그냥 물어보는 게, 프로젝트 범위를 현실적으로 잡는 데 도움이 됐다.
- 무료 API라도 기능별로 무료/유료가 갈릴 수 있다는 걸 미리 확인하고 시작하는 게 중요하다는 걸 배웠다.
Day 5 — 로드맵을 "진짜 만들 수 있는" 설계도(PRD)로 구체화했다
한 줄 요약: 로드맵엔 “뭘·왜·누구를 위해”만 있었는데, “그래서 화면엔 뭐가 보이고, AI는 뭘 근거로 판단하고, 얼마나 자주 돌아가는지”는 하나도 안 정해져 있었다. PRD 인터뷰로 그 빈칸을 다 채웠다.
이런 분께 도움돼요: 로드맵은 만들었는데 “그래서 이제 뭐부터 코드로 만들지” 막막한 분.
Before
로드맵엔 “미국 주식 10개 종목으로 AI 모의매매 에이전트 + 대시보드 사이트”라고만 적혀 있었다. 근데 막상 만들려니 — 화면엔 정확히 뭐가 보여야 하는지, AI는 뭘 보고 사고팔지 판단하는지, 가상의 돈은 얼마로 시작하는지, 이런 세부적인 게 하나도 안 정해져 있었다.
어떻게 했나
“내 프로젝트 PRD 만들어줘”라고 했더니, 로드맵에 이미 있는 “뭘·왜·누구”는 다시 안 묻고, 빠져 있던 것만 골라서 하나씩 예시와 함께 물어봤다.
1. 판단 근거부터
“AI가 뭘 보고 매매 판단을 내릴까요?”라는 질문에 예시 몇 개(가격만 보기 / 뉴스만 보기 / 둘 다 종합)를 받고, 가격 + 뉴스를 함께 AI에게 주고 종합 판단하는 방식으로 정했다. “TSLA는 오늘 뉴스가 긍정적이고 가격도 올랐으니 매수” 같은 식이다. 판단마다 이유도 같이 남기기로 했다 — 대시보드에 그대로 보여줄 거라서.
2. 화면에 뭐가 보여야 하는지
한 화면에 이 세 가지가 다 있어야 한다고 정했다.
- 종목별 현재 상태 (보유중/현금, 수량·평가금액)
- 전체 수익률 그래프 (날짜별 꺾은선)
- 매매 히스토리 + 이유 (언제·뭘·왜 샀는지 팔았는지)
3. 가상 자본금·실행 주기
가상 자본금은 $10,000을 10개 종목에 균등 분배(종목당 $1,000)해서 종목별 성과를 비교하기 쉽게 했고, 매일 하루 한 번, 사람 개입 없이 자동 실행되는 걸로 정했다.
4. 만드는 방법은 AI가 조사해서 추천
“어떻게 만들까요?”라고 나한테 되묻지 않고, 지금 기준으로 제일 쉬운 조합을 조사해서 보여줬다.
| 역할 | 도구 | 왜 |
|---|---|---|
| 매일 자동 실행 | GitHub Actions 예약 실행 | 이미 쓰는 저장소에서 새 가입 없이 바로 가능, 무료 |
| 데이터 저장 | JSON 파일 1개를 계속 커밋 | DB 없이 제일 간단, “매일 기록 쌓기”랑 딱 맞음 |
| 화면 | Astro 페이지 1개 추가 | 이미 쓰는 프레임워크라 새로 배울 게 없음 |
| 배포 | Vercel(기존 연결 그대로) | Actions가 매일 커밋 → 자동 재배포 |
막힘 → 해결
“화면 구성”이나 “판단 로직” 같은 말이 처음엔 낯설었다. 근데 질문마다 “이런 식으로 할 수도 있고, 저런 식으로 할 수도 있어요, 이 중엔 이게 제일 무난해요”처럼 예시 + 추천을 같이 줘서, 뭘 골라야 할지 몰라 막히는 일 없이 하나씩 정할 수 있었다.
After
PRD 문서 하나에 이게 다 담겼다 — 판단 근거, 화면 구성, 자본금, 실행 주기, 구현 방법, 이번엔 안 하는 것(실거래·로그인 등은 제외), 그리고 바로 시작할 첫 실행 항목까지. 이제 뭐부터 코드로 만들면 되는지 명확해졌다.
배운 점 / 재사용 자산
- 로드맵 = 큰 지도, PRD = 실제로 만들 수 있는 설계도. 이 둘을 나눠서 생각하니 “무작정 코딩 시작” 대신 순서 있게 갈 수 있었다.
- 낯선 개념이 나올 땐 “예시 2~3개 + 추천 하나”를 요청하면 막힘 없이 결정할 수 있다.
- “어떻게 만들까요?”는 스스로 답하기 어려운 질문이니, AI한테 “최신 기준으로 제일 쉬운 방법 조사해서 추천해줘”라고 넘기는 게 훨씬 빨랐다.
Day 6 — PRD를 쪼개서, 진짜로 AI 판단 하나를 받아냈다
한 줄 요약: 어제 만든 PRD를 “하루에 하나씩 될 만한 크기”로 쪼갠 다음, 그중 두 조각(Finnhub 데이터 가져오기, Claude API로 AI 판단 받기)을 오늘 직접 만들고 실행해서, 프로젝트가 처음으로 “진짜로 작동하는” 상태가 됐다.
이런 분께 도움돼요: PRD·계획은 세웠는데 “그래서 코드는 어디서부터 짜지” 막막한 분, 또는 Claude API로 구조화된 판단을 받고 싶은 분.
Before
PRD엔 “가격+뉴스를 AI에게 줘서 매수/매도/보유 판단을 받는다”고만 적혀 있었지, 실제로 그걸 코드 몇 줄로 어떻게 짜는지는 하나도 안 정해져 있었다. 게다가 Claude API를 스크립트에서 부르는 건 처음이라, 어떤 모델을 써야 할지도 몰랐다.
어떻게 했나
1. PRD를 하루 단위로 쪼개기
이렇게 물어봤다.
어제 만든 PRD를 바탕으로 세부계획을 세우고 싶어.
단, 계획을 짜기 전에 먼저 조사부터 해줘 —
이걸 지금 만든다면 요즘 제일 쉽고 많이 쓰는 방법이 뭔지 최신 기준으로 찾아봐.
나는 코딩을 잘 몰라. 4주 안에 진짜 만들 수 있게, 작은 단계로 잘게 쪼개서
순서대로 정리해줘. 각 단계는 "하루 안에 될 만한 크기"로.
AI가 모델 선택(비용 대비 성능), Node.js에서 Claude API를 부르는 방법, “판단+이유”를 안정적인 JSON으로 받는 방법까지 조사한 뒤, 1~9단계로 쪼갠 세부계획을 만들어줬다.
2. 데이터 하나 가져오기 (2단계)
Finnhub API로 AAPL의 오늘 가격과 최신 뉴스를 가져오는 짧은 스크립트를 만들어 바로 실행해봤다. 콘솔에 진짜 숫자(현재가 336.91, 전일 대비 +1.17%)와 뉴스 제목이 찍히는 걸 보고서야 “아, 이게 실제로 되는구나” 싶었다.
3. AI 판단 연결하기 (3단계)
여기서부터가 이번 사례의 핵심이다. @anthropic-ai/sdk를 설치하고, 가격·뉴스를 프롬프트로 만들어서 Claude에게 넘긴 뒤, “구조화된 출력”이라는 기능으로 판단을 강제된 JSON 형태로 받게 만들었다.
const DecisionSchema = z.object({
판단: z.enum(['매수', '매도', '보유']),
이유: z.string(),
});
const response = await client.messages.parse({
model: 'claude-sonnet-5',
messages: [{ role: 'user', content: 프롬프트 }],
output_config: { format: zodOutputFormat(DecisionSchema) },
});
막힘 → 해결
코드를 처음 돌렸을 때 Cannot read properties of undefined (reading 'def')라는 에러가 났다. 원인은 설치된 zod 라이브러리가 v3→v4 과도기 버전이라, import { z } from 'zod'로 쓰면 옛날 방식이 되고, 구조화된 출력은 새 방식을 기대해서 생긴 충돌이었다. 'zod/v4'에서 가져오도록 한 줄 고치니 바로 해결됐다.
After
- PRD가 1~9단계 세부계획으로 쪼개졌다
- Finnhub에서 실제 가격·뉴스를 가져오는 스크립트 완성
- Claude API로 “매수/매도/보유 + 이유”를 안정적인 JSON으로 받는 스크립트 완성 — 실제로 AAPL에 대해 “보유” 판단과 그 이유를 받아냄
- 새로 나온 개념들은 개념페이지로 정리해둠
배운 점 / 재사용 자산
- “조사 먼저, 계획은 그 다음” — 계획부터 짜지 말고 “지금 제일 쉬운 방법이 뭔지” 먼저 물어보면, 계획 자체가 훨씬 실전적으로 나온다.
- **구조화된 출력(structured output)**은 AI 판단을 코드에 안정적으로 연결할 때 재사용할 수 있는 패턴 — 이번에 쓴 Zod 스키마 방식은 앞으로 다른 판단(예: 종목별 반복 처리)에도 그대로 가져다 쓸 수 있다.
- zod 버전 충돌 해결법(
zod/v4에서 import)도 기억해둘 것 — SDK 버전이 올라가도 같은 문제가 또 나올 수 있다.
1주차 회고 — 새로 배운 것들로 돌아보는 한 주
한 줄 요약: 1주일 전엔 Git도 API도 몰랐는데, 낯선 용어를 하나씩 물어보고 배우다 보니 이번 주 끝엔 실제 주가·뉴스 데이터를 가져와 AI한테 매매 판단까지 받아내고 있었다.
이런 분께 도움돼요: 코딩을 전혀 몰라서 “이 낯선 말이 대체 뭐지” 하나하나 막히는 분, AI랑 같이 프로젝트를 처음 시작하려는 분.
Before
1주일 전엔 Git이 뭔지, API가 뭔지도 몰랐다. AI한테 뭘 어떻게 시켜야 하는지도 감이 없었다.
이번 주 배운 것들 (시간순)
1. AI와 “같이 일하는 법” 자체 (Day 1)
제일 먼저 배운 건 코드가 아니라 AI랑 어떻게 대화해야 하는지였다. SOUL·USER·AGENTS·CLAUDE.md 4개 파일로 나만의 학습메이트(미소)를 만들고, “바로 만들지 말고 먼저 하나씩 물어봐달라”는 인터뷰 방식을 배웠다. 이 방식은 이번 주 내내 그대로 써먹었다 — 로드맵 만들 때도, PRD 만들 때도, 세부계획 세울 때도 항상 “먼저 조사부터 해줘” 라고 시켰다.
어제 만든 PRD를 바탕으로 세부계획을 세우고 싶어.
단, 계획을 짜기 전에 먼저 조사부터 해줘 —
이걸 지금 만든다면 요즘 제일 쉽고 많이 쓰는 방법이 뭔지 최신 기준으로 찾아봐.
나중엔 “PRD 만드는 법” 자체를 스킬로 만들어서, 다음 프로젝트에도 그대로 재사용할 수 있게 해뒀다.
2. 내 사이트를 실제로 인터넷에 올리는 법 (Day 3)
명령어를 한 줄도 안 치고 GitHub·Vercel 계정을 연결해서 사이트를 실제로 배포했다. 배포된 사이트는 멀쩡한데 로컬 미리보기에서만 스타일이 하나도 안 나오는 버그를 만났는데, 원인은 폴더의 진짜 이름이 KEVIN(대문자)인데 계속 kevin(소문자)으로 명령을 실행하고 있었던 것 — Windows가 대소문자를 구분 안 하는 것처럼 보여도, 빌드 도구 내부에선 다르게 취급할 수 있다는 걸 배웠다.
3. 자동화 — 워크플로, cron, 훅 (Day 5)
매일 정해진 시간에 사람 없이 자동으로 돌아가는 GitHub Actions 워크플로를 처음 만들어봤다. 그리고 “글 저장할 때마다 사이트가 안 깨지는지 자동으로 확인하고 싶다”는 반복 작업을 자동화하고 싶어서, 스킬·CLAUDE.md 규칙·서브에이전트·훅 네 가지의 차이를 하나씩 비교해봤다 — “내가 불러야 하는 것”과 “안 불러도 자동으로 되는 것”의 차이를 이번에 처음 제대로 이해했고, 결국 훅으로 만들었다. 일부러 깨진 글을 저장해서 실제로 잡아내는 것까지 확인했다.
4. 진짜 데이터를 가져와서 AI에게 판단시키기 (Day 6)
이번 주의 하이라이트. Finnhub API로 실제 주가·뉴스를 가져오고, 그걸 Claude API에 넘겨서 “매수/매도/보유 + 이유”를 **구조화된 출력(JSON)**으로 안정적으로 받는 법을 배웠다.
const DecisionSchema = z.object({
판단: z.enum(['매수', '매도', '보유']),
이유: z.string(),
});
실제로 AAPL에 대해 이런 판단을 받아냈다:
판단: 보유
이유: AAPL이 52주 신고가를 경신하며 상승세를 보이고 있으나, AI 경쟁력에 대한 의구심과 기술주 전반의
조정 압력이 존재해 추가 매수보다는 기존 포지션을 유지하며 추이를 지켜보는 것이 적절해 보입니다.
막힘 → 해결 모음
- Node.js 설치 PATH 문제(Day 1) — winget이 구버전이라 자동 설치가 안 돼서 수동 설치로 해결.
- 대소문자 버그(Day 3) — 폴더 이름 대소문자 불일치. 로컬 전용 설정에 경로를 명시해서 해결.
- zod 버전 충돌(Day 6) —
Cannot read properties of undefined (reading 'def')에러.zod/v4에서 가져오도록 한 줄 고쳐서 해결. - 마켓플레이스·LLM 위키 플러그인 다루기 — 처음 써보는 도구라 조금 헤맸지만, 클로드에게 물어보며 해결했다.
After
1주일 전엔 Git도 API도 몰랐는데, 지금은 실제 주식 API를 긁어와서 AI한테 매매 판단까지 받는 걸 직접 만들 수 있게 됐다. 이번 주는 “결과물”보다 “낯선 용어를 하나씩 이해하는 시간”에 훨씬 많이 썼는데, 그 시간이 쌓여서 마지막 날엔 진짜로 작동하는 것 하나가 만들어졌다.
배운 점 / 재사용 자산
- 인터뷰 프롬프트 템플릿: “바로 만들지 말고 먼저 조사·질문부터 해줘” — 새 프로젝트를 시작할 때마다 재사용.
- 자동화 선택 기준: “내가 불러야 하나, 안 불러도 되나”로 스킬/규칙/서브에이전트/훅을 구분하는 법.
- 구조화된 출력 패턴: Zod 스키마로 AI 판단을 안정적인 JSON으로 받는 방식 — 다음 판단(종목별 반복)에도 그대로 재사용.
- 다음 주(2주차) 계획: 주식 AI 모의매매 사이트 만들기를 본격적으로 진행한다 — 10종목 전체로 확장하고, 자동 실행에 실제 로직을 연결하고, 대시보드를 만든다.
2주차
이틀 만에 자리표시자였던 코드가 매일 자동으로 도는 공개 사이트가 됐다
한 줄 요약: 1주차 끝엔 “AAPL 1종목, AI 판단 한 번 성공”이 전부였는데, 이틀(2주차 1~2일차) 만에 10종목 전체가 매일 밤 자동으로 판단·기록되고, 그 결과를 그래프·히스토리로 보여주는 공개 사이트까지 완성했다.
이런 분께 도움돼요: 계획은 잘게 쪼갰는데 “그래서 하루에 얼마나 진도가 나가야 정상인지” 감이 안 잡히는 분, GitHub Actions 자동화를 처음 실전에 연결해보는 분, 차트 라이브러리 없이 그래프를 그려야 하는 분.
Before
세부계획엔 9단계가 있었고, 1주차 끝엔 1~3단계(API 키, 데이터 하나, AI 판단 하나)만 끝난 상태였다. scripts/trade.js는 “자동 실행 확인”이라는 문구만 매일 찍는 자리표시자였고, 대시보드 페이지는 아예 없었다.
어떻게 했나
1일차 — 자리표시자를 진짜 로직으로 (4단계)
만들기 전에 먼저 오픈소스로 이미 있는 게 있는지 조사부터 했다. TradingAgents·AI Hedge Fund 같은 멀티에이전트 프레임워크가 나왔지만, PRD에서 이미 “간단하게, 백테스트 없이”로 범위를 좁혀둔 것과 안 맞아서 직접 만들기로 판단했다. 큰 도구를 그냥 가져다 쓰는 게 항상 정답은 아니라는 걸 배운 지점이다.
그다음 4단계를 작은 단계 5개로 쪼갰다 — 공용 함수 → 10종목 반복 → 자산 계산 → JSON 저장 → 로컬 테스트. 한 단계 끝날 때마다 바로 실행해서 확인하고 다음으로 넘어갔다.
// 판단 결과를 종목의 현금·보유수량에 반영 (종목당 독립된 $1,000 예산)
function 자산_반영(portfolioEntry, 판단, 현재가) {
if (판단 === '매수' && portfolioEntry.상태 === '현금') {
const 수량 = Math.floor(portfolioEntry.현금 / 현재가);
if (수량 > 0) {
portfolioEntry.현금 -= 수량 * 현재가;
portfolioEntry.보유수량 = 수량;
portfolioEntry.상태 = '보유';
}
} else if (판단 === '매도' && portfolioEntry.상태 === '보유') {
portfolioEntry.현금 += portfolioEntry.보유수량 * 현재가;
portfolioEntry.보유수량 = 0;
portfolioEntry.상태 = '현금';
}
}
2일차 — 자동화 실전 연결 (5단계), 그리고 첫 실패
워크플로에 GitHub Secrets를 연결하고 수동 실행 버튼을 눌렀는데, 바로 실패했다.
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@anthropic-ai/sdk'
로그를 읽어보니 Secrets는 정상적으로 잘 들어갔는데(FINNHUB_API_KEY: ***로 잘 나옴), 워크플로에 npm install 하는 단계 자체가 아예 빠져 있었다. GitHub Actions 서버는 매번 깨끗한 상태로 시작해서 node_modules가 없다는 걸 놓쳤던 것. 한 줄 추가하고 다시 실행하니 성공했다.
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci # ← 이 한 줄이 빠져서 실패했었다
- run: node scripts/trade.js
env:
FINNHUB_API_KEY: ${{ secrets.FINNHUB_API_KEY }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
대시보드 3종 (6~8단계)
PRD에서 정한 화면 구성 3가지를 각각 작은 단계로 쪼개서 만들었다.
- 종목별 상태 표 — 10종목의 현금/보유 상태를 표로
- 수익률 그래프 — 라이브러리를 새로 설치하지 않고, SVG를 직접 계산해서 꺾은선을 그렸다. 점 하나짜리 선 하나 그리자고 차트 라이브러리를 설치하는 건 오히려 과했다.
const x = (i) => PAD.left + (i / (series.length - 1)) * (W - PAD.left - PAD.right);
const y = (v) => H - PAD.bottom - ((v - domainMin) / (domainMax - domainMin)) * (H - PAD.top - PAD.bottom);
- 매매 히스토리 — “언제·어떤 종목·왜”를 리스트로, 매수는 초록·매도는 빨강 배지로 구분
통합 테스트 (9단계) — 그리고 또 한 번 막힘
배포된 사이트를 직접 열어 확인하던 중, 로컬 커밋을 푸시하려는데 거부당했다. 원인은 그사이 GitHub Actions 야간 자동 실행이 원격에 새 커밋을 이미 만들어둔 것 — 내가 로컬에서 작업하는 동안 자동화가 조용히 지 할 일을 하고 있었던 거다. git fetch + merge로 충돌 없이 합쳐졌다.
After
data/trades.json이 매일 밤 실제 10종목 AI 판단으로 자동 갱신됨/dashboard에서 상태 표·수익률 그래프·매매 히스토리를 실시간으로 볼 수 있음- https://kevin-one-murex.vercel.app/dashboard — 로그인 없이 누구나 바로 볼 수 있는 공개 주소
- 로드맵 2주차 목표(“작동하는 매매 판단 로직 + 대시보드 초안”)가 완성됨
배운 점 / 재사용 자산
- 작은 단계마다 바로 실행해서 확인 — 5단계씩 쪼개고 매번 실행해보니, 문제가 생겨도 어디서 생겼는지 바로 알 수 있었다.
- 자동화 로그는 에러 메시지를 그대로 읽으면 원인이 나온다 —
npm ci빠진 것도 로그 한 줄로 바로 잡았다. - 작업 중 원격이 먼저 바뀌어 있을 수 있다 — 자동화가 돌고 있는 프로젝트라면, 푸시 전에 항상
git fetch로 먼저 확인하는 습관이 필요하다. - SVG 직접 그리기 패턴: 점 개수가 적고 단순한 꺾은선이면, 차트 라이브러리 없이 좌표 계산 몇 줄로 충분하다. 새 의존성을 늘리기 전에 “정말 라이브러리가 필요한가”부터 물어볼 것.
"만약 계산기" — 방문자가 직접 골라보는 AI 매매 시뮬레이터 만들기
한 줄 요약: “AI 판단 vs Buy & Hold” 비교 그래프를 다 만들고 나니, 원래 원했던 건 방문자가 직접 시작 날짜·금액을 골라보는 것이었다는 걸 알아채고, 로그인·서버 없이 브라우저에서 바로 계산되는 “만약 계산기”로 다시 만들었다.
이런 분께 도움돼요: 다 만들고 나서 “어, 이게 아닌데” 싶은 순간을 겪어본 분, 계정·로그인 없이 방문자 인터랙션을 넣고 싶은 분, Astro 같은 정적 사이트에서 클라이언트 사이드 계산을 어떻게 넣는지 궁금한 분.
Before
2주차 목표(작동하는 매매 로직 + 대시보드)를 다 채운 뒤, 대시보드 그래프에 “AI가 실제로 판단한 포트폴리오” vs “그냥 처음부터 계속 들고만 있었다면(Buy & Hold)“을 겹쳐 보여주는 선을 하나 추가했다. 여기까지는 고정된 그래프였다 — 방문자가 뭘 고르거나 입력할 수는 없고, 그냥 보여지는 화면이었다.
어떻게 했나
”어, 이게 아니었네”를 알아챈 순간
그래프를 다 만들고 나서, 이런 설명을 받았다.
“방문자가 ‘시작 날짜 + 금액’만 골라보면, AI가 그동안 실제로 내린 판단 기록을 가지고 ‘그때 넣었으면 지금 얼마가 됐을지’를 계산해서 보여주는 거예요. 계정·로그인 없이, 지금 있는 데이터만으로 만들 수 있어요.”
이미 만든 고정 그래프와는 다른, 방문자가 직접 조작하는 인터랙티브 기능이었다. 여기서 중요했던 건 이미 만든 걸 버리지 않고 “이건 방금 만든 것과 다르다”고 먼저 짚은 다음, 범위를 다시 확인한 것이다. 범위가 넓었다(전체 포트폴리오에 나눠 넣기 vs 종목 하나에만 넣기) — 애매하면 짐작해서 밀어붙이지 않고, 선택지 두 개를 만들어 되물었다.
Q. 방문자가 금액을 넣으면, 그 돈이 어떻게 적용되어야 할까요?
- 종목 하나를 골라서 그 종목에만
- 10종목에 균등분배(포트폴리오 전체)
“종목 하나에만”으로 정해지고 나서야 구현을 시작했다.
막힘 — 가격 히스토리 자체가 없었다
만들려고 보니 지금까지 종목별 “그날 가격”이 아예 저장되고 있지 않았다. 매매 판단(매수/매도/보유)과 이유만 기록에 남기고, 그날 가격은 계산에만 쓰고 버리고 있었던 것. 과거로 거슬러 계산하는 건 불가능했고, 오늘부터 새로 가격을 기록에 남기기 시작하는 걸로 범위를 좁혔다.
// scripts/trade.js — 기록에 가격을 함께 남기도록 한 줄 추가
data.기록.push({
날짜: 오늘,
종목: symbol,
판단,
이유,
가격: quote.c, // ← 이 한 줄이 "만약 계산기"의 재료가 된다
});
계산기 구현 — 서버 없이, 브라우저에서
종목별로 “날짜·판단·가격”만 뽑은 걸 빌드 시점에 페이지에 JSON으로 심어두고, 방문자가 종목·시작일·금액을 고르면 그 이후 기록을 순서대로 재생해서 최종 가치를 계산한다.
// 매수/매도 판단을 현금·보유수량에 반영하는 규칙 (src/lib/trade-rule.js)
export function applyDecision(state, 판단, 가격) {
if (판단 === '매수' && state.보유수량 === 0) {
const 수량 = Math.floor(state.현금 / 가격);
if (수량 > 0) {
state.현금 -= 수량 * 가격;
state.보유수량 = 수량;
}
} else if (판단 === '매도' && state.보유수량 > 0) {
state.현금 += state.보유수량 * 가격;
state.보유수량 = 0;
}
}
이 함수를 종목의 기록 위에서 날짜순으로 돌리기만 하면 끝이다. 서버 호출 없이 로그인도 필요 없다 — 이미 페이지에 심어둔 데이터로 브라우저가 계산한다.
검증 — 실제 API를 안 쓰고도 로직 확인하기
data/trades.json에 테스트용 기록(8/5 AAPL $200에 매수 → 8/6 $220으로 평가)을 잠깐 추가해서 빌드해보니, “$1,000 → $1,100 (+10.0%)“로 정확히 계산됐다. 확인 끝나고 git checkout으로 테스트 데이터는 바로 되돌렸다 — 데이터가 git에 있어서 안전하게 되돌릴 수 있었다.
그다음 GitHub Actions를 수동으로 한 번 실행해(workflow_dispatch), 오늘 밤을 기다리지 않고 바로 10종목 가격이 실제로 기록되기 시작하는 걸 확인했고, 배포된 사이트를 직접 열어 계산기가 실제로 작동하는 것까지 확인했다.
After
- 대시보드에 방문자가 직접 조작하는 “만약 계산기” 섹션이 생겼다 — 종목·날짜·금액을 고르면 즉석에서 결과가 나온다.
- 오늘부터 10종목 전부 가격이 쌓이기 시작했다 (과거는 소급 불가, 오늘이 기준일).
- 나중에
/simplify로 점검해보니, 이 계산기의 매수/매도 재생 로직이scripts/trade.js의 진짜 매매 로직과 같은 규칙을 따로 타이핑하고 있던 걸 발견해서, 공용 규칙 파일(src/lib/trade-rule.js)로 뽑아 정리했다.
배운 점 / 재사용 자산
- 다 만든 뒤에도 “이게 맞나?”를 한 번 더 짚기 — 이미 만든 걸 버리는 게 아니라, “방금 만든 것과 다르다”를 먼저 인정하고 범위를 다시 물어보면 된다.
- 범위가 애매하면 선택지로 되묻기 — “어떻게 적용될까요?”를 열린 질문으로 던지지 않고, 구체적인 선택지 2~3개를 만들어 고르게 하면 훨씬 빨리 정해진다.
- 정적 사이트에서도 인터랙티브 기능이 가능하다 — 서버 없이, 빌드 시점에 필요한 데이터를 JSON으로 페이지에 심어두고 브라우저에서 계산하면 로그인·API 없이도 방문자 맞춤 기능을 만들 수 있다.
- 실제 API 키를 안 쓰고도 로직을 검증할 수 있다 — 데이터 파일에 가짜 기록을 잠깐 넣고 빌드해서 확인한 뒤
git checkout으로 되돌리면, 비용 없이 안전하게 테스트할 수 있다.
2주 만에, 혼자 도는 AI 트레이딩 사이트를 실전 배포까지
한 줄 요약: 1주차 끝엔 “종목 1개, AI 판단 1번 성공”이 전부였다. 2주차가 끝난 지금은 10종목이 매일 밤 사람 없이 자동으로 판단·기록되고, 방문자가 직접 시나리오를 돌려볼 수 있는 계산기까지 갖춘 사이트가 실제로 공개돼 있다.
이런 분께 도움돼요: “만들기”에서 “운영되는 상태로 유지하기”로 넘어가는 단계를 궁금해하는 분, AI에게 코드 리뷰를 맡겨본 적 없는 분, 자동화 파이프라인에서 중복 실행 같은 실전 버그를 다뤄본 적 없는 분.
Before → After
| 1주차 끝 | 2주차 끝 | |
|---|---|---|
| 매매 로직 | 1종목, 수동 1회 실행 | 10종목, 매일 자동 실행 |
| 화면 | 없음 | 상태표·수익률 그래프·매매 히스토리 |
| 방문자 기능 | 없음 | 종목·날짜·금액을 골라 시뮬레이션하는 “만약 계산기” |
| 코드 품질 | 확인 안 함 | AI 4개 관점 병렬 리뷰로 실제 중복 로직 발견·정리 |
| 안정성 | — | 중복 실행 버그를 원인까지 찾아 재발 방지 장치 추가 |
어떻게 만들었나
1. 자동화 파이프라인부터 굳혔다
10종목 전체에 매수/매도 판단 로직을 적용하고, GitHub Actions로 매일 밤 사람 개입 없이 돌게 만들었다. 첫 실전 실행은 npm ci 한 줄이 빠져서 실패했지만, 로그를 그대로 읽고 원인을 잡아 바로 해결했다.
2. 대시보드 3종 + 방문자 인터랙티브 기능
상태표·수익률 그래프(차트 라이브러리 없이 SVG 좌표를 직접 계산)·매매 히스토리까지 만든 뒤, 여기서 멈추지 않았다. “AI 판단 vs Buy & Hold” 비교 그래프를 추가하다가, 원래 원했던 건 방문자가 직접 시작 날짜·금액을 골라보는 것이었다는 걸 알아챘다. 이미 만든 걸 버리지 않고 범위를 다시 확인해서, **로그인·서버 없이 브라우저에서 바로 계산되는 “만약 계산기”**로 재설계했다.
// 종목의 실제 매매 기록을 날짜순으로 재생하기만 하면, "그때 넣었으면 지금 얼마"가 나온다
export function applyDecision(state, 판단, 가격) {
if (판단 === '매수' && state.보유수량 === 0) {
const 수량 = Math.floor(state.현금 / 가격);
if (수량 > 0) {
state.현금 -= 수량 * 가격;
state.보유수량 = 수량;
}
} else if (판단 === '매도' && state.보유수량 > 0) {
state.현금 += state.보유수량 * 가격;
state.보유수량 = 0;
}
}
3. AI에게 코드 리뷰를 맡겼다
/simplify 스킬로 재사용·단순화·효율성·구조(고도) 4가지 관점을 병렬로 돌려 코드를 점검했다. 실제로 진짜 문제 하나를 잡아냈다 — 매수/매도 규칙이 자동매매 스크립트와 대시보드 계산기, 두 군데에 따로 타이핑돼 있던 것. 공용 규칙 파일로 뽑아 정리하고, 나머지 제안(과한 방어 코드 제거 등)은 “지금 규모에선 오히려 손대는 게 더 위험하다”고 판단해 의도적으로 넘겼다 — AI 제안을 전부 받아들이는 게 아니라 골라서 적용하는 것도 이번 주 배운 판단력이다.
4. 프로덕션 버그를 증상이 아니라 원인까지 고쳤다
밤사이 자동 실행 결과를 확인하다가, 수동 실행과 예약 실행이 겹쳐서 매매 기록이 종목마다 두 번씩 쌓이고 있던 걸 발견했다. 사실 이 문제는 1주차 끝 무렵에도 한 번 나왔던 것인데, 그땐 눈에 보이는 숫자만 정리하고 진짜 원인(같은 날 중복 실행을 막는 장치가 없던 것)은 그대로 남아있었다. 이번엔 데이터를 정리하는 데서 멈추지 않고, “오늘 이미 실행됐으면 건너뛰기” 가드를 코드에 넣어서 재발 자체를 막았다.
배운 점 / 재사용 자산
- 목표를 채운 뒤에도 “이게 맞나”를 한 번 더 묻기 — 완성했다고 끝내지 않고, 원래 의도와 다시 맞춰보는 습관이 결과물의 완성도를 갈랐다.
- AI 코드 리뷰는 다각도로, 그리고 골라서 적용 — 재사용·단순화·효율성·구조 4개 관점을 병렬로 돌리면 진짜 문제와 과한 제안을 구분해서 볼 수 있다.
- 버그는 증상이 아니라 원인까지 — “정리했다”와 “다시 안 생기게 했다”는 다르다.
- 안 되면 되돌리는 것도 실력이다 — 커스텀 도메인처럼 예상보다 손이 더 가는 작업은, 화면을 보며 확인해야 안전한 시점에 억지로 밀어붙이지 않고 원래 상태로 되돌린 뒤 다음으로 넘어갔다.
지금 여기서 직접 확인 가능: kevin-one-murex.vercel.app/dashboard — 로그인 없이 누구나 바로 볼 수 있다.
2주차 회고 — "만약 계산기"로 완성한 한 주
한 줄 요약: 2주차 목표는 “작동하는 매매 로직 + 대시보드 초안”이었는데, 그걸 이틀 만에 끝내고도 멈추지 않았다. 다 만든 그래프가 원래 원했던 것과 다르다는 걸 알아채고, 방문자가 직접 종목·날짜·금액을 골라보는 “만약 계산기”까지 만들어냈다.
이런 분께 도움돼요: 목표를 다 채웠는데도 “이게 진짜 내가 원하던 거 맞나?” 다시 물어본 경험이 궁금한 분, 계정·로그인 없이 방문자가 조작하는 기능을 만들고 싶은 분.
Before
1주차 끝엔 “AAPL 1종목, AI 판단 한 번 성공”이 전부였다. 2주차 목표는 그걸 10종목 전체로 확장하고, 매일 자동으로 돌게 하고, 대시보드로 보여주는 것 — 여기까지가 로드맵에 적힌 이번 주의 할 일이었다.
이번 주 하이라이트 — “만약 계산기”
목표는 8/3~8/4 이틀 만에 끝났다. 10종목 매매 로직, GitHub Actions 자동 실행, 대시보드 3종(상태표·그래프·히스토리)까지 — 로드맵의 2주차 목표가 그대로 완성됐다.
그런데 여기서 멈추지 않았다. “AI 판단 vs Buy & Hold(그냥 계속 보유)” 비교 그래프를 추가로 만들고 나서, 이런 설명을 받았다.
“방문자가 ‘시작 날짜 + 금액’만 골라보면, AI가 그동안 실제로 내린 판단 기록을 가지고 ‘그때 넣었으면 지금 얼마가 됐을지’를 계산해서 보여주는 거예요. 계정·로그인 없이, 지금 있는 데이터만으로 만들 수 있어요.”
방금 만든 그래프와는 완전히 다른, 방문자가 직접 조작하는 기능이었다. 여기서 중요했던 건 이미 만든 걸 버리지 않고 “이건 방금 만든 것과 다르다”는 걸 먼저 인정한 것이다. 그리고 범위가 애매했던 지점(전체 포트폴리오에 나눠 넣기 vs 종목 하나에만)은 짐작으로 밀어붙이지 않고 선택지를 만들어 되물어서 정했다.
만들다 보니 지금까지 종목별 “그날 가격”이 아예 저장되고 있지 않았다는 것도 발견했다 — 과거로는 소급이 안 됐고, 그날부터 새로 가격을 기록에 남기는 걸로 범위를 좁혔다. 결과적으로 서버 없이, 빌드 시점에 페이지에 심어둔 데이터로 브라우저가 바로 계산하는 기능이 완성됐다.
// 매수/매도 판단을 현금·보유수량에 반영하는 규칙 — 이걸 종목의 기록 위에서
// 날짜순으로 돌리기만 하면, "그때 넣었으면 지금 얼마"가 계산된다
export function applyDecision(state, 판단, 가격) {
if (판단 === '매수' && state.보유수량 === 0) {
const 수량 = Math.floor(state.현금 / 가격);
if (수량 > 0) {
state.현금 -= 수량 * 가격;
state.보유수량 = 수량;
}
} else if (판단 === '매도' && state.보유수량 > 0) {
state.현금 += state.보유수량 * 가격;
state.보유수량 = 0;
}
}
막힘 → 해결
- 스펙이 도중에 바뀐 걸 알아챈 순간 — 이미 만든 그래프를 버리지 않고, 범위를 다시 확인해서 재설계했다.
- 가격 히스토리가 아예 없었던 것 — 과거 소급은 포기하고, 그 시점부터 새로 쌓기 시작했다.
- 커스텀 도메인 시도, 그리고 되돌리기 — “이 프로젝트만의 독립된 주소”를 무료로 만들어보려고 Vercel 프로젝트 이름을 바꿔봤는데, 새로 만든 주소가 로그인 화면만 뜨는 걸 발견했다. Vercel의 “대표 도메인” 지정이 한 단계 더 필요한 걸 그제서야 알았고, 화면을 보면서 확인하는 게 안전할 것 같아서 그날은 원래 상태로 깔끔하게 되돌렸다. 안 되는 걸 억지로 끝까지 밀어붙이기보다, 애매한 지점에서 되돌려두는 것도 이번 주에 배운 판단이었다.
- 중복 실행 버그, 뿌리까지 — 수동 실행과 예약 실행이 겹쳐서 매매 기록이 두 번씩 쌓이던 걸 발견했다. 예전에 한 번 “고쳤다”고 생각했던 문제였는데, 사실은 눈에 보이는 숫자만 정리했을 뿐 진짜 원인(같은 날 중복 실행을 막는 장치가 없던 것)은 그대로였다. 이번엔 데이터만 정리하지 않고, 재발 방지 가드까지 넣었다.
After
- 2주차 목표(작동하는 매매 로직 + 대시보드)를 완성했고, 그 위에 방문자가 직접 조작하는 “만약 계산기”까지 얹었다.
/simplify로 코드를 점검해서, 실제로 있던 중복(매수/매도 규칙이 두 곳에 따로 타이핑돼 있던 것)을 찾아 정리했다.- 데이터 파이프라인의 재발 방지 장치까지 넣어서, 지금은 사람 개입 없이도 매일 밤 안정적으로 도는 상태다.
배운 점 / 재사용 자산
- 다 만든 뒤에도 “이게 맞나?”를 한 번 더 짚기 — 이미 만든 걸 버리는 게 아니라, “방금 만든 것과 다르다”를 먼저 인정하고 범위를 다시 물어보면 된다.
- 범위가 애매하면 선택지로 되묻기 — 열린 질문 대신 구체적인 선택지 2~3개를 만들어 고르게 하면 훨씬 빨리 정해진다.
- “고쳤다”고 끝내지 않고 원인까지 확인하기 — 증상(중복 기록)만 지우고 넘어갔던 게 다시 터졌다. 데이터를 정리할 땐 원인(재발 방지 장치)까지 같이 봐야 한다.
- 안 되면 되돌리는 것도 판단이다 — 커스텀 도메인처럼 한 단계 더 필요한 걸 알게 됐을 때, 억지로 끝까지 밀어붙이지 않고 원래 상태로 깔끔하게 되돌린 뒤 다음으로 넘어갔다.
- 3주차 계획: 지금 만든 걸 계속 다듬을지, 새 기능을 하나 더 추가할지 아직 열어두고, 이번 주처럼 문제점을 찾으면 바로바로 고치면서 진행한다.
3주차
완성 기준 정하기부터, 반복되는 하루를 스킬로 만들기까지 — 3일
한 줄 요약: 로드맵상 3주차 목표는 사실 2주차 안에 이미 다 끝나 있었다. 그래서 3주차는 “뭘 더 해야 완성인가”부터 다시 정의해야 했는데, 완성 기준을 한 문장으로 정해 이틀 만에 다 채웠다. 그리고 3일째엔 한 발 더 나가서, 그 3일 동안 내가 매일 똑같이 반복하고 있던 작업 패턴 자체를 찾아내 자동화 방법을 정하고 스킬로 만들었다.
이런 분께 도움돼요: 마감은 다가오는데 “뭘 더 해야 끝난 건지” 감이 안 잡히는 분, 매일 똑같은 걸 반복하고 있다는 느낌은 드는데 그걸 어떻게 자동화할지 감이 안 잡히는 분, “규칙으로 적어둘지 / 스킬로 만들지 / 예약 실행으로 돌릴지” 중 뭘 골라야 할지 궁금한 분.
Before → After
| 3주차 시작 전 | 3일 뒤 | |
|---|---|---|
| 목표 | ”3주차엔 뭘 해야 하지?” 막연함 | 완성 기준 한 문장 + 우선순위 3단계 |
| 대시보드 | 종목별 상태표만 있음 | 필터/정렬 + 종목별 개별 그래프 + 매매 히스토리 한줄요약 + 최고·최저 수익률 카드 |
| 매일 하는 일 | 매번 “이 폴더에서 이어서 만들 거야, 완성 기준 보고 오늘 할 일 정해줘”를 직접 다 타이핑 | ”2번 해줘” 한마디로 상태 점검부터 오늘 할 일 제안까지 자동 진행 |
어떻게 했나
1. “완성”부터 다시 정의했다
로드맵엔 3주차 목표가 “대시보드 완성 + 배포 공개 + 자동화”라고 적혀 있었는데, 확인해보니 이건 2주차 안에 이미 다 끝나 있었다. 그래서 3주차를 “그냥 하고 싶은 거 아무거나” 식으로 보내지 않으려고, 새 기능 후보를 세 가지로 나눴다.
| 분류 | 기준 |
|---|---|
| 필수 (이것만 되면 완성) | 지금 흐름에서 자연스럽게 이어지고, 남은 시간에 확실히 끝낼 수 있는 것 |
| 있으면 좋음 | 없어도 지장 없지만, 시간 남으면 추가 |
| 이번엔 빼는 것 | 그럴듯해 보이지만 근거 없는 것, 혹은 지금 규모엔 과한 것 |
그리고 “지금 하던 게 완료되면 완성”이라는 형태로 기준을 문장 하나에 못 박았다.
종목별 개별 수익률 그래프가 대시보드에 붙어서, 필터로 고른 종목 하나의 수익률 추이를 볼 수 있게 되면 — 이번 주는 완성이다.
2. 필수부터 순서대로, 그리고 여유 시간까지 채웠다
1일차 — 종목별 필터·정렬(업종·상태로 거르고 수익률 순 정렬)을 먼저 붙이고, 이어서 완성 기준이었던 종목별 개별 수익률 그래프를 만들었다. 전체 포트폴리오 그래프를 그릴 때 썼던 SVG 좌표 계산 코드를 그대로 재사용했다. 이 조각이 끝난 순간 완성 기준을 충족했다.
2일차 — 시간이 남아서 “있으면 좋음”으로 미뤄뒀던 매매 히스토리 한줄요약 뱃지까지 만들었다. AI를 다시 부르지 않고, 이미 있는 판단 이유 문장을 첫 문장(또는 45자) 기준으로 잘라서 뱃지로 보여줬다. 반대로 “AI 판단 신뢰도 점수”는 실제로 AI가 계산해준 적이 없는 값이라 근거 없는 숫자를 만들게 되므로 이번엔 빼기로 했다.
3일차 — 완성 기준은 이미 채웠지만, 데이터가 이미 다 계산돼 있던 김에 최고·최저 수익률 종목 요약 카드를 하나 더 얹었다. 새 계산 없이, 기존 종목별 수익률에서 최댓값·최솟값만 뽑아 카드 2개로 보여주는 가벼운 기능이었다.
// 종목의 실제 판단 이력을 처음부터 재생해서 날짜별 총자산을 계산 —
// 자동매매 스크립트·만약 계산기와 같은 규칙(applyDecision)을 그대로 재사용
export function getSymbolAssetSeries(종목) {
const 기록들 = getPricedHistoryBySymbol()[종목] ?? [];
const state = { 현금: 종목당초기자본, 보유수량: 0 };
return 기록들.map((r) => {
applyDecision(state, r.판단, r.가격);
return { 날짜: r.날짜, 총자산: state.현금 + state.보유수량 * r.가격 };
});
}
3. 반복되는 하루 자체를 스킬로 만들었다
3일을 지내면서, 매일 세션을 시작할 때 거의 똑같은 문장을 그대로 반복해서 타이핑하고 있다는 걸 알아챘다 — “오늘은 O일이야, 이 폴더에서 프로젝트 이어서 만들 거야, 완성 기준이랑 지금까지 만든 거 보고 오늘 할 일 정해줘.” 그래서 이번엔 반복 그 자체를 재료로 삼아, 어떤 반복을 뭘로 자동화할지 정리했다.
| 반복 | 자동화 방법 | 왜 |
|---|---|---|
| 하루 시작 스크립트 | 스킬 | 상태 점검 → 후보 제안 → 사람이 고르는 상호작용이 필수라 사람이 있어야 굴러감. 예약 실행(cron)으로는 못 돌림 |
| 커밋·push를 각각 따로 확인받는 것 | 이미 규칙 (그대로 유지) | 의도적으로 넣어둔 확인 지점이라, 자동화로 없애면 오히려 안전장치를 잃는 셈 |
| 매일 가상 매매 기록 | 이미 예약 실행(GitHub Actions cron) | 사람 없이 무인으로 돌아도 되는 일이라 이미 맞는 방법으로 자동화돼 있었음 |
그렇게 골라낸 “하루 시작 스크립트”를 .claude/skills/오늘작업/SKILL.md라는 스킬로 만들었다. 이제 “2번 해줘” 한마디면 상태 점검 → 오늘 할 일 제안 → (코드 변경이면) 계획·승인 → 구현·검증까지 같은 순서로 진행된다.
만드는 과정에서 한 가지 더 정리했다 — 처음엔 이 규칙을 프로젝트 규칙 파일(AGENTS.md)에 문장으로 바로 적었는데, 곧 스킬 파일에도 같은 절차를 다시 적어야 한다는 걸 깨달았다. 같은 내용을 두 군데에 적어두면 나중에 하나만 고치고 다른 하나는 안 고쳐서 어긋날 수 있다. 그래서 스킬 파일을 “정답”으로 남기고, AGENTS.md는 “이 트리거 문구 → 이 스킬”이라는 연결 한 줄만 남기도록 정리했다.
배운 점 / 재사용 자산
- “완성”을 한 문장으로 못 박기 — “이것만 되면 완성이다”를 미리 정해두면, 마감이 다가올 때마다 “이거 할까 말까”를 새로 고민하지 않아도 된다.
- 근거 없는 지표는 안 만든다 — “그럴듯해 보이는 것”과 “진짜 있는 데이터”는 다르다.
- 반복을 알아채면, 뭘로 자동화할지부터 고른다 — 사람의 선택이 필요하면 스킬, 매번 잊지 말고 챙겨야 하는 거면 규칙, 무인으로 돌아도 되면 예약 실행. 이 세 갈래만 구분해도 어떤 도구를 써야 할지 헷갈리지 않는다.
- 같은 규칙을 두 곳에 적지 않기 (단일 소스 원칙) — 절차는 스킬 파일 하나에만 자세히 적고, 다른 곳(AGENTS.md)에서는 “어디로 가면 되는지”만 가리키게 하면 나중에 어긋날 일이 없다.
지금 여기서 직접 확인 가능: kevin-one-murex.vercel.app/dashboard — 로그인 없이 누구나 바로 볼 수 있다.
일부러 이상하게 써보니 나온 것 — 업종별 비교 + 엣지 케이스 점검
한 줄 요약: 업종별 평균 수익률 카드를 새로 붙인 뒤, 대시보드의 입력·선택 지점들을 일부러 이상하게 써봤다(빈 값, 중간에 취소, 엉뚱한 값). 크래시는 없었지만 진짜 문제 2개를 찾아 바로 고쳤다.
이런 분께 도움돼요: 기능을 다 만들고 나서 “이제 뭘 확인해야 하지” 감이 안 잡히는 분, 정상 입력만 테스트해보고 넘어가곤 하는 분.
오늘 추가한 것
이미 계산돼 있던 종목별 수익률을 업종으로 묶어서 평균만 내는 업종별 평균 수익률 카드를 대시보드에 추가했다. 새 계산 로직이 거의 없어서 위험이 적은 기능이었다.
일부러 이상하게 써본 순서
기능이 아니라 입력 지점을 기준으로 훑었다 — 이 사이트에서 사람이 값을 직접 넣거나 고르는 곳은 “만약 계산기”(종목·날짜·금액)와 필터·정렬 드롭다운들이다.
- 빈 값으로 넘기기 — 날짜 비우기, 금액 0/비우기
- 엉뚱한 값 넣기 — 금액에 문자열(“abc”), 음수, 극단적으로 큰 수(10^20), 날짜 칸에 진짜 날짜가 아닌 문자열, 존재하지 않는 종목 코드
- 중간에 취소하듯 바꾸기 — 정상 값 넣다가 다시 비우기, 선택지를 없는 값으로 강제로 바꾸기
찾은 것
| 시도 | 결과 |
|---|---|
| 날짜·금액 비우기/0/음수/문자열 | 전부 “종목·날짜·금액을 모두 확인해주세요” — 이미 잘 막고 있었음 |
| 날짜·종목 select에 없는 값 강제 주입 | 브라우저의 type="date"와 <select> 자체가 유효하지 않은 값을 거부하고 빈 값으로 되돌림 — 앱 코드 이전에 이미 막힘 |
| 필터 드롭다운(업종·상태)에 없는 값 | 표가 0줄 되고 “조건에 맞는 종목이 없어요” 정상 표시 |
| 극단적으로 큰 금액(10^20) | 계산은 됐지만 결과 문구에 콤마가 안 찍혀서 $100000000000000000000.00처럼 읽기 힘든 숫자가 그대로 나옴 |
| 종목별 그래프 select가 무효한 값이 되는 경우 | 화면이 아무 안내 없이 조용히 텅 빔 — 필터 표에는 있는 “빈 결과” 문구가 이 섹션엔 없었음 |
크래시나 콘솔 에러는 하나도 없었다. 대부분은 브라우저의 기본 입력 검증(type="date", <select>)과 이미 짜둔 방어 코드(빈 값·0·음수 체크)가 막고 있었다.
고친 것
1. 종목별 그래프 빈 상태 안내 추가
function showSelectedChart() {
const 선택 = symbolChartSelect.value;
const 매칭됨 = symbolCharts.some((el) => el.dataset.종목 === 선택);
symbolCharts.forEach((el) => {
el.hidden = el.dataset.종목 !== 선택;
});
symbolChartEmpty.hidden = 매칭됨; // 매칭 안 되면 안내 문구 보여줌
}
2. 만약 계산기 결과에 콤마 포맷 적용
const 최종표시 = 최종.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
resultEl.textContent = `... 지금 $${최종표시} ...`;
배운 점 / 재사용 자산
- “입력 지점” 기준으로 훑으면 빠짐없이 확인된다 — 기능 단위가 아니라 “사람이 값을 직접 넣거나 고르는 곳”을 먼저 나열하고, 그 각각에 빈 값·엉뚱한 값·취소를 대입해보면 테스트 범위를 놓치지 않는다.
- 브라우저 기본 검증도 방어선이다 —
type="date",<select>처럼 브라우저가 원래 막아주는 것과, 코드가 직접 막아야 하는 것(빈 문자열, 0, 음수, NaN)을 구분해서 보면 어디를 더 신경 써야 할지 보인다. - “안 죽는다” ≠ “잘 처리한다” — 두 문제 다 크래시는 아니었다. 하나는 그냥 읽기 불편한 숫자, 하나는 조용히 비는 화면. 에러가 안 나는 것과, 사용자가 지금 상황을 이해할 수 있는 것은 다른 기준이다.
지금 여기서 직접 확인 가능: kevin-one-murex.vercel.app/dashboard