# TriplePick 2026 **"AI(GPT · Claude · Gemini) vs 너"** — 글로벌 축구 승부예측 서비스. 3개 AI 모델이 매 경기를 서로 다르게 예측하고, 유저는 픽을 찍어 AI와 겨룬다. 끝까지 가장 정확하게 맞힌 1인에게 100만원 챌린지. ## 아키텍처 ``` o2o-triple-pick/ ├── docker-compose.yml # db · api · worker · frontend 한 번에 실행 ├── backend/ # FastAPI + SQLAlchemy(async) + PostgreSQL │ ├── app/ # API · 워커(APScheduler) · AI/이메일 실연동 │ └── .env.example └── frontend/ # React + Vite + TypeScript + Tailwind v4 ├── src/ # pages · components · lib(api 연동) └── .env.example ``` - **frontend** — React SPA. nginx 가 정적 파일 서빙 + `/api` 를 백엔드로 프록시. - **backend (api)** — FastAPI. 경기/AI예측/crowd 읽기, 픽 제출, 채점, 리더보드, 관리자. - **backend (worker)** — APScheduler 별도 프로세스. 아래 "시간 기반 작업" 자동 처리. - **db** — PostgreSQL. ## 빠른 시작 (Docker) ```bash cp backend/.env.example backend/.env # 키(선택) 채우기 docker compose up --build # 프론트: http://localhost:8080 # API 문서: http://localhost:8000/docs ``` DB 는 최초 기동 시 6경기 + AI 예측(부트스트랩) + crowd baseline 으로 자동 시드된다. AI/이메일 키가 없어도 전체 플로우(예측·제출·채점·리더보드)는 즉시 동작한다. ## 시간 기반 작업 (워커가 자동 처리) 조사된 "필요한 시간들"을 워커 단일 프로세스가 모두 담당한다: | 작업 | 시점 | 설정 | |---|---|---| | 투표 오픈 | 킥오프 − 48h (D-2) | `VOTE_OPEN_HOURS_BEFORE` | | 투표 마감 | 킥오프 − 5분 | `VOTE_LOCK_MINUTES_BEFORE` | | 상태 전이 (scheduled→open→locked→finished) | 주기 틱 | `STATUS_TICK_SECONDS` (기본 60s) | | AI 예측 생성 (3모델 실 API 호출) | 매일 KST 00:05 | `AI_GENERATE_HOUR` / `_MINUTE` | | 결과 메일 발송 (구독자) | 경기 종료 +3h | `RESULT_EMAIL_DELAY_MINUTES` | > 데모에서는 `DEMO_FORCE_OPEN=true` 로 마감 전까지 항상 투표 가능. **운영 배포 시 false**. ## 외부 연동 (실연동 — 키 없으면 해당 기능만 생략) - **AI 3모델** — OpenAI(GPT) · Anthropic(Claude, `claude-opus-4-8`) · Google(Gemini). `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` / `GOOGLE_API_KEY`. - **이메일** — SMTP. `SMTP_HOST` 외 `backend/.env` 참조. ## API 요약 | 메서드 | 경로 | 설명 | |---|---|---| | GET | `/api/matches?lang=ko` | 전체 경기 (예측·crowd 포함) | | GET | `/api/matches/{id}` | 경기 상세 | | POST | `/api/predictions` | 픽 제출 (1회 수정·crowd 증분·매칭 모델) | | GET | `/api/leaderboard` | 누적 포인트 랭킹 | | POST | `/api/admin/result` | (Bearer) 결과 입력 → 채점 | | POST | `/api/admin/ai-predictions` | (Bearer) AI 예측 수동 upsert | ## 로컬 개발 (Docker 없이) ```bash # 백엔드 cd backend && python3.12 -m venv .venv && source .venv/bin/activate pip install -r requirements.txt # Postgres 띄우고 DATABASE_URL 지정 후: uvicorn app.main:app --reload # API python -m app.worker # 워커 # 프론트 cd frontend && npm install && npm run dev # http://localhost:5173 (/api → :8000 프록시) ``` ## 채점 규칙 `docs/SCORING.md` (SSOT). 정확 스코어 5 · 근접 3 · 승패 2 · 부분 1 · 빗나감 0. 누적 포인트 1위에게 최종 상금. 임직원/운영진 배제. ## 문서 - `docs/SCORING.md` — 채점·심사 SSOT - `docs/DESIGN.md` — 디자인 토큰 SSOT - `docs/BACKEND.md` — 초기 백엔드 설계 메모(Firebase 기준 → 현 구현은 FastAPI)