尚未收集儲存庫資訊。
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗스팀 게임의 동접(인기 신호) × 할인(구매 신호) 을 결합한 다국어 발견 도구. 프로젝트의 모든 결정사항·제약은 CLAUDE.md가 단일 기준 문서입니다.
🟢 라이브: https://steambubbles.vercel.app (프로덕션 · ko + en 오픈)
ko(기본) + en 오픈. ja/zh·유럽어는 동결(트리거 대기).ALERT_WEBHOOK_URL 환경변수), Google Search Console 등록 + 색인 요청(브랜드·파비콘 반영 확인 겸 ko 노출 추이 계기판), 애드센스 신청(유입 축적 후). (Vercel Web Analytics는 활성 확인됨.)| 영역 | 선택 |
|---|---|
| 프레임워크 | Next.js 15 (App Router) + TypeScript |
| 스타일 | Tailwind CSS v4 |
| i18n | next-intl — /ko·/en 오픈 (구조는 ja/zh·유럽어 확장 대비) |
| DB | Neon Postgres (serverless) + Drizzle ORM |
| 수집 트리거 | Upstash QStash → /api/cron/* Route Handler |
| 시각화 | d3-force + PixiJS (Canvas/WebGL) |
| 배포 | Vercel (프로덕션 빌드는 webpack) |
npm install
DATABASE_URL이 없으면 자동으로 목업 데이터 모드로 동작합니다 (1,000개 게임 fixture, src/mocks/games.json). 실제 키 없이 npm run dev만으로 전체 UI를 확인할 수 있고, 화면 하단에 "목업 데이터 모드" 뱃지가 표시됩니다. 실데이터 전환은 .env에 값을 채우는 것만으로 이뤄집니다.
.env.example을 .env로 복사한 뒤 값을 채웁니다.
cp .env.example .env
| 변수 | 설명 | 발급처 |
|---|---|---|
DATABASE_URL | Neon Postgres 연결 문자열. 비우면 목업 모드 | https://console.neon.tech |
USE_MOCK_DATA | 1이면 DATABASE_URL이 있어도 목업 모드 강제 (선택) | — |
STEAM_API_KEY | Steam Web API 키 (일 10만 콜 예산) | https://steamcommunity.com/dev/apikey |
CRON_SECRET | /api/cron/* Bearer 인증용 랜덤 문자열 | 직접 생성 |
QSTASH_TOKEN | QStash 스케줄·체이닝 토큰 | https://console.upstash.com/qstash |
QSTASH_URL | QStash 지역 엔드포인트 (예: https://qstash-us-east-1.upstash.io) — SDK baseUrl에 필수 | 위 콘솔 |
SITE_URL | QStash 체이닝 콜백용 베이스 URL (배포 시) | — |
ALERT_WEBHOOK_URL | 데드맨스위치·서킷브레이커 알림용 Discord 웹훅 | 개인 Discord 서버 |
npm run db:push # 개발 초기: 스키마를 Neon에 직접 반영
# 또는 마이그레이션 기반:
npm run db:generate # ./drizzle 에 SQL 마이그레이션 생성
npm run db:migrate # 마이그레이션 적용
npm run dev
http://localhost:3000 접속 시 브라우저 언어에 따라 /ko 또는 /en으로 리다이렉트됩니다.
| 명령 | 설명 |
|---|---|
npm run dev | 개발 서버 (Turbopack) |
npm run build | 프로덕션 빌드 |
npm run lint | ESLint |
npm run db:push | Drizzle 스키마를 DB에 직접 반영 |
npm run db:generate / db:migrate | 마이그레이션 생성 / 적용 |
npm run db:studio | Drizzle Studio (DB 브라우저) |
node scripts/generate-mock-games.mjs | 목업 게임 fixture 재생성 (결정론적 시드) |
src/
app/[locale]/ # 로케일 라우팅 (ko·en) — 버블맵 홈 · game/[appid] 상세 · about · privacy
app/sitemap.ts # 동적 sitemap (홈+정적+게임, 로케일별) app/robots.ts
app/api/bubbles/ # 버블맵 스냅샷 API (기간·통화별) app/api/trend/ 게임별 추이 API
app/api/cron/ # players-tier1(10분) · players-tier2(30분) · players-tier3(3시간) · details · universe · maintenance · healthcheck
components/bubble-map/ # PixiJS + d3-force 버블맵 렌더러 (탭=선택 / 드래그=버블 이동 / hover=툴팁)
components/app/ # 상단 바(언어·통화·필터), 모달, 랭킹 테이블, 앱 셸
lib/ # types(계약), fetch-util(백오프+서킷브레이커), circuit(DB 지속화), steam, format, site
lib/data/ # 데이터 프로바이더 — index(스위치) / mock / db
mocks/ # 목업 fixture (games.json 1,000개, genres.json)
i18n/ # 로케일·통화 정책 (locales.ts — OPEN_LOCALES), 라우팅, 요청 설정
db/ # Drizzle 스키마(schema.ts) + Neon 클라이언트
middleware.ts # next-intl 로케일 미들웨어 (언어 감지)
messages/ # UI 문자열 사전 — ko.json / en.json
drizzle/ # 생성된 SQL 마이그레이션
scripts/ # 목업 fixture 생성기
각 Phase 완료 시 프로덕션 배포. 상세 기준은 CLAUDE.md 6번, Phase별 체크리스트는 GitHub 이슈로 추적. Phase 1~5 전부 라이브 — Launch 슬라이스 완료 (노출 우선 전략으로 Phase 4를 3보다 먼저 진행).
job_runsplayers-tier1 수집 + 데드맨스위치 헬스체크 핸들러ALERT_WEBHOOK_URL) → 중단 알림 활성화cubic-bezier(0.23,1,0.32,1)) · 버튼 press 피드백(active scale) · @starting-style + reduced-motion 분기. 버블맵 캔버스는 성능상 제외GetGamesByConcurrentPlayers 실테스트(→ Tier 1 1콜 최적화) · CLAUDE.md 기록/[locale]/game/[id] — 게임 소개(Steam short_description, 로케일별) + 데이터 대시보드(현재 동접 히어로·24h 피크·순위·스팀 점유율·가격/할인·평점 긍정률 바·출시일) + 추이·장르·Steam 링크. 동접 수치는 줄글 대신 데이터로 (소개 미수집 시 순위·평점·가격 폴백 문장)short_description·release_date 파싱 추가(추가 API 콜 0) → apps.desc_ko/desc_en/release_date. HTML 엔티티·태그 정리(수집·렌더 양쪽)router.back() 위치·스크롤 복원 / SEO 직접 유입=홈 push)/[locale]/og 동적 OG 이미지 — next/og로 top 7 동접 리더보드(1200×630) + 홈 openGraph/twitter 연결<Analytics/> — 배포 환경 수집)Phase 1~5 라이브 이후 추가된 증분. 전부 프로덕션 반영됨. 세 해자(ko SEO · 히스토리 · 공유 포맷)에 기여하는 것만.
/[locale]/og/movers, next/og 1200×630) — 순위 · 게임 썸네일(서버 프리페치 → data URI, 실패 시 이니셜 폴백으로 우아한 강등) · Δ · 동접. 공유 버튼은 이미지 미리보기 모달로 열려 다운로드 · 복사 · Web Share 제공(모바일)/api/refresh/[appid]). 3중 게이트(추적 대상만 · 6h 쿨다운 · store 서킷브레이커)로 남용/과금 방지 — "본 만큼 신선". 수집 로직은 details 크론과 lib/collect.ts 공용[1, 3000] clamp · 뒤집힘 정규화 · max>1,000이면 deep 스냅샷 승급). 스팬 상한은 전체 3,000까지 허용/icon 라우트를 로케일 리다이렉트로 깨뜨리던 버그 수정ja/zh·유럽어는 동결 (트리거 대기)ja/zh 로케일, 유럽어, 세일 감지 트리거, Tier 3 sitemap 등재, 수익화 전체. (Tier 3 수집·표시는 2026-07 오픈됨) 해제 트리거는 CLAUDE.md 8번 참조.