91 lines
3.7 KiB
Markdown
91 lines
3.7 KiB
Markdown
# 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` |
|
||
| 투표 마감 | 킥오프 정각 | `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)
|