From 22e2e8c29c12b1bb5f806f76ac726f82fff353a8 Mon Sep 17 00:00:00 2001 From: jwkim Date: Tue, 18 Aug 2026 09:42:10 +0900 Subject: [PATCH] =?UTF-8?q?share=20OG:=20=ED=8C=80=EB=AA=85=20DB=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C(=ED=81=B4=EB=9F=BD=20=EB=A6=AC=EA=B7=B8=20?= =?UTF-8?q?=ED=95=9C=EA=B8=80=EB=AA=85)=20+=20=EB=AC=B8=EA=B5=AC=20?= =?UTF-8?q?=EA=B0=B1=EC=8B=A0=20+=20=EC=8D=B8=EB=84=A4=EC=9D=BC=20?= =?UTF-8?q?=EC=BA=90=EC=8B=9C=EB=B2=84=EC=8A=A4=ED=84=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /match/:id OG 프리렌더가 STL/CIN 같은 코드 대신 DB 의 한글 short 팀명을 사용 (KBO·MLB·MLS 포함). 리그 태그도 제목에 표기 - 설명문을 멀티리그 기준 최신 카피로 갱신 - og:image 에 ?v=2 캐시버스터 — 메신저가 과거 실패/구버전 썸네일을 캐시한 경우 재수집 유도 (index.html 정적 OG 동일 적용) Co-Authored-By: Claude Fable 5 --- backend/app/routers/share.py | 33 ++++++++++++++++++++++++++------- frontend/index.html | 6 +++--- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/backend/app/routers/share.py b/backend/app/routers/share.py index b483595..e6641d5 100644 --- a/backend/app/routers/share.py +++ b/backend/app/routers/share.py @@ -12,10 +12,14 @@ from __future__ import annotations import html -from fastapi import APIRouter +from fastapi import APIRouter, Depends from fastapi.responses import HTMLResponse +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession from ..config import settings +from ..database import get_db +from ..models import Match from ..schedule_data import TEAMS router = APIRouter() @@ -51,7 +55,7 @@ def _team_label(code: str | None) -> str: @router.get("/match/{match_id}", response_class=HTMLResponse) -async def match_share(match_id: str) -> HTMLResponse: +async def match_share(match_id: str, db: AsyncSession = Depends(get_db)) -> HTMLResponse: a, b = _parse_codes(match_id) image = DEFAULT_OG @@ -62,19 +66,34 @@ async def match_share(match_id: str) -> HTMLResponse: image = OG_DIR + OG_IMAGES[key] is_custom = True - la, lb = _team_label(a), _team_label(b) + # 팀명: DB 의 경기 행이 있으면 한글 short 명(클럽 리그 포함), + # 없으면 월드컵 정적 테이블 → 코드 순으로 폴백. + m = ( + await db.execute(select(Match).where(Match.match_id == match_id)) + ).scalar_one_or_none() + if m: + la, lb = m.team_a_short, m.team_b_short + a, b = m.team_a_code, m.team_b_code + else: + la, lb = _team_label(a), _team_label(b) # 한국은 항상 왼쪽으로 표기(프론트 화면 규칙과 동일). if b == "KOR" and a != "KOR": la, lb = lb, la + league_ko = {"kbo": "KBO", "mlb": "MLB", "mls": "MLS"}.get(m.league if m else "", "") if la and lb: - title = f"TriplePick 2026 — {la} vs {lb} AI 승부예측" + tag = f"{league_ko} " if league_ko else "" + title = f"TriplePick — {tag}{la} vs {lb} AI 승부예측" else: - title = "TriplePick 2026 — AI 2026 글로벌 축구 축전 승부예측" - desc = "AI 셋이 매 경기를 서로 다르게 예측합니다. 당신의 픽을 찍고 AI와 겨뤄보세요." + title = "TriplePick — AI 스포츠 승부예측 (월드컵·KBO·MLB·MLS)" + desc = ( + "GPT·Claude·Gemini 3대 AI가 이 경기를 서로 다르게 예측합니다. " + "당신의 픽을 찍고 AI와 겨뤄보세요." + ) origin = settings.public_origin.rstrip("/") page_url = f"{origin}/match/{html.escape(match_id)}" - img_url = f"{origin}{image}" + # ?v= 캐시버스터: 메신저가 과거 실패/구버전 썸네일을 캐시한 경우 재수집 유도 + img_url = f"{origin}{image}?v=2" t = html.escape(title) d = html.escape(desc) # 기본 썸네일만 규격이 1200x630 으로 확정 → width/height 명시. diff --git a/frontend/index.html b/frontend/index.html index 313479d..3c51456 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -28,8 +28,8 @@ content="GPT·Claude·Gemini 3대 AI가 월드컵·KBO·MLB·MLS 매 경기를 서로 다르게 예측합니다. 당신의 픽을 찍고 AI와 겨뤄보세요. 무료 참여." /> - - + + @@ -42,7 +42,7 @@ name="twitter:description" content="GPT·Claude·Gemini 3대 AI가 월드컵·KBO·MLB·MLS 매 경기를 예측합니다. 당신의 픽을 찍고 AI와 겨뤄보세요." /> - +