Commit Graph

28 Commits

Author SHA1 Message Date
bb930cc59f 응원가 공유·플레이어 문구 '오늘의' → 제작일 표기 (예: 8월 28일 OO 응원가)
songs API에 dateKst(경기일) 추가, OG 공유 제목·프론트 shareText·artist에 적용
— 매일 갱신되는 콘텐츠임을 드러낸다

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 10:21:24 +09:00
fdb04a2ccc 응원가 영구 보존·종료 경기 노출 — 음원 DB 저장 + 경기별 조회 API
- Suno CDN 임시 URL 만료 대비: 완성 곡 첫 트랙을 워커가 다운로드해
  song_audio(bytea)로 보존하고 audioUrl을 /api/songs/audio/{id}/{idx}로 재작성
  (틱당 5곡, 실패 3회 상한 — 기존 곡도 자동 백필)
- GET /api/songs/match/{match_id} 추가 — 날짜 무관 조회로 종료된 경기
  상세에서도 '응원가 듣기' 버튼 노출
- 프론트 getTeamSongTracks를 오늘 전체 캐시 → 경기별 조회·캐시로 전환
- 음원 서빙은 Range(206) 지원, immutable 캐시 + task_id 캐시버스터

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 15:39:16 +09:00
6770543318 월드컵 서비스 종료 + 응원가 MLS 확장
- 리그 탭에서 월드컵 제거, ?league=wc 는 KBO 강등, 기본 리그 kbo·mlb·mls
- index.html·OG 기본 타이틀에서 월드컵 문구 제거, 월드컵 특설 정적
  플레이리스트 제거
- 응원가 MLS 포함: 라인업 소스 없는 리그는 윈도우 진입 즉시 생성,
  스타일은 soccer 앤섬 변형, 커버 로고는 Match flag(ESPN PNG) 재사용
- MLB 도 한국 팬 표기 지시 적용, 전날 활약 조회는 kbo/mlb 만

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 10:47:49 +09:00
abcdf42aeb 가사 데이터 보강(활약·타율) + 커버는 팀 로고 100%
- 전날 경기 활약: KBO=네이버 record 타자 boxscore(홈런·3안타 이상),
  MLB=boxscore batting — 어제 결과 줄에 "활약: ..." 로 부가
- 확정 라인업에 타자 시즌 타율 병기 (MLB=seasonStats, KBO=최근 경기 hra 맵)
- 커버 합성에서 Suno 배경 제거 — 다크 단색 배경 + 팀 로고 최대 크기

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 10:42:55 +09:00
434f282e6b 응원가 커버를 팀 로고 합성본으로 교체
- /api/songs/cover/:matchId/:teamCode — Suno 앨범아트(감광 배경) 위에
  팀 로고 중앙 합성 (1200x630, OG 규격), 메모리 캐시 + task 캐시버스터
- 로고 소스: KBO=프론트 로컬 PNG(내부 프록시), MLB=mlbstatic spots PNG
- 플레이어 썸네일·/song OG 카드 모두 합성 커버 사용, pillow 의존성 추가

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 10:26:49 +09:00
dbc26a4150 곡 스타일 전곡 고정 + 팀당 1곡만 노출
- 스타일은 레퍼런스 확정본(brass fanfare·drum corps·128bpm·live stadium)
  으로 고정, LLM 은 제목·가사만 작성
- Suno 생성 2트랙 중 첫 트랙만 API 노출

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 10:23:51 +09:00
3a5fc36ee8 플레이어에 가사 보기·공유하기 + 응원가 전용 OG 공유 카드
- 하단 MusicBar: 가사 패널 토글(바 위로 펼침)·공유 버튼(네이티브 공유,
  폴백 클립보드) — 응원가 트랙에만 노출
- 공유 링크 /song/:matchId/:teamCode — 크롤러(카톡·페북)는 "오늘의 OO
  응원가" 제목 + Suno 앨범아트 OG 카드, 사람은 경기 페이지로 리다이렉트
  후 그 팀 응원가 자동 로드(?song=)
- nginx /song/ 크롤러 분기 추가

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 10:20:54 +09:00
dbd08e62c7 응원가를 MLB 로 확장 (MLS 제외)
- MLB 라인업: Stats API schedule→gamePk→boxscore battingOrder (양팀 9명 = 발표)
- 작사 프롬프트 리그 분기 (MLB 는 한국 팬 표기 지시)
- /api/songs/today league 미지정 시 전 리그 반환, 프론트는 전 리그 조회
- 상세 페이지 응원가 버튼 KBO+MLB 노출

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 10:05:27 +09:00
0fc7598d88 응원가 생성을 라인업 발표 이후로 게이트
- 네이버 preview fullLineUp 조회 — 양팀 타자 8명 이상이면 발표로 간주,
  확정 라인업(타순·포지션 실명)을 가사 컨텍스트에 주입
- 생성 윈도우(킥오프 150분 전~) 안에서 발표까지 대기, 킥오프 40분 전까지
  미발표면 라인업 없이 폴백 생성
