Commit graph

599 commits

Author SHA1 Message Date
17746581e1 feat(schedule): date_precision 컬럼 추가 (날짜 미정 일정 지원)
월만 확정된 일정을 위해 schedules에 date_precision ENUM('day','month')
추가. 기본값 'day'로 기존 일정/쿼리에 영향 없음. month인 경우
date는 해당 월 1일로 저장하고 확정 시 수정에서 정확한 날짜 입력.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 18:34:24 +09:00
01cf1cfe9a fix(mobile-schedule): 카테고리 칩 자동 숨김 제거
스크롤 방향 감지 자동 숨김이 sticky 바의 transform 전환과
충돌해 리스트 상단에서 위로 스크롤 시 떨림 발생.
항상 보이는 단순 sticky 칩 바로 변경.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 15:04:45 +09:00
f6ba4c8183 feat(mobile-members): 매거진 풀블리드 스티키 스택 디자인
- 멤버를 화면 폭 전체 화보 카드로 (한글명 + 생일/나이 + 인스타)
- 스티키 스택: 스크롤 시 다음 카드가 이전 카드를 덮으며 흐려짐/축소
- 스크롤 멈추면 가장 가까운 카드를 상단에 자석처럼 스냅
- 마지막 카드도 상단까지 올라오도록 동적 하단 여유 공간

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 14:47:37 +09:00
9b2e4e190d feat(mobile-schedule): 카테고리 필터 추가 + 리스트 카드 플랫화
- 일정 리스트 위에 카테고리 필터 칩 추가 (해당 달 전체 카테고리)
- 스크롤 방향 감지 자동 숨김 (내리면 숨고 올리면 보임), 상단 여백 일관
- 카테고리 선택 시 일정 목록 + 날짜 점 필터링 (공개 PC와 store 공유)
- 일정 리스트 카드: 그림자 제거, 1.5px 테두리로 플랫하게

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 14:10:16 +09:00
381461c25e fix(event): 모바일 축제 포스터 클릭 시 라이트박스로 열기
새 창(target=_blank) → MobileLightbox로 변경 (메인/추가 포스터 모두).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 13:48:57 +09:00
1a50f93d65 feat(event): 축제 상세 페이지 디자인 개편
- 골드 그라데이션 단일 히어로로 통합 (타입/학교/제목/날짜/장소/멤버/링크)
- 장소는 히어로에서 클릭 → 지도 다이얼로그(PC 모달/모바일 바텀시트)
- 칩(타입·학교·멤버·링크)을 흰 배경 + 앰버 글자로, 텍스트 그림자 추가
- 모바일: 포스터를 카드와 분리해 크게 표시 + 스크롤 패럴랙스/페이드

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 13:46:20 +09:00
c0ac18060d fix(admin-schedule): 카테고리 필터를 공개 페이지와 통일
- categoryCounts를 선택 날짜와 무관하게 해당 달 전체 기준으로 변경
- 달력 점도 카테고리 필터 반영

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 12:54:47 +09:00
70fb6527fe fix(event): 학교 축제 상세 날짜 옆 배지를 학교명 → 축제 타입으로
학교명은 이미 제목에 포함되어 중복이므로 '대학 축제' 타입 표시로 변경.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 12:50:32 +09:00
2ddc16d532 feat(concert): 콘서트 상세 페이지 추가 (몰입형 디자인)
기존 DefaultSection으로 빈약하게 표시되던 콘서트를 전용 상세 페이지로.

백엔드:
- getScheduleDetail 콘서트 분기: 포스터/장소/세트리스트(곡별 멤버)/굿즈/다른 회차

