# TriplePick — 아키텍처 (에이전트용 안내) "AI(GPT·Claude·Gemini) vs 너" 글로벌 축구 승부예측 서비스. 모바일 우선. ## 스택 (2026 리팩토링) - **frontend/** — React 19 + Vite + TypeScript + Tailwind v4, react-router. nginx 정적 서빙. - **backend/** — Python FastAPI + SQLAlchemy(async) + PostgreSQL. 별도 워커(APScheduler). - **docker-compose.yml** (루트) — db · api · worker · frontend 를 한 번에 실행. ## 디렉토리 ``` backend/app/ config.py 설정(.env): DB·투표윈도우·스케줄러시각·외부키 database.py async 엔진/세션, init_db models.py ORM: matches / ai_predictions / crowd_stats / user_predictions schemas.py Pydantic API 계약 (프론트 lib/types.ts 와 정합) scoring.py 채점(docs/SCORING.md SSOT) + 임직원 배제 schedule_data.py 경기 일정 SSOT (Group A 6경기, KST) seed_data.py 부트스트랩(결정론적) 예측/crowd 생성기 seed.py DB 시드 (idempotent) domain.py phase 계산 + ORM→응답 직렬화 services/ ai.py(3모델 실연동) · email.py(SMTP) · grading.py routers/ matches · predictions · leaderboard · admin main.py FastAPI 앱(API) worker.py APScheduler 워커(상태전이·AI생성·결과메일) frontend/src/ lib/ types · i18n · format · api(백엔드 호출) · useLang components/ Hero · MatchupHUD · Arena · ScheduleBoard · TeamFlag · … pages/ Dashboard · MatchDetail · Leaderboard · NotFound ``` ## 시간/스케줄 규칙 (워커가 자동 처리) - 투표 오픈 = 킥오프 − 120h(D-5, `VOTE_OPEN_HOURS_BEFORE`) - 투표 마감 = 킥오프 5분 전(`VOTE_LOCK_MINUTES_BEFORE=5`) - 상태 전이: scheduled → open → locked → finished (`STATUS_TICK_SECONDS` 주기) - AI 예측 생성: 매일 KST `AI_GENERATE_HOUR:MINUTE` (실 LLM API 호출) - 결과 메일: 경기 종료 후 `RESULT_EMAIL_DELAY_MINUTES`(기본 180=3h) 경과 시 발송 - `DEMO_FORCE_OPEN=true` 면 마감 전까지 항상 투표 가능(운영 시 false) ## SSOT 문서 - `docs/SCORING.md` — 채점·심사(100만원) 단일 기준 - `docs/DESIGN.md` — 룩앤필/디자인 토큰 (변경 시 먼저 갱신) - `docs/BACKEND.md` — 초기 백엔드 설계 메모(원본 Firebase 기준 — 현 구현은 FastAPI) ## 실행 `cp backend/.env.example backend/.env` → 키 채우기 → `docker compose up --build` → http://localhost:8080