- 라인업 없이 만든 곡은 발표 후 자동 재생성(업그레이드) — 기존 트랙을
  유지한 채 새 곡 완성 시점에 교체, 실패 시 이전 곡 복귀

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 09:59:19 +09:00
277378477a 오늘의 응원가 자동 생성 파이프라인 (Suno)
- 경기 맥락(전날 결과·순위·연전 차수·선발투수) 조립 → LLM 작사
  (콜앤리스폰스·섹션 태그 형식) → Suno(sunoapi.org) 생성 → songs 테이블
- 워커: 킥오프 150분 전 윈도우 진입 시 생성 시작 + 2분 주기 폴링
- API: GET /api/songs/today · POST /api/songs/callback(싱크대)
  · POST /api/songs/generate(관리자 강제 생성)
- 프론트: MusicBar 가 경기 상세·메인에서 오늘의 응원가를 동적 로드
  (정적 플레이리스트는 폴백 유지)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 09:33:34 +09:00
22e2e8c29c share OG: 팀명 DB 조회(클럽 리그 한글명) + 문구 갱신 + 썸네일 캐시버스터
- /match/:id OG 프리렌더가 STL/CIN 같은 코드 대신 DB 의 한글 short 팀명을
  사용 (KBO·MLB·MLS 포함). 리그 태그도 제목에 표기
- 설명문을 멀티리그 기준 최신 카피로 갱신
- og:image 에 ?v=2 캐시버스터 — 메신저가 과거 실패/구버전 썸네일을
  캐시한 경우 재수집 유도 (index.html 정적 OG 동일 적용)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 09:42:10 +09:00
7705099c64 feat(auth): 카카오 로그인 — o2o-castad-backend 인증 스택 이식
백엔드 (castad 와 동일 흐름, triplepick 스타일로 재작성):
- users/refresh_tokens 테이블 (신규 — create_all 로 자동 생성)
- 카카오 OAuth (code → 토큰 → 사용자 정보), aiohttp 대신 httpx
- JWT HS256 access 60분 / refresh 7일, Refresh Token Rotation
  (재사용 감지 시 TOKEN_REVOKED, castad 동일 에러 코드 체계)
- /api/auth/{kakao/login, kakao/callback, refresh, logout, me}
- 콜백 → 프론트 리다이렉트는 쿼리 대신 해시 프래그먼트로 토큰 전달
  (서버 로그·Referer 에 토큰 노출 방지 — castad 방식에서 한 단계 보강)
- 크레딧·소셜계정 연동 등 castad 전용 개념은 제외

프론트:
- lib/auth.ts — 토큰 보관·자동 갱신·/me 캐시·useAuth 훅
- Hero 에 카카오 로그인 버튼(브랜드 노랑) / 프로필 칩 + 로그아웃
- 투표 폼(Arena) 이메일을 로그인 계정 이메일로 자동 채움
  (기존 이메일 기반 투표·리더보드 파이프라인은 그대로 유지)

설정: KAKAO_CLIENT_ID/SECRET/REDIRECT_URI, JWT_SECRET (.env.example 참고)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 15:42:54 +09:00
74de57fc1c feat(mls): MLS 리그 추가 — ESPN 비공식 API 연동
- 일정·결과·컨퍼런스 순위·프리뷰(폼/시즌전적/맞대결/머니라인) 수집
- 라이브 카드: 스코어·경기시간·득점/카드·선발 라인업(피치 뷰)·교체 현황
- 문자중계: ESPN commentary 규칙 기반 한글 변환 (미지원 템플릿은 팀명만 한글화)
- MLS 레코드는 야구와 키 구조가 같아 sync_baseball_schedule/settle 재사용
- AI 예측 데이터 블록에 MLS 전용 컨텍스트 추가

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 13:47:13 +09:00
c73a9ad9f9 관리자 조회 API 추가(경기별 투표·이메일 랭킹, 토큰 인증) + ops/ gitignore
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 14:04:14 +09:00
4e1ebc8989 feat: KBO/MLB 운영 안정화 — 순위 탭·라이브 개선·취소/더블헤더 지원·야구 점수제
AI 예측
- 생성 시점을 킥오프 22시간 전으로 변경(선발투수 예고 이후), 잡 매시간 실행
- 경기 시작 후 생성 금지(사후 예측 방지), 경기 단위 커밋으로 중단 시 진행분 보존

일정·라이브 UI
- 야구 일정에 순위 탭 추가 (KBO 단일 순위표 · MLB 6개 디비전, /api/standings 신설)
- 경기중 카드에 현재 이닝·실시간 스코어 표시 (30s 폴링, 서버 15s 캐시)
- MLB 선발 누락 수정: statsapi 날짜 파라미터 미국 날짜 기준 보정(-1일)
- 라이브 대기타석 스크롤바 다크 테마 처리

