- PC/모바일 앨범 상세, 갤러리 페이지에 뒤로가기 처리
- PC/모바일 X 일정 상세 페이지에 뒤로가기 처리
- 라이트박스 열릴 때 history.pushState 호출
- popstate 이벤트로 라이트박스 닫기
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- API 응답 형식 변경 (category_id → category.id)
- X 일정에 content, imageUrls, postUrl, profile 필드 추가
- 본문 내 URL 자동 하이퍼링크 추가 (react-linkify)
- PC/모바일 ScheduleDetail에서 새 API 형식 사용
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- GET /schedules에 startDate 파라미터 추가
- 다가오는 일정 조회 응답 형식 문서화
- PUT /admin/youtube/schedule/:id 문서 추가
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 백엔드에 startDate 파라미터 지원 추가 (다가오는 일정 조회)
- handleUpcomingSchedules 함수 구현
- 메인 페이지 일정 카드 디자인을 일정 페이지와 동일하게 변경
- 멤버 표시 로직 API 응답에 맞게 수정 (PC/모바일)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 멤버 페이지에서 포지션 영역 제거 (PC/모바일)
- 모바일 일정 페이지 멤버 표시 로직 API 응답에 맞게 수정
- 데이트픽커 연도 제한 2025 → 2017로 변경
- 2017년 1월에서 이전 달 버튼 비활성화
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- YouTube 일정 수정 API (PUT /api/admin/youtube/schedule/:id)
- 멤버 선택, 영상 유형(video/shorts) 수정 기능
- 일정 API에 멤버 배열 추가 (5명 이상 시 "프로미스나인")
- 관리 페이지 React Query 캐싱 적용
- Shorts/Video 별 UI 레이아웃 분리
- React Query 사용 가이드 문서화
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 봇 lastAddedCount를 실제 추가시에만 업데이트 (0으로 덮어쓰지 않음)
- 일정 추가 폼 애니메이션 타이밍 개선 (첫 로딩: 딜레이, 카테고리 변경: 즉시)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 생일이 생년 이전 년도에 표시되는 버그 수정
- 페이지 진입 애니메이션 추가 (사전 관리, 일정 추가)
- 데이트픽커 12년 단위 이동으로 변경
- 년도 선택 시 월 선택 화면 전환 제거
- 시작 년도 2025년 고정, 이전 이동 비활성화
- PC/모바일 일정 페이지, 관리자 페이지 모두 적용
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 백엔드: /api/admin/x/post-info, /api/admin/x/schedule API 추가
- scraper.js에 fetchSingleTweet 함수 추가 (Nitter로 단일 트윗 조회)
- 프론트엔드: XForm 컴포넌트 생성 (게시글 ID 입력 → 미리보기 → 저장)
- 일정 추가 폼에서 X 카테고리 분기 추가
- API 문서 업데이트
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 카테고리 선택 UI를 최상단으로 이동
- YouTube 카테고리 전용 폼 추가 (URL 입력 → 자동 정보 조회)
- 폴더 구조 분리: pages/pc/admin/schedule/form/
- API 추가:
- GET /schedules/categories (카테고리 목록)
- DELETE /schedules/:id (일정 삭제)
- GET /admin/youtube/video-info (영상 정보 조회)
- POST /admin/youtube/schedule (YouTube 일정 저장)
- fetchApi에서 body 없는 요청 시 Content-Type 미설정
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- uploads playlist ID를 Redis에 영구 캐싱 (불변값)
- 일일 API 사용량 6,480 → 4,320 units (33% 절감)
- 문서 업데이트 (컨테이너 분리 구조, X source.name 빈 문자열)
- CLAUDE.md에 문서 업데이트 필수 안내 추가
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- x_profiles 테이블 생성 (username, display_name, avatar_url)
- saveProfile 함수로 DB + Redis 캐시 동시 저장
- getProfile 함수 Redis → DB 폴백 지원
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 모바일 Schedule.jsx: category 객체 형식 지원 (category.id, category.name 등)
- 백엔드 API: X 일정의 source.name을 빈 문자열로 변경
- Meilisearch: 검색 결과도 source 객체 형식으로 통일
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- vite.config.js: localhost:3000 → fromis9-backend:80
- docker-compose.yml: depends_on, VITE_API_URL 수정
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- backend/Dockerfile 생성
- frontend/Dockerfile 생성
- docker-compose.yml에 별도 서비스로 분리
- 기존 루트 Dockerfile 삭제
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- SQL GREATEST()로 동적 임계값 적용
- MAX(count) * 1% 또는 최소 10회 중 더 큰 값 사용
- Prefix, 초성, 인기 검색어 모두 필터링 적용
- 데이터가 적을 때도 오타 필터링 가능
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- GET /admin/bots: 봇 목록 조회
- POST /admin/bots/:id/start: 봇 시작
- POST /admin/bots/:id/stop: 봇 정지
- POST /admin/bots/:id/sync-all: 전체 동기화
- GET/DELETE /admin/bots/quota-warning: 할당량 경고
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 봇 관리 API 엔드포인트 추가 (routes/admin/bots.js)
- GET /api/admin/bots: 봇 목록 조회
- POST /api/admin/bots/:id/start: 봇 시작
- POST /api/admin/bots/:id/stop: 봇 정지
- POST /api/admin/bots/:id/sync-all: 전체 동기화
- GET/DELETE /api/admin/bots/quota-warning: 할당량 경고
- 프론트엔드 API 엔드포인트 경로 수정
- 봇 업데이트 시간 UTC → 로컬 시간 변환 수정
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- source_name, source_url → source: { name, url } 형태로 변경
- YouTube: schedule_youtube에서 video_id로 URL 생성
- X: schedule_x에서 post_id로 URL 생성
- 프론트엔드 전체 파일 source 객체 형태로 수정
- 문서 업데이트 (api.md, architecture.md, migration.md 등)
- tracks → album_tracks 테이블명 변경 반영
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Meilisearch 기반 일정 검색 API 구현
- 멤버 별명으로 검색 지원 (하냥 → 송하영)
- 영문 자판 → 한글 변환 검색 지원
- 검색 응답 구조 개선 (category 객체, datetime 통합, members 배열)
- 개발/배포 환경 Dockerfile 통합 (주석 전환 방식)
- docker-compose.yml 단일 파일로 통합
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 형태소 분석기 사용자 사전 관리 페이지 추가
- 단어 추가/삭제/수정 시 즉시 저장 및 형태소 분석기 리로드
- 품사별 통계 및 필터링 기능
- 검색 기능 추가
백엔드:
- GET/PUT /api/schedules/suggestions/dict API 추가
- morpheme.js에 reloadMorpheme(), getUserDictPath() 함수 추가
프론트엔드:
- AdminScheduleDict.jsx 페이지 추가
- AdminSchedule.jsx에 사전 관리 버튼 추가
- 라우트 추가 (/admin/schedule/dict)
Co-Authored-By: Claude <noreply@anthropic.com>
- kiwi-nlp 기반 한국어 형태소 분석기 추가
- 추천 검색어 API 구현 (/api/schedules/suggestions)
- Prefix 매칭, Bi-gram 다음 단어 예측
- 초성 검색 지원, 영문→한글 자동 변환 (Inko)
- 사용자 사전 추가 (멤버/그룹명, 프로그램명 등)
- DB 테이블: suggestion_queries, suggestion_word_pairs, suggestion_chosung
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- API 응답(날짜별 그룹화)을 플랫 배열로 변환하는 로직 추가
- 별도 카테고리 API 호출 제거, 일정 데이터에서 카테고리 추출
- PC/모바일 Schedule.jsx, AdminSchedule.jsx 수정
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- GET /api/schedules?year=&month= 월별 일정 조회
- 날짜별 그룹화 + 카테고리 목록/개수 포함
- 유튜브 카테고리의 경우 source_name(채널명) 반환
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- /api/admin/* + /api/* 분리 구조를 /api/*로 통합
- GET 요청은 공개, POST/PUT/DELETE는 인증 필요로 변경
- albums 라우트를 기능별 파일로 분리 (index, photos, teasers)
- 프론트엔드 API 호출 경로 업데이트
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- /api/admin/stats 라우트 추가 (멤버, 앨범, 사진, 일정, 트랙 수)
- AdminDashboard에서 단일 API 호출로 통계 조회
- useQuery로 변경하여 중복 요청 방지
- AnimatedNumber 컴포넌트에 3자리 쉼표 및 애니메이션 적용
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- AdminAlbums.jsx: useQuery로 앨범 목록 조회, 삭제 후 캐시 무효화
- AdminAlbumForm.jsx: useQuery로 앨범 상세 조회, 저장 후 캐시 무효화
- AdminAlbumPhotos.jsx: useQuery로 앨범/사진/티저/멤버 조회
- backend: 정적 파일 서빙 추가 (프로덕션 모드용)
- backend: 앨범 라우트에 인증 미들웨어 적용
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend:
- 앨범 CRUD API 구현 (목록, 상세, 생성, 수정, 삭제)
- 앨범 사진 관리 API 구현 (업로드, 삭제, 티저 관리)
- 이미지 서비스에 앨범 관련 함수 추가
- Public 라우트 추가 (앨범, 멤버 공개 API)
Frontend:
- AdminAlbums.jsx admin API로 변경
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 8개 어드민 페이지에서 중복된 인증 코드 제거
- localStorage 직접 접근 → useAdminAuth 훅 사용
- authApi.hasToken()/verifyToken() 호출 제거
- 일관된 인증 상태 관리 (5분 캐시, 자동 리다이렉트)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend:
- 멤버 CRUD API 추가 (routes/admin/members.js)
- 이미지 업로드 서비스 추가 (services/image.js)
- S3에 3가지 해상도로 저장 (original, medium_800, thumb_400)
- multipart 플러그인 등록
Frontend:
- useAdminAuth 커스텀 훅 추가 (토큰 검증 API 사용)
- AdminMembers, AdminMemberEdit useQuery로 변경
- 로그인 확인 로직 중복 제거
- 수정 완료 시 목록 페이지로 이동 및 토스트 표시
Co-Authored-By: Claude <noreply@anthropic.com>
- API 연동 임시 제거, 더미 데이터로 대체
- position 필드 제거
- 별명(nicknames) 태그 입력 UI 추가
- DB 변경: members 테이블 position/image_url 제거, image_id 추가
- DB 변경: member_nicknames 테이블 생성
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- @fastify/jwt 플러그인 기반 인증 시스템
- POST /api/admin/login: 로그인 (JWT 토큰 발급)
- GET /api/admin/verify: 토큰 검증
- bcrypt 비밀번호 해싱 검증
- JWT 설정 config 분리
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Express → Fastify 5 프레임워크 전환
- 플러그인 기반 아키텍처로 재구성
- plugins/db.js: MariaDB 연결 풀
- plugins/redis.js: Redis 클라이언트
- plugins/scheduler.js: 봇 스케줄러 (node-cron)
- 봇 설정 방식 변경: DB 테이블 → 설정 파일 (config/bots.js)
- 봇 상태 저장: DB → Redis
- YouTube/X 봇 서비스 분리 및 개선
- 날짜 유틸리티 KST 변환 수정
- 미사용 환경변수 정리
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- schedule-sections 폴더 생성
- YoutubeSection, XSection, ConcertSection, DefaultSection 분리
- KakaoMap, utils.js 공통 모듈 분리
- 메인 ScheduleDetail.jsx 1010줄 → 175줄로 간소화
- 히어로 섹션 배경을 포스터 확대 + 블러 효과로 변경
- 회차 선택을 드롭다운 형태로 변경 및 디자인 개선
- 드롭다운 열릴 때 선택된 항목 자동 스크롤
- 장소 카드 디자인 정리 (MapPin 아이콘 사용)
- 지도 높이 2배로 증가 (h-64 → h-[32rem])
- 길찾기 버튼 색상 분기 (카카오맵: #0079f4, 구글맵: #4285F4)
- 글래스모피즘 효과 제거