knob을 mt-0.5 margin 방식 대신 absolute top-0.5 left-0.5로 위치 지정,
트랙에 relative 추가. 위아래가 잘려 보이던 문제 해결, 4개 토글 모두
X봇 다이얼로그와 동일한 비율로 통일.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
translate-x-5.5(유효하지 않은 Tailwind 클래스)로 예정 일정/고정 멤버
토글의 knob이 움직이지 않고 색만 바뀌던 문제 수정. 모든 토글을
translate-x-5(오른쪽=활성화)로 통일.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
예정 일정 자동 생성 시 봇의 고정 멤버(default_member_ids)를 함께
추가하는 옵션(auto_schedule_config.includeDefaultMembers). 워크돌처럼
멤버가 고정인 채널의 다음 주 예정 일정에 멤버가 자동으로 붙음.
DB/라우트 변경 없이 auto_schedule_config JSON에 플래그 추가 +
관리자 다이얼로그에 토글.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
#root의 min-width(1440)를 스크롤 컨테이너(main) 내부 콘텐츠로 옮기고
main에 OverlayScrollbars 적용. 1440 미만으로 줄여도 세로 스크롤바가
뷰포트 끝에 항상 보이고 가로 스크롤이 생김(maplestory 방식). 헤더 고정
모델 유지, 일정 페이지는 기존 내부 스크롤 유지. 공개/관리자 레이아웃 동일 적용.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
카드가 onClick(schedule)을 호출하도록 변경(기존 호출부는 인자 무시라
호환), 페이지는 useCallback 안정 핸들러를 전달. 매 렌더 새 인라인
함수로 memo가 깨져 필터/스크롤마다 전체 카드가 리렌더되던 문제 해결.
검색 결과 가상화 카드는 범위에서 제외(이미 최적화됨).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
축제 봇 추가/수정 다이얼로그에 1~12월 토글 그리드 + 전체 선택/해제
추가. 신규 봇은 전체 월(항상 실행) 기본. 전체 선택은 active_months
null로 저장.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
date_precision='month' 일정을 점선 "N월 중" 카드(UndatedScheduleCard)로
표시. 선택 날짜와 무관하게 해당 월이면 확정 일정 아래에 배치하고
사이에 "날짜 미정" 구분선 추가. 카운트에도 포함.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- 카테고리 카운트를 선택 날짜와 무관하게 해당 달 전체 기준으로 변경
- 카테고리 섹션이 길어지면 카드 내부 스크롤 (평소엔 콘텐츠 크기 유지)
- 달력 하단에 오늘 날짜로 이동하는 버튼 추가
- 달력 하단 여백 24px → 20px
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- 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>
- bot_youtube에 extract_members_from_title 컬럼 추가 (기본값 0)
- services/youtube/index.js: 설명과 제목에서 각각 멤버 이름 검색, 합집합으로 중복 제거
- YouTubeBotDialog 고급 설정에 토글 추가 (설명 추출 토글 아래)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 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>
- 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>
- 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>
- 백엔드: POST/PUT/GET /admin/variety/schedule API
- 백엔드: 일정 상세 응답에 broadcaster, replayUrl, thumbnailUrl 포함
- 프론트엔드: VarietyForm (추가), VarietyEditForm (수정) 페이지
- 방송사 프리셋 버튼 (KBS, MBC, SBS, tvN, 유튜브, 티빙 등)
- 출연 멤버 선택, 다시보기 링크, 썸네일 URL 지원
- 라우트 등록 및 일정 목록 편집 링크 연결
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 백엔드: GET /admin/concert/schedule/:seriesId (상세 조회)
- 백엔드: PUT /admin/concert/schedule/:seriesId (수정)
- 프론트엔드: ConcertEditForm 페이지 (생성 폼 컴포넌트 재사용)
- 라우트: /admin/schedule/concert/:seriesId/edit 등록
- 일정 목록: 콘서트 카테고리 편집 버튼이 수정 페이지로 연결
- schedule.js: formatSchedule에 concertSeriesId 추가
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 로그 formatDateTime에서 UTC 메서드 사용하여 KST 이중 변환 방지
- 일반 일정 페이지 n개 일정 텍스트에 모드 전환 애니메이션 적용
- Vite HMR 오버레이 비활성화 (외부 봇 malformed URI 에러 방지)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
localStorage.getItem("adminToken")이 null을 반환하여 401 인증
에러가 발생하던 문제 수정. Zustand auth-storage에서 토큰을 올바르게
조회하도록 7개 파일 수정.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Logs.jsx에서 상수/유틸과 다이얼로그를 components/pc/admin/log/로 분리하여
프로젝트 구조 패턴에 맞춤. 빈 객체 {} details가 표시되던 버그 수정.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 카테고리를 하드코딩 대신 DB에서 조회하도록 변경 (GET /admin/logs/categories)
- 카테고리 칩을 체크박스 멀티셀렉트 드롭다운으로 교체
- 카테고리가 없을 때 드롭다운 비활성화
- DatePicker에 min/max/compact prop 추가 (날짜 범위 제한, 높이 통일)
- 날짜 선택 칸 너비 축소, 초기화 버튼 여백 축소
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
X 봇 설정에서 트윗 내 YouTube 링크 자동 추출 기능을 온/오프 가능하게 함:
- bot_x 테이블에 extract_youtube 컬럼 추가 (기본값: false)
- 고급 설정에 "YouTube 영상 추출" 토글 추가
- extractYoutube가 true일 때만 YouTube 일정 자동 생성
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- include_retweets 옵션으로 리트윗 포함 여부 설정 가능
- 고정된 트윗(pinned)은 기본적으로 파싱에서 제외
- XBotDialog에서 Twitter 아이콘을 X 아이콘으로 변경
- schedule_x의 username을 source_name으로 활용
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend:
- bot_x 테이블에 text_filters 컬럼 추가
- syncNewTweets/syncAllTweets에 텍스트 필터링 로직 적용
- 봇 추가 시 전체 트윗 동기화 수행 (백그라운드)
- X 봇 API에 text_filters 필드 처리
Frontend:
- XBotDialog에 고급 설정 (키워드 필터) UI 추가
- BotTableRow에서 X 봇 수정/삭제 버튼 활성화
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 채널 핸들로 채널 정보 조회 API 추가 (POST /youtube-bots/lookup)
- getChannelByHandle 함수 추가 (YouTube API forHandle 사용)
- 봇 추가 시 채널 조회 후 배너 이미지 표시
- 봇 수정 API 스키마에 null 허용 추가
- 삭제 확인 다이얼로그 및 삭제 기능 구현
- 디버깅 로그 제거
Co-Authored-By: Claude <noreply@anthropic.com>
- YouTube 봇 전용 API 라우트 추가 (GET/POST/PUT/DELETE /api/admin/youtube-bots)
- 봇 목록 API에 YouTube 봇 상세 정보 포함 (db_id, channel_id 등)
- 수정 다이얼로그에서 useQuery로 봇 데이터 조회
- 채널 배너 이미지 표시 추가
- Fastify 스키마에 additionalProperties 설정으로 auto_schedule_config 정상 반환
Co-Authored-By: Claude <noreply@anthropic.com>
- YouTube 봇 설정을 bots.js에서 youtube_bots 테이블로 이동
- 봇 ID를 AUTO_INCREMENT로 변경 (youtube-{id} 형식)
- 고정 멤버 다중 선택 지원 (default_member_ids JSON)
- 제목 필터 다중 키워드 지원 (title_filters JSON)
- Redis 캐싱 제거 (Activities API 사용으로 불필요)
- 채널 배너 URL DB 저장 (youtube_bots.banner_url)
- YouTubeBotDialog UI 개선:
- Portal 기반 드롭다운 (overflow 문제 해결)
- AnimatePresence 애니메이션 적용
- 다중 선택 컴포넌트 추가
- 태그 입력 형태의 제목 필터
- 뒷배경 클릭 방지
Co-Authored-By: Claude <noreply@anthropic.com>
- WordItem, ScheduleDict 드롭다운 z-index를 z-20에서 z-40으로 변경
(테이블 헤더의 z-30보다 높게 설정하여 가려지는 문제 해결)
- YouTubeBotDialog에 커스텀 Dropdown 컴포넌트 추가
- 네이티브 select 요소를 커스텀 드롭다운으로 교체
- 시간 선택을 위한 TIME_OPTIONS (00:00~23:00) 추가
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 채널 핸들 입력 및 조회 기능 (UI만)
- 동기화 간격 선택
- 예정 일정 자동 생성 설정 (요일, 시간, 제목 템플릿, 마감 요일)
- 고급 설정 (제목 필터, 멤버 추출)
- 추가/수정 모드 지원
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Meilisearch: 리스트형 (BotListItem) - 한 줄에 모든 정보
- YouTube: 미니 카드형 (BotMiniCard) - 호버시 액션 버튼
- X: 테이블형 (BotTableRow) - 표 형식으로 정보 비교
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- createConcertSchedule API 함수 추가
- handleSubmit에서 FormData 구성 및 API 호출 구현
- 유효성 검사 및 저장 성공 시 목록으로 이동
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 세트리스트 섹션: 곡명, 앨범명, 참여 멤버 선택
- 곡 검색 다이얼로그: 앨범별 트랙 검색 및 다중 선택
- 직접 입력과 곡 검색 두 가지 방식으로 곡 추가 가능
- 공연 일정/세트리스트 추가 버튼을 하단으로 이동
- ConfirmDialog에 createPortal 적용
- 콘서트 정보 → 공연 정보로 명칭 변경
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 콘서트 정보 섹션: 공연명, 포스터, 참여 멤버 선택
- 공연 일정 섹션: 다회차 지원 (날짜, 시간, 장소)
- VenueSearchDialog 컴포넌트 추가 (국내/해외 장소 검색)
- 회차 추가/삭제 애니메이션 적용
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Watchtower 제외 라벨 추가하여 자동 업데이트 방지
- 버전 체크 방식 제거, 매일 12시 전체 동기화로 변경
- 봇 관리 UI를 다른 봇들과 동일하게 통일 (버전 → 업데이트 간격)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- DebutCard 컴포넌트 추가 (PC/모바일)
- DebutCelebrationDialog 축하 다이얼로그 추가
- Fromis9Logo SVG 컴포넌트 추가
- 기념일 카테고리 추가 (ID: 9)
- 데뷔일(2018.01.24) 및 주년 일정 자동 생성
- 폭죽 효과 추가 (fireDebutConfetti)
- 카테고리 정보 DB에서 동적 조회하도록 개선
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- DB: music_video_url을 video_url로 변경, video_type 컬럼 추가
- 백엔드: insertTracks에서 video_url, video_type 처리
- 관리자: 영상 타입 선택 드롭다운 추가 (뮤직비디오/스페셜 영상)
- CustomSelect: {value, label} 객체 옵션 및 size prop 지원
- 트랙 상세: video_type에 따른 라벨 동적 표시
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- datetime 필드를 date와 time 필드로 분리하여 00:00 시간도 정상 표시되도록 수정
- 백엔드: formatSchedule, Meilisearch 검색 결과, 스키마 업데이트
- 프론트엔드: datetime 파싱 로직 제거, date/time 직접 사용
- 문서: API 응답 예시 업데이트
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- date.js: nowKST() 함수 추가
- 모든 타임스탬프를 UTC에서 KST(+09:00)로 변경
- scheduler.js, bots.js, x/index.js, logger.js, app.js
- Meilisearch 봇에 동기화 소요 시간(ms) 추적 추가
- BotCard.jsx: 중복된 마지막 동기화 대신 소요 시간 표시
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- scheduler.js: cron.schedule에 timezone: 'Asia/Seoul' 옵션 추가
- bots.js: Meilisearch 봇 API에 버전 정보 추가
- BotCard.jsx: Meilisearch 봇 카드에 마지막 동기화 시간, 동기화 수, 버전 표시
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 로그인 Rate Limit 추가 (5회/분, 마지막 시도 기준 리셋)
- Multipart JSON 파싱 에러 처리 추가
- 로그아웃 시 무한 리다이렉트 버그 수정
- 인증 라우트 가드(RequireAuth) 추가로 비로그인 접근 차단
- Zustand hydration 대기로 페이지 깜빡임 해결
- admin/public 라우트 조건부 렌더링으로 경로 매칭 경고 해결
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>