운영 견고성
- 우천취소: 경기 삭제 → cancelled 상태 보존 (투표·예측 기록 유지, 정산/투표/AI 제외)
- 더블헤더: 시작시각순 seq로 1·2차전 분리 등록 (match_id _2, 정산·라이브·프리뷰 매핑)
- 축구 데이터 수집을 wc 리그로 한정 (야구 팀을 축구 API에 검색하던 쿼터 낭비 수정)

점수제
- 야구 판정 완화: 근접=득실차 ±1, 부분=한 팀 득점 ±1 (등급·배점은 리그 공통 유지)
- 채점 판정을 _grade_of() 단일 함수로 통합, 종료된 야구 경기 재채점
- 배점 안내 모달 야구 문구 분리, docs/SCORING.md 갱신

기타
- 야구 전용 댓글 닉네임 풀 (종목별 세션 캐시 분리)
- 리더보드 리그별 조회 연동 (?league=)
2026-07-22 11:01:10 +09:00
16bd01fc95 남아공전 공유하기 한국이 왼쪽으로 오게끔 수정 2026-06-22 17:32:24 +09:00
0a64a220ca Crowd Pick 합 100% 초과 버그 수정 및 투표 오픈을 킥오프 7일 전으로 변경 2026-06-19 10:36:58 +09:00
a8e20d5ac8 누적 랭킹 보기 탭 추가 2026-06-18 17:01:41 +09:00
b4fc96f299 내 지난 얘측 보기 기능 추가, 한국 멕시코 경기 응원가 1곡 추가 2026-06-18 15:41:39 +09:00
b62bedc665 feat: 댓글 익명화 + 전 경기 적용
- 이메일/투표 게이트 제거 → 완전 익명
- 세션 단위 발급(sessionStorage 캐싱) — 탭 닫으면/시크릿이면 새 닉
2026-06-17 14:47:26 +09:00
8a67094510 한국 멕시코 경기 댓글 기능 추가 2026-06-17 11:22:29 +09:00
65e7c7571c 한국-멕시코전 전용 공유 카드 + 앱 배너 이미지 2026-06-15 17:22:38 +09:00
deb1332440 Load all 12 groups' schedule (72 matches) + Naver-style schedule UI
Backend
- teams_data.py: 48-team data (ko/short/en), TLA→FIFA code remap
- config: schedule_all_groups, featured_group("A") — only featured group is votable/AI-predicted
- schedule_fetch: fetch all GROUP_STAGE matches from football-data, KST serialize
- schedule_sync: ingest all groups, unordered-pair match to avoid Group A dup, derive votable from group
- worker: AI generation limited to featured group; settle still covers all
- domain/predictions: is_votable() + MatchOut.votable; reject non-votable submits with 403 MATCH_NOT_VOTABLE

Frontend
- types: Match.votable
- ScheduleBoard: Naver-style date/group tabs + chips; votable(A) cards link to detail with AI split + 참여수, others display-only

Verified: 72 matches (12×6), Group A not duplicated, votable A=6/others=66; A submit 200, B submit 403

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 14:56:24 +09:00
c9244bc42d feat(predictions): 이메일도 중복 투표 방지 (이메일 우선 식별)
같은 이메일은 같은 경기에 1픽만 — 다른 기기에서 같은 이메일로 제출 시
새 픽 추가 대신 기존 픽 수정 + crowd 보정. 이메일은 소문자 정규화 저장.
모델에 (match_id, email) 유니크 제약 추가(신규 DB 적용, 기존 테이블은 앱 로직 보장).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 10:51:42 +09:00
140e15fb9f feat(stats): 일별 방문자 집계 추가
page_visits 테이블((visit_date, device_id) 유니크) — 하루 1기기 1회 집계.
POST /api/visit(접속 기록), GET /api/admin/visits(일별 순수 방문자, Bearer).
프론트는 App 마운트 시 1회 recordVisit() 호출.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 17:31:23 +09:00
8a4a23b0cb 전체일정 스코어 조정, utc 시간 -> kst 변경 2026-06-11 10:48:16 +09:00
1a803b7fa0 포인트 시스템 추가, 프론트 국기 반영 2026-06-10 15:11:56 +09:00
6ffe0dfca3 Refactor: Next.js+Firebase → React(Vite) + FastAPI + PostgreSQL
- 백엔드: FastAPI + SQLAlchemy(async) + PostgreSQL, 별도 워커(APScheduler)
- 프론트: React 19 + Vite + TS + Tailwind v4 (기존 UI 이식, API 연동)
- docker-compose: db · api · worker · frontend 일괄 실행
- 경기 일정: openfootball 매일 09:00 크롤링 → DB upsert (신규 경기 자동 삽입+예측 생성)
- AI 예측: GPT·Claude·Gemini 실 API 매일 생성 → DB 저장 → 조회 (목데이터 제거)
- 투표창: 오픈 킥오프 D-2 / 마감 킥오프 1시간 전, lockAt 백엔드 전달→프론트 카운트다운
- 채점/리더보드: docs/SCORING.md 기준 누적 포인트
- crowd: 0 시작, 실제 제출로만 증분
- 구 Next.js/Firebase 파일 제거, README/AGENTS 갱신

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 13:04:35 +09:00