프론트엔드:
- ConcertSection(PC) / MobileConcertSection(모바일) 신규
- 블러 포스터 히어로 + 회차 드롭다운 + 장소 지도 다이얼로그
- 세트리스트 펼치기/접기 애니메이션, 유닛/솔로만 멤버 태그
- 굿즈 masonry 갤러리(라이트박스), 회차 전환은 history replace
- 모바일은 세로 중앙형 전용 히어로 + 바텀시트
- Lightbox/MobileLightbox를 createPortal로 변경 (오버레이 전체화면 보장)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 23:20:48 +09:00
dd5ef48592 feat(schedule): 검색 결과 없음 UI 추가 및 빈 상태 위치 개선
- PC: 검색 모드에서 결과 0개일 때 아무것도 안 나오던 문제 수정
  (돋보기 아이콘 + 검색어 표시), 검색 중 로딩 구분
- 모바일: 검색/날짜별 빈 상태를 아이콘 포함 디자인으로 통일
- 빈 상태/로딩을 일정 영역 기준으로 배치
  (PC: 상단 30% 지점, 모바일: 중앙)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 22:15:10 +09:00
8b8b9a7f53 feat(x-schedule): 링크 미리보기(OG) 카드 추가 - 하이브리드
트윗의 외부 링크에 대해 미리보기 카드 표시.
- Nitter가 렌더링한 카드 우선 사용 (extractCard)
- Nitter 카드가 비어있으면 본문 URL로 OG 직접 추출 (og.js)
  - YouTube/Instagram 등 복구, HTML 엔티티 디코딩 포함
  - TikTok 등 봇 차단 사이트는 Nitter 카드로 커버
- schedule_x.card_data 컬럼 + getScheduleDetail 응답에 card 포함
- 가로 레이아웃 카드 (왼쪽 이미지 + 오른쪽 텍스트)
- CardImage: 이미지 로드 실패 시 fallback 아이콘 (인스타 CDN 만료 대비)
- 자체 영상/이미지가 있으면 OG 카드 숨김 (중복 방지)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 19:34:42 +09:00
d3d3c9cf75 feat(x-schedule): 트윗 네이티브 영상 썸네일 표시
Nitter는 영상 파일을 제공하지 않으므로 썸네일만 추출해 표시하고,
재생 시 원본 트윗으로 이동.

- scraper: extractVideoThumbnails 추가 (amplify_video_thumb 등)
- schedule_x.video_thumbnails 컬럼 + saveTweet 저장
- getScheduleDetail 응답에 videoThumbnails 포함
- PC/모바일 X 상세: 썸네일 + 재생버튼 + 'X에서 재생' 배지

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 19:02:29 +09:00
4cfa4ffc00 fix(x-bot): 리트윗 이중 저장 방지
같은 리트윗이 타임라인에서 래퍼 id / 원본 id 두 형태로 번갈아 나타나
post_id 중복 체크를 통과해 두 번 저장되던 문제 수정.

리트윗 저장 시 동일 내용 + (원작자 또는 봇계정) username이 이미 있으면
중복으로 간주해 건너뜀. hydration으로 양쪽 모두 전체 내용을 갖추므로
내용 기반 매칭이 안정적으로 동작.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 18:02:22 +09:00
2cfc580283 fix(x-bot): 잘린 긴 리트윗 전체 내용 복원 (hydration)
X long tweet(280자 초과)을 Nitter 타임라인이 간헐적으로 …로 잘라서
주는 경우, 개별 상태 페이지에서 재요청해 전체 내용으로 교체.

- parseTweets: …로 끝나는 트윗에 truncated 플래그 부여
- hydrateTruncatedTweets: 잘린 트윗 status 페이지 재요청 후 교체 (best-effort)
- fetchTweets/fetchAllTweets에 적용
- fetchSingleTweet을 timeout-safe하게 변경

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 18:00:14 +09:00
6a24b997dd feat(logs): 활동 로그 다이얼로그 상세 정보 표시 + 에러 정보 보강
- logs API: longtext로 저장된 details를 JSON 객체로 파싱해 반환
- 응답 스키마에 additionalProperties: true 추가 (fast-json-stringify가
  스키마 미정의 키를 제거하던 문제 해결)
- scheduler 에러 로그: err.cause / err.code / err.causeCode 함께 기록
  (fetch failed 등 모호한 메시지의 진짜 원인 식별 가능)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 17:02:53 +09:00
