尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
正在載入完整 README。 以下為已儲存的摘錄。
국내 상장사에 대해 한국어로 질문하면, 전자공시(DART) 숫자로 계산한 근거 차트(왼쪽)와 AI가 쓴 분석 글(오른쪽)을 함께 보여 주는 서비스입니다. • 배포 주소: https://projectsleepyheads.vercel.app (구글 로그인) • 작성자: Sung, Hyun-Joon · Lee, Yelim · ByeongJun Min • ⚠️ 비상업 수업 프로젝트입니다. 광고·유료 기능이 없고, 수익을 목적으로 운영하지 않습니다. 분석 글은 투자 권유가 아니며 AI가 쓴 글이라 틀릴 수 있습니다. "SK하이닉스 최근 실적 어때?", "직전 분기 대비 영업이익 변화와 감소한 경쟁사 비교해줘"처럼 물으면: 1. AI가 질문을 분석 요청(기업·지표·기간) 으로만 바꿉니다 — AI는 계산하지 않습니다. 2. 서버가 OpenDART 재무제표를 받아 정해진 계산식으로 지표를 계산합니다 (12월 외 결산은 달력 분기로 환산). 3. 차트·표를 그리고, AI가 그 숫자의 ID만 가리키는 방식으로 분석 글(결론 + 투자 포인트)을 씁니다 → 글의 숫자는 항상 차트와 같습니다.檢視完整 README ↗
국내 상장사에 대해 한국어로 질문하면, 전자공시(DART) 숫자로 계산한 **근거 차트(왼쪽)**와 AI가 쓴 **분석 글(오른쪽)**을 함께 보여 주는 서비스입니다.
| 첫 화면 | 결과 화면 (분석 보드 · 좌 차트 / 우 분석 글) |
|---|---|
"SK하이닉스 최근 실적 어때?", "직전 분기 대비 영업이익 변화와 감소한 경쟁사 비교해줘"처럼 물으면:
| 기능 | 내용 |
|---|---|
| 질문형 분석 | 최근 실적·추이·연간·원인·기업 비교·합계. 기간을 안 적으면 최근 4개 분기 |
| 근거 차트 | 지표 카드·막대·선·표, 제목·축·단위·범례·출처, "표로 보기"(키보드), 재무 용어 한 줄 설명, ⓘ 계산식 |
| 분석 글 | 결론 2문장 + 투자 포인트 2~4개(긍정·위험·확인할 점), 스마트폰 한 화면 분량. 매수·매도 의견·목표주가 금지 |
| 복합 질문 | 분석 계획 카드 → [분석 시작] 승인 → 진행 표시·취소 → 실행 기록. 경쟁사 자동 선택(같은 섹터 시가총액 순) |
| 뉴스 단서 | Google 뉴스 RSS 기사 제목으로 요지를 만들어 "원인"의 참고 단서로만 사용 (본문 저장 없음) |
| 분석 보드 | 기간·비교 기업 필터 → 모든 차트·표를 같은 조건으로 다시 계산(AI·질문 수 사용 없음), [설명 다시 쓰기] |
| 재무 + 주가 결합 | 시가총액·PER·PBR (금융위원회 주식시세, 기준일 종가). 보통주 코드 중복·같은 날 가격 2행이면 결합 중단 + 경고 |
| 저장·재현성 | 프로젝트·분석 저장, 데이터 버전(접수번호로 고정) → 같은 조건 재실행은 같은 숫자 |
| 안전장치 | 범위 밖·투자 권유·조작 시도 질문 정중한 거절, 질문 수 한도(하루 20개), 질문당 AI 비용 상한, 프롬프트 주입 방어 |
| 비로그인 예시 | 첫 화면 아래 SK하이닉스 예시 분석 (매일 새 정기보고서가 있을 때만 다시 만듦) |
| 영역 | 사용 |
|---|---|
| 화면·서버 | Next.js 16 (App Router, src/proxy.ts), React 19, TypeScript, Tailwind CSS, Recharts |
| DB·로그인 | Supabase (Postgres + RLS, 구글 로그인) — 프로젝트 sleepyhead 하나 |
| 배포 | Vercel (Hobby, Cron 3개) |
| AI | OpenAI Responses API + Structured Outputs — 질문 해석·뉴스 요지 gpt-6-luna, 분석 글 gpt-6-sol |
| 테스트 | Vitest(단위·정확도·DB·회귀), Playwright(화면 1280px·375px), GitHub Actions (Linux·Windows) |
| 데이터 | 출처 | 비고 |
|---|---|---|
| 기업·재무제표·공시 | 금융감독원 전자공시시스템 OpenDART | 수업 워크플로우의 CSV 업로드를 대체 |
| 주가·상장주식수 | 공공데이터포털 금융위원회_주식시세정보 (출처: 한국거래소) | 이용 조건(출처표시·상업적 이용금지·변경금지)에 따라 비상업적으로만 사용 |
| 뉴스 | Google 뉴스 RSS | 기사 제목·언론사·발행일만, 본문 저장·표시 없음. 저작권은 각 언론사 |
| 분석 글 | OpenAI | AI 작성 표시, 숫자는 서버가 채움 |
| 수업 워크플로우 | 이 프로젝트 | 증거 |
|---|---|---|
| CSV 파일 업로드·미리보기 | OpenDART 조회로 대체, 결과 화면의 "사용된 데이터"(행·열·자료형·기간) | STEP1_PASS_TEST |
| Step 1 첫 분석 | 질문 → 차트 + 분석 글, 오류 안내, AI 장애 시 실패 표시 | STEP1_PASS_TEST |
| Step 2 저장·전처리·재현성 | 프로젝트·데이터 버전·재실행, 전처리 진단, 소유자 외 404 | STEP2_PASS_TEST |
| Step 3 계획·실행·검증 | 계획 카드·승인·취소·실행 기록·재시도·상한, 경쟁사·뉴스 | STEP3_PASS_TEST |
| Step 4 분석 보드·품질 | 필터 연동, 차트 규격, 가상 12만 행 측정·처리 한도 | STEP4_PASS_TEST |
| Step 5 확장·운영 | 확장 ② 두 데이터셋 결합(재무+주가), 작업 큐, 회귀 세트, 프롬프트 주입 방어 | STEP5_PASS_TEST, 회귀 결과 |
| (추가) | 뉴스 단서, 서비스 범위 밖 질문 거절 |
구현 제외 항목 (PRD §11.2)
| 제외 | 사유 | 대신 증명 |
|---|---|---|
| CSV 업로드·빈 파일·허용 크기 초과 | 파일 업로드 없음 (OpenDART로 대체) | 데이터 없음·기간/기업 수 초과 오류 안내 |
| 결과 내보내기, 내보낸 CSV 수식 주입 처리, "내려받은 파일 회수 불가" | 다운로드 기능 없음 | — |
| 열람자/편집자 권한, 공유 해제 후 접근 차단 | 외부 공유 기능 없음 | 소유자 외 접근 차단 (서버 검사 + RLS, 남의 ID는 404) |
준비물: Node.js 24(.nvmrc), pnpm (corepack enable로 켜짐), Git
git clone [email protected]:wilstein91/project_sleepyheads.git
cd project_sleepyheads
pnpm install
키 없이 화면만 보려면 가짜 모드: .env.example을 .env.local로 복사하고 NEXT_PUBLIC_API_MOCK=1만 채운 뒤
pnpm dev
→ http://localhost:3000 (화면 맨 위에 "개발용 가짜 데이터로 동작 중입니다" 줄이 보이면 성공. 서버 API·외부 키 없이 tests/fixtures/mock/ 데이터로 동작)
실제 데이터로 돌리려면 .env.local에 아래 키를 모두 채우고 확인:
pnpm check:keys
(항목마다 ✅가 나오면 준비 끝)
| 명령 | 하는 일 |
|---|---|
pnpm lint · pnpm format:check · pnpm typecheck | 검사 (ESLint · Prettier · TypeScript) |
pnpm test | 단위·정확도·DB 테스트 |
pnpm test:e2e | 화면 테스트 (가짜 모드로 빌드, 1280px·375px) |
pnpm exec vitest run -c tests/regression/vitest.config.mts | 회귀 세트 (AI 고정 응답, 비용 0) |
.env.local·Vercel에만)| 이름 | 공개 | 용도 |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | 공개 | Supabase 주소·공개 키 |
SUPABASE_SECRET_KEY | 🔒 | 서버 전용 관리자 키 |
OPENDART_API_KEY | 🔒 | OpenDART |
DATA_GO_KR_SERVICE_KEY | 🔒 | 공공데이터포털 주식시세 |
OPENAI_API_KEY | 🔒 | OpenAI — 쉼표로 여러 개 넣으면 잔액이 떨어진 키 다음 키를 씀 |
OPENAI_MODEL | 서버 | 질문 해석·뉴스 요지 모델 (기본 gpt-6-luna) |
OPENAI_EXPLAIN_MODEL, OPENAI_EXPLAIN_DAILY_BUDGET_USD | 서버 | 분석 글 모델(기본 gpt-6-sol)과 하루 예산(기본 $1, 넘으면 그날은 gpt-6-luna). 로컬은 OPENAI_EXPLAIN_MODEL=gpt-6-luna 권장 |
CRON_SECRET | 🔒 | Vercel Cron 호출 인증 (16자 이상 무작위) |
NEXT_PUBLIC_API_MOCK | 개발 | 1이면 가짜 모드 (운영 배포에서는 넣어도 꺼짐) |
🔒 값은 NEXT_PUBLIC_을 붙이지 않습니다(브라우저에 공개됨). .env*는 저장소에 올라가지 않습니다.
| 문서 | 내용 |
|---|---|
| PRD | 제품 요구사항 |
| TECH_SPEC | 기술 명세 (계산식 §6.4, AI 안전장치 §11.5, 보안 §17) |
| API_SPEC | 서버 API |
| WORK_UNITS | 작업 단위·완료조건 |
| HANDOFF | 팀 업무분장·현재 상태 (새로 합류하면 §0부터) |
| FINAL_CHECKLIST | 최종 점검표 |
| USER_TEST | 사용자 테스트 진행표 |
Supabase 무료 플랜은 7일 동안 활동이 적으면 프로젝트를 일시정지합니다 (약 1주 전 경고 메일, 정지 후 확인 메일. 정지 후 1년 안에는 대시보드에서 되살릴 수 있음 — Supabase 공식 문서, 2026-10-01 확인).
sleepyhead 프로젝트를 누릅니다.pnpm check:keys의 Supabase 2줄이 ✅以上為 README 的開頭部分。其餘內容請閱讀原文。 檢視完整 README ↗