9e3bff9762 feat(schedule): 카테고리 필터 개선 및 달력 오늘 버튼 추가
- 카테고리 카운트를 선택 날짜와 무관하게 해당 달 전체 기준으로 변경
- 카테고리 섹션이 길어지면 카드 내부 스크롤 (평소엔 콘텐츠 크기 유지)
- 달력 하단에 오늘 날짜로 이동하는 버튼 추가
- 달력 하단 여백 24px → 20px

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:47:13 +09:00
51e8f17cc1 feat(schedule): 카테고리 선택 시 달력 점도 필터링
카테고리 필터가 일정 목록만 필터링하던 것을 달력 점에도 적용.
날짜 필터는 제외하여 달력은 한 달 전체 점을 유지.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:35:12 +09:00
d530822a68 feat(festival-bot): 대학 축제 크롤러 봇 구현 (3단계)
검색 페이지(memogipost)를 크롤링하여 프로미스나인 출연 대학 축제를
Gemini url_context로 추출, 행사 일정을 자동 생성하는 봇.

백엔드:
- services/event.js: 이벤트 생성 로직 공유화 (upsertVenue, createEventSchedule, 카카오 검색)
- services/festival/: scraper(검색 페이지 크롤) + gemini(추출) + index(봇 플러그인)
- routes/admin/festival-bots.js: 축제 봇 CRUD API
- scheduler.js: festival 타입 지원, 시간 단위 cron(0 */H * * *) 변환
- 처리한 글 URL은 festival_crawl_log에 기록, 새 글 없으면 Gemini 미호출
- 학교명 부분일치 중복 감지, 활동 멤버 전체 자동 등록
- Gemini 503/500/429 재시도 로직

기타 수정:
- 행사 상세 페이지 관련 링크 줄바꿈 (truncate → break-all)
- 대학 축제 아이콘 변경 (GraduationCap → PartyPopper)
- docs/api.md, CLAUDE.md 환경변수 문서화

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:28:24 +09:00
3827a23d75 feat(festival-bot): 축제 봇 관리 UI 추가 (2단계)
- bot_festival, festival_crawl_log 테이블 SQL
- FestivalBotDialog: 봇 이름/크롤링 URL/동기화 간격(1~24시간) 입력
- 봇 관리 페이지에 '축제' 섹션 추가 (emerald, PartyPopper)
- BotCard: festival 타입 수정/삭제 버튼 표시
- API 클라이언트 함수 추가 (백엔드 라우트는 3단계)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:09:07 +09:00
2e459995c3 fix(event): 세부 타입 라벨 '학교 축제' → '대학 축제'
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 21:50:12 +09:00
bcc8555193 feat(youtube-bot): 제목에서 멤버 추출 옵션 추가
- bot_youtube에 extract_members_from_title 컬럼 추가 (기본값 0)
- services/youtube/index.js: 설명과 제목에서 각각 멤버 이름 검색, 합집합으로 중복 제거
- YouTubeBotDialog 고급 설정에 토글 추가 (설명 추출 토글 아래)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 18:50:02 +09:00
678e228bc5 feat(x-bot): 관리 YouTube 채널 영상 제외 옵션 추가
- bot_x에 exclude_managed_channels 컬럼 추가 (기본값 1, 기존 동작 유지)
- X 봇이 트윗에서 YouTube 링크를 추출할 때 이미 등록된 YouTube 봇 채널의 영상을 중복 추가할지 옵션으로 제어
- XBotDialog에 토글 추가 (extract_youtube 활성 시만 노출, 왼쪽 border로 하위 옵션 시각화)
- services/x/index.js processYoutubeLinks 시그니처에 옵션 파라미터 추가

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 18:45:45 +09:00
9e87549ca3 style(admin): 곡 검색 다이얼로그 선택 순서 번호 표시
- 체크 아이콘 대신 선택 순서(1, 2, 3...) 숫자 뱃지 표시
- 선택 해제 시 남은 곡 번호 자동 재계산
- 숫자 시각 중심 보정 (leading-none + translate-y)
- 순서는 이미 클릭 순서대로 세트리스트에 추가됨 (selectedTracks push 순서 유지)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 17:25:42 +09:00
18efd952c4 style(admin): 세트리스트 드래그앤드롭 재정렬 추가
- framer-motion의 Reorder를 사용해 세트리스트 곡 순서를 드래그로 변경 가능
- 카드 왼쪽에 GripVertical 핸들 영역 분리, 오른쪽에 기존 폼 필드
- 내부 input/버튼은 드래그 임계값 덕분에 자유롭게 조작 가능

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 17:22:14 +09:00
5472725e9c style(admin): 콘서트 굿즈 섹션 UI 개선 + 드래그앤드롭 재정렬
- 그리드 4열 레이아웃으로 전환해 카드 공백감 해소
- 세로 이미지 잘림 방지: aspect-[3/4] + object-contain + 회색 배경
- 호버 시 삭제 버튼 노출, 순서 뱃지 상시 표시
- 마지막 칸에 '+ 추가' 점선 타일 추가 (다중 업로드 가능)
- @dnd-kit 기반 드래그앤드롭 재정렬 도입 (DragOverlay, rectSortingStrategy)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 17:13:20 +09:00
2564e1ddef style(admin): 콘서트/예능 수정 폼 너비를 추가 폼과 통일
수정 폼이 화면 전체 너비를 쓰던 문제를 max-w-4xl 컨테이너로 감싸 추가 페이지와 동일하게 맞춤.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 17:04:17 +09:00
7c20e9bb17 feat(schedule): 행사 수정 폼 + 공개 상세 페이지 + 지도
- Admin: EventEditForm 추가 (기존 포스터 유지 + 신규 추가 조합), ScheduleItem 편집 경로에 '행사' 분기
- PC 공개 상세: EventSection 추가 - 포스터 Swiper 슬라이드 + 호버 화살표, 클릭 시 Lightbox, 카카오맵 + 마커 + 장소명 오버레이, 관련 링크는 중간점+primary 색상, max-w-5xl 및 text-2xl로 크기 확대
- Mobile 공개 상세: MobileEventSection 추가 (포스터/장소/지도/링크)
- KakaoMap 공용 컴포넌트 신규 (SDK 1회 로드 공유), VITE_KAKAO_JS_KEY 사용
- .gitignore: frontend/.env 제외
- routes/admin/events.js: PUT 핸들러의 addOrUpdateSchedule → syncScheduleById 정정
- 관련 문서(api/architecture/development) 업데이트

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 12:24:01 +09:00
d9836d2f5d feat(schedule): 행사 카테고리 추가 (학교 행사)
- schedule_categories에 '행사' 카테고리(id=11) 시드, CATEGORY_IDS.EVENT 상수 추가
- event_venues / schedule_event 테이블 생성 (subtype, school_name, venue_id, post_urls, poster_image_ids)
- routes/admin/events.js 신설: multipart 기반 CRUD + 다중 포스터 업로드 + 카카오맵 venue upsert
- services/image.js에 uploadEventPoster 추가 (event/{scheduleId}/poster/...)
- 공개 /schedules 서비스의 SCHEDULE_LIST_SQL / getScheduleDetail에 행사 JOIN 및 응답(subtype, schoolName, venue, posters, postUrls)
- buildSource에 EVENT 분기 추가 → source.name = 학교명
- Meilisearch 동기화: source_name에 school_name 포함, 부분 검색 대응을 위한 resolveSchoolNames 추가
- 프론트: form/index.jsx에 '행사' 분기, EventForm 컴포넌트 신설 (LocationSearchDialog 재사용, 다중 포스터/URL)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 09:04:42 +09:00
f2a15e07d6 feat(youtube-bot): 주간 지정 시간 폴링 모드 추가
- bot_youtube에 weekly_schedule_config JSON 컬럼 추가, cron_interval nullable로 변경
- weekly 모드: 지정 요일/시각에만 cron 트리거 → setInterval로 intervalSeconds 간격 폴링
- 종료 조건: 새 영상 1개 발견(stopOnFound) 또는 durationMinutes 경과
- 평상시 API 호출 없어 주 1회 업로드 채널(워크맨 등)의 할당량 낭비 최소화
- 프론트 폼에 상시/주간 모드 토글 추가, 요일 드롭다운 월~일 순서로 정렬
- 관련 문서(api/development/architecture) 갱신

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 20:56:54 +09:00
39bb6f77f9 feat(admin): 활동 로그 페이지에 페이지 번호 직접 입력 기능 추가
- 페이지네이션을 3-column grid로 배치해 버튼 그룹은 중앙 정렬, 오른쪽 구석에 입력 박스 추가
- 숫자만 입력, Enter 또는 blur 시 페이지 이동 (1~totalPages로 clamp)
- Enter 시 blur() 호출로 포커스 자동 해제

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 11:47:59 +09:00
8ece4b1850 feat(backend): 봇 연속 오류 시 자동 정지 로직 추가
- consecutiveErrors 카운터로 실패 횟수 추적 (성공 시 0으로 리셋)
- 동일 에러 루프에서 sync/error 로그는 첫 1회만 기록하여 스팸 방지
- 10회 연속 실패 시 stopBot 호출 및 bot/stop 로그 1건 남김
- docs/logs.md, docs/development.md 관련 설명 추가

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 11:38:37 +09:00
f73314d5dc feat(app): 예능 일정 상세 화면 추가
- ScheduleDetail 모델: broadcaster, replayUrl, varietyThumbnailUrl 필드 추가
- 예능 섹션: 썸네일(블러 배경 + contain) + 정보 카드
- 방송사 뱃지(카테고리 색상), 날짜/시간, 제목, 멤버, 다시보기 버튼
- 썸네일 없을 때 카테고리 색상 배경 + Tv 아이콘 표시

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 17:06:06 +09:00
aae606725f feat(mobile): 앨범/곡/컨셉포토 상세 페이지 뒤로가기 버튼 추가
- MobileHeader에 showBack prop 추가 (ChevronLeft + history.back)
- Layout에 showBack 전달
- 라우터에서 상세 페이지에 showBack 적용
- 개별 페이지의 중복 액션바 제거

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 14:16:19 +09:00
901d788d9a feat(mobile): 일정 상세 페이지 액션바에 뒤로가기 버튼 추가
- ChevronLeft 아이콘 + history.back()
- 오른쪽 w-9 빈 영역으로 제목 중앙 정렬 유지

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 14:11:35 +09:00
1626091539 style(mobile): 일정 상세 액션바 카테고리 텍스트 font-bold로 변경
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 14:09:38 +09:00
aaec7fa071 style(mobile): 예능 썸네일 블러 배경 + 높이 축소
- 높이 h-52로 고정
- 배경에 동일 이미지를 scale-110 blur-2xl로 깔아서 빈 공간 채움
- 메인 이미지는 object-contain으로 원본 비율 유지

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 14:07:46 +09:00
45819f7a01 style(pc): 예능 상세 썸네일/정보 가로 배치, 높이 독립
- 썸네일: w-52 h-72 고정, object-cover
- 정보 카드: flex-1, 콘텐츠에 따라 높이 자유
- items-start로 서로 높이 영향 없음

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 14:05:37 +09:00
de3adc0ad6 refactor: 예능 상세 페이지 썸네일/정보 분리 레이아웃
- 가로 flex → 세로 분리 (썸네일 카드 + 정보 카드)
- 썸네일: object-contain으로 원본 비율 유지, max-h 제한
- 기본 이미지: 카테고리 색상 배경 + Tv 아이콘
- 제목이 길어져도 레이아웃 깨지지 않음
- PC/모바일 모두 적용

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 14:03:48 +09:00
2a1849f608 feat: 예능 썸네일 없을 때 카테고리 색상 기본 이미지 표시
- 썸네일 없으면 카테고리 색상 배경 + Tv 아이콘 표시
- PC/모바일 모두 적용
- 항상 flex 레이아웃 유지 (썸네일 유무와 무관)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 13:58:57 +09:00
4bc188b4f9 feat: 모바일 예능 일정 상세 섹션 추가
- MobileVarietySection: 썸네일(w-32) + 콘텐츠 flex 레이아웃
- 방송사 뱃지, 제목, 멤버 칩, 다시보기 버튼
- PC 버전과 동일한 구조, 모바일 사이즈에 맞게 축소

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 13:57:03 +09:00
83dd852ffb style: 예능 다시보기 버튼을 다크 스타일로 변경
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 13:54:49 +09:00
de1399579f style: 예능 상세 텍스트 크기 전체적으로 확대
- 방송사 뱃지/날짜: text-xs → text-sm
- 제목: text-lg → text-xl
- 멤버 칩: text-xs → text-sm, 패딩 증가
- 다시보기 버튼: text-xs → text-sm, 패딩 증가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 13:53:11 +09:00
b1d890d758 style: 예능 상세 레이아웃 상단/하단 분리
- 방송사+날짜, 제목, 멤버: 상단에 붙임
- 다시보기 버튼: mt-auto로 하단에 고정
- justify-between으로 세로 공간 분배

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 13:52:12 +09:00
c990af41e1 style: 예능 상세 페이지 디자인 정리
- 썸네일 hover 효과 제거, 너비 w-44로 축소
- 다시보기 버튼: 멤버 칩과 같은 줄에 compact하게 배치 (회색 pill)
- 불필요한 border-t 구분선 제거
- 전체적으로 compact한 레이아웃

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 13:51:09 +09:00
fcbda88464 fix: 예능 상세 썸네일을 세로 포스터 레이아웃으로 변경
- 가로 전체 → 왼쪽 세로 포스터(w-52) + 오른쪽 콘텐츠 (flex 레이아웃)
- 세로 이미지가 잘리지 않도록 object-cover + 고정 너비

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 13:48:12 +09:00
36854a223f style: PC 예능 상세 페이지 디자인 개선
- 썸네일: aspect-video 비율, hover 시 확대 + 재생 버튼 오버레이
- 방송사 뱃지: 카테고리 색상 기반, 날짜와 한 줄로 배치
- 다시보기 버튼: 다크 pill 스타일, 유튜브면 Play 아이콘
- 전체 카드 레이아웃으로 통일

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 13:46:31 +09:00
6feedae267 feat: PC 예능 일정 상세 페이지 추가
- VarietySection: 썸네일, 방송사 뱃지, 제목, 날짜/시간, 멤버, 다시보기 버튼
- ScheduleDetail에서 '예능' 카테고리 분기 연결

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 13:45:14 +09:00
c14bd90e89 fix: 카테고리 API를 React Query로 변경 (중복 호출 방지)
- useEffect + useState → useQuery로 변경
- staleTime 10분으로 캐시하여 중복 요청 제거
- 카테고리 색상 Redis 캐시도 삭제 (DB 변경 반영)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 13:40:17 +09:00
48ed3bb9e0 feat(variety): 방송사 프리셋을 입력 빈도수 기반으로 변경
- GET /admin/variety/broadcasters: DB에서 빈도수 상위 10개 조회 (Redis 1시간 캐시)
- 일정 생성/수정 시 캐시 무효화
- 프론트엔드: 하드코딩 프리셋 제거, API에서 동적으로 로드

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 13:37:52 +09:00
a01d368728 feat(variety): 썸네일을 RustFS 이미지 업로드로 변경
- schedule/{id}/thumbnail/ 경로에 original/medium_800/thumb_400 webp 업로드
- images 테이블로 이미지 관리, schedule_variety.thumbnail_id로 참조
- 프론트엔드: URL 입력 → 파일 업로드(드래그&드롭) + 미리보기로 변경
- 수정 시 기존 썸네일 교체/삭제 지원

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 19:07:08 +09:00