Commit graph

58 commits

Author SHA1 Message Date
5f9f9789aa feat: 관리자 404 에러 페이지 추가
- pages/pc/admin/common/NotFound.jsx 생성
- AdminLayout 사용, 대시보드 이동 버튼 포함
- App.jsx에 /admin/* catch-all 라우트 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 23:03:18 +09:00
6a96b8a5f9 refactor: CATEGORY_ID 하드코딩 제거 및 봇 관리 페이지 애니메이션 추가
- constants/index.js에서 CATEGORY_ID 상수 삭제
- 카테고리 API 데이터의 name으로 비교하도록 변경 (유튜브, X)
- 봇 관리 페이지에 stagger 애니메이션 및 AnimatedNumber 추가
- admin/schedules API 경로 수정 (/admin/schedules/:id → /schedules/:id)
- authApi export 누락 수정
- 문서 업데이트 (Phase 1 완료, 관리자 에러 페이지 추가 예정)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 22:04:37 +09:00
b314b70014 refactor: 프론트엔드 개선 계획 수립
- 기존 마이그레이션 문서 삭제 (admin-migration.md, frontend-refactoring.md, migration.md)
- 새로운 개선 계획서 작성 (frontend-improvement.md)
- constants 정리: CATEGORY_NAMES, ALBUM_TYPES, 불필요한 SNS 링크 삭제
- schedule.js: getMemberList에서 쉼표 구분 로직 제거

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 21:30:28 +09:00
1d5626568a feat: 일정 추가 폼 카테고리별 분기 마이그레이션
- form/index.jsx: 카테고리 선택 메인 페이지
- form/YouTubeForm.jsx: YouTube URL 기반 일정 추가
- form/XForm.jsx: X 게시글 ID 기반 일정 추가
- form/components/CategorySelector.jsx: 카테고리 선택기
- edit/YouTubeEditForm.jsx: YouTube 일정 수정 폼
- App.jsx 라우트 업데이트
  - /admin/schedule/new → 새로운 카테고리 선택 폼
  - /admin/schedule/new-legacy → 기존 레거시 폼
  - /admin/schedule/youtube/:id/edit → YouTube 수정 폼

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 21:11:59 +09:00
9515db712d feat: 전체 멤버인 경우 '프로미스나인'으로 표시
- 백엔드: buildMemberMap, getScheduleDetail 함수에서 현재 활동 멤버 전원인 경우
  "프로미스나인"으로 대체하여 반환
- 프론트엔드: getDisplayMembers 함수에서 멤버 수 계산 로직 제거 (백엔드에서 처리)
- 탈퇴 멤버(is_former=1) 제외하고 현재 활동 멤버만 계산

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 20:42:05 +09:00
ff5c168529 docs: admin-migration.md 5단계 일정 관리 완료 체크
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 20:36:16 +09:00
7dc3ec692e feat: 관리자 페이지 마이그레이션 완료 (Phase 4-5)
- 관리자 페이지 폴더 구조 재구성 (pages/pc/admin/)
  - login/, dashboard/, members/, albums/, schedules/
- 앨범 관리 페이지 마이그레이션 (Albums, AlbumForm, AlbumPhotos, AlbumTeasers)
- 일정 관리 페이지 마이그레이션 (Schedules, ScheduleForm, ScheduleCategory, ScheduleDict, ScheduleBots)
- DatePicker 컴포넌트 버그 수정 (월 이동 및 연도 선택)
- 일정 관리 라우트 경로 수정 (/admin/schedule)
- 마이그레이션 문서 업데이트

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 20:35:05 +09:00
f64f6cee00 feat: 관리자 간단한 페이지 마이그레이션 (Phase 3)
- AdminDashboard 페이지 추가
- AdminMembers 페이지 추가
- AdminMemberEdit 페이지 추가
- useToast 훅 추가
- App.jsx에 관리자 라우트 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 19:03:21 +09:00
4a26369dff refactor: 관리자 기반 설정 마이그레이션 (Phase 2)
- 관리자 API 추가 (albums, members, schedules, categories, stats, suggestions, bots)
- AdminLayout/Header 컴포넌트 추가
- 공통 컴포넌트 추가 (ConfirmDialog, DatePicker, TimePicker, NumberPicker)
- AdminLogin 페이지 마이그레이션
- App.jsx에 관리자 라우트 추가 (/admin)
- ScheduleDetail.jsx import 경로 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 18:44:15 +09:00
58f359adfa docs: 관리자 마이그레이션 계획서 추가 및 완료된 문서 삭제
- 관리자 페이지 마이그레이션 계획서 추가 (admin-migration.md)
- 완료된 백엔드 리팩토링 문서 삭제
- 완료된 코드 개선 문서 삭제
- 파비콘 복사

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 18:27:52 +09:00
772eda21e0 docs: 코드 개선 문서 최종 업데이트
- 3.7 리스트 key 검토 완료 (정적 리스트는 index 유지, 동적은 고유 ID 사용 중)
- 품질 점수 요약 업데이트 (6/10 → 8.5/10 달성)
- 모든 Phase 완료 표시

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 16:33:12 +09:00
a0fc67adae refactor: Low 우선순위 코드 품질 개선
- constants에 GROUP_INFO 상수 추가 (데뷔일, 팬덤명)
- PC Home에서 멤버 수 동적 계산 (API 기반)
- mobile/Layout.jsx 컴포넌트 분리 (Header.jsx, BottomNav.jsx)
- 미사용 유틸리티 함수는 관리자 페이지용으로 유지

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 16:30:39 +09:00
116d41ff07 refactor: Medium 우선순위 코드 품질 개선
- API client: fetchFormData에 requireAuth 옵션 추가
- API client: HTTP 헬퍼 함수를 팩토리 함수로 통합 (api, authApi)
- useMediaQuery: 리스너 핸들러 useCallback 메모이제이션
- useCalendar: 반환 객체 useMemo 메모이제이션
- schedule.js: date.js의 extractDate/extractTime 재사용
- format.js: decodeHtmlEntities 순수 함수화 (SSR 호환)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 14:25:20 +09:00
21639171e1 fix(lightbox): X 버튼 이벤트 버블링 및 닫기 애니메이션 수정
- PC Lightbox X 버튼에 e.stopPropagation() 추가 (이중 닫힘 방지)
- MobileLightbox AnimatePresence 구조 수정 (exit 애니메이션 활성화)
- 모바일 앨범 상세/갤러리 페이지에 헤더 표시 (hideHeader → pageTitle)
- 문서에 MobileLightbox 컴포넌트 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 14:21:56 +09:00
57d4f1dd5c refactor: High 우선순위 코드 품질 개선
- utils/youtube.js: YouTube URL 파싱 유틸리티 생성
  - getYoutubeVideoId, getYoutubeThumbnail, getYoutubeEmbedUrl
- utils/format.js: parseCredits, calculateTotalDuration 함수 추가
- hooks/useLightbox.js: 라이트박스 상태 관리 훅 생성
- components/common/ErrorMessage.jsx: 에러 메시지 컴포넌트 생성
- components/common/Loading.jsx: size prop 추가 (sm, md, lg)
- TrackDetail (PC/Mobile): 중복 함수 제거, 유틸리티 사용
- AlbumDetail (PC/Mobile): getTotalDuration -> calculateTotalDuration 유틸리티 사용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 12:40:31 +09:00
72b3800ce7 docs: frontend-refactoring.md 진행 상황 업데이트
- NotFound 페이지 완료 표시
- Phase 9-2 코드 품질 개선 단계 추가
- code-improvements.md 참조 링크 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 12:27:13 +09:00
0ce67d57e8 docs: 코드 품질 개선 사항 문서 추가
- code-improvements.md 생성: 전체 코드 검토 결과 정리
- Critical/High/Medium/Low 우선순위별 개선 사항 분류
- 구체적인 문제점과 해결방법 코드 예시 포함
- migration.md에서 useToast를 관리자 영역으로 이동

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 12:22:08 +09:00
276ef509f0 feat: NotFound (404) 페이지 추가
- PC/Mobile 404 페이지 구현
- App.jsx에 catch-all 라우트 추가
- pages/common/ 폴더 구조 생성

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 12:10:57 +09:00
9d1f54c68a refactor: 컴포넌트 폴더 구조 정리
- PC 컴포넌트를 components/pc/로 이동 (Calendar, ScheduleCard, BirthdayCard, CategoryFilter)
- Mobile 컴포넌트를 components/mobile/로 이동 (Mobile 접두사 제거)
- components/schedule/에는 공용 코드만 유지 (confetti.js, AdminScheduleCard)
- Schedule, Home 페이지의 import 경로 업데이트
- 관련 문서 업데이트

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 12:08:47 +09:00
4dcd79504d chore: docs 파일 정리 및 불필요한 파일 삭제
- docs/refactoring.md → docs/backend-refactoring.md 이름 변경
- frontend-temp/package-lock.json 삭제

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 00:49:46 +09:00
e0ab3ce0f8 fix(backend): getUpcomingSchedules 응답 형식 통일
- getUpcomingSchedules가 getMonthlySchedules와 동일한 날짜별 그룹화 형식 반환
- routes/schedules 응답 스키마에 oneOf 추가 (객체/배열 둘 다 허용)
- docs/architecture.md, migration.md 업데이트

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 20:10:26 +09:00
fe067ca8c8 feat(frontend): Phase 4 - API 계층 구현
- api/client.js: fetch 래퍼, ApiError, 헬퍼 함수 (get/post/put/del)
- api/auth.js: 로그인, 토큰 검증
- api/schedules.js: 스케줄/카테고리 API (공개 + 어드민)
- api/albums.js: 앨범 API (공개 + 어드민)
- api/members.js: 멤버 API (공개 + 어드민)
- docs: useQuery 사용 가이드라인 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 17:17:56 +09:00
3ee41beb46 feat(backend): Redis 캐시 확대 - 카테고리, 앨범 목록/상세 캐싱
캐시 적용:
- 카테고리 목록: 1시간 TTL
- 앨범 목록: 10분 TTL
- 앨범 상세: 10분 TTL

캐시 무효화:
- 앨범 생성/수정/삭제 시 자동 무효화
- invalidateAlbumCache 함수 추가

utils/cache.js:
- TTL 상수 추가 (SHORT, MEDIUM, LONG, VERY_LONG)
- 앨범 관련 캐시 키 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 16:16:09 +09:00
a62cf7142b refactor(backend): 21단계 검색 페이징 최적화 - 중복 slice 제거
- services/meilisearch: 내부 SEARCH_LIMIT(1000)과 페이징 파라미터 분리
- services/meilisearch: 기본 limit을 100으로 변경
- routes/schedules: handleSearch에서 중복 slice 제거, 직접 offset/limit 전달

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 16:04:07 +09:00
bfdbc08405 refactor(backend): 20단계 서비스 레이어 확대 - schedules 로직 분리
- services/schedule.js: getCategories, getScheduleDetail 함수 추가
- routes/schedules/index.js: 서비스 호출로 변경 (약 70줄 감소)
- 일관된 서비스 패턴 적용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 16:02:44 +09:00
3f27b1f457 refactor(backend): 19단계 Redis 캐시 확대 - 멤버 목록 캐싱
- utils/cache.js 생성: getOrSet, invalidate, invalidatePattern, cacheKeys
- services/member.js: getAllMembers에 Redis 캐시 적용 (10분 TTL)
- services/member.js: invalidateMemberCache 함수 추가
- routes/members: 캐시 사용 및 수정 시 캐시 무효화

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 16:01:12 +09:00
fec2a4455c refactor(backend): 18단계 이미지 처리 최적화 - 메타데이터 중복 조회 제거
- processImage: includeMetadata 옵션 추가
- processImage: sharp 인스턴스 재사용 (clone() 사용)
- uploadAlbumPhoto: 중복 sharp(originalBuffer).metadata() 제거

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 15:59:14 +09:00
b0ac0e51e4 refactor(backend): 17단계 중복 코드 제거 - 멤버/앨범 조회 서비스 분리
- services/member.js 생성: getAllMembers, getMemberByName, getMemberBasicByName
- services/album.js에 getAlbumByName, getAlbumById 추가
- routes/members/index.js 서비스 호출로 변경 (약 50줄 감소)
- routes/albums/index.js 서비스 호출로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 15:58:08 +09:00
5cc258b009 refactor(backend): 16단계 에러 처리 일관성 - schedules 라우트 try/catch 추가
모든 핸들러에 try/catch 블록 적용:
- GET /categories
- GET / (검색/월별/다가오는 일정)
- POST /sync-search
- GET /:id
- DELETE /:id

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 15:56:10 +09:00
f483f2cf53 refactor(backend): 트랜잭션 헬퍼, JSON 스키마 추가 및 스키마 파일 분리
- src/utils/transaction.js: withTransaction 헬퍼 함수 추가
- src/schemas/: 도메인별 스키마 파일 분리 (common, album, schedule, admin, member, auth)
- 라우트에 JSON Schema 검증 및 Swagger 문서화 적용
- 트랜잭션 패턴을 withTransaction 헬퍼로 추상화

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 14:58:07 +09:00
2d7d82baf3 refactor(backend): 대형 핸들러 서비스로 분리
- createAlbum, updateAlbum, deleteAlbum 서비스 함수 추가
- insertTracks 배치 삽입 헬퍼 함수
- albums/index.js POST/PUT/DELETE → 서비스 호출로 변경
- routes 파일 80줄 감소

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 14:22:45 +09:00
7b227a6c56 refactor(backend): 로거 통일
- utils/logger.js 생성 (createLogger)
- 서비스 레이어: logger 유틸리티 사용
- 라우트 레이어: fastify.log 사용
- console.error/log → 구조화된 로깅으로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 14:20:32 +09:00
f719fd9259 refactor(backend): 응답 형식 통일
- suggestions.js: {success, message} → {error} 또는 {message} 형식

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 14:14:29 +09:00
44e3878f2d refactor(backend): meilisearch 카테고리 ID 상수화
- 하드코딩된 2, 3 → CATEGORY_IDS.YOUTUBE, CATEGORY_IDS.X

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 14:13:18 +09:00
0a91d04992 refactor(backend): 순차 쿼리 → 병렬 처리
- getAlbumDetails: tracks/teasers/photos 쿼리 Promise.all로 병렬 실행
- photos.js: 멤버 INSERT for loop → VALUES 배치 처리

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 14:12:27 +09:00
c3e504d1e3 refactor(backend): 매직 넘버 config 이동
- 이미지 크기/품질 설정 (800x85, 400x80) → config.image
- X 기본 사용자명 'realfromis_9' → config.x.defaultUsername
- Meilisearch 최소 점수 0.5 → config.meilisearch.minScore

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 14:11:35 +09:00
7593004bd6 refactor(backend): 중복 코드 제거
- scheduler.js: handleSyncResult 함수 추출로 동기화 결과 처리 로직 통합
- youtube/index.js: 하드코딩된 카테고리 ID를 CATEGORY_IDS 상수로 변경
- 리팩토링 문서 업데이트

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 13:45:08 +09:00
2f30c67b93 refactor(backend): 에러 처리 통일
- src/utils/error.js 생성: 에러 응답 유틸리티 함수들
- reply.status() → reply.code() 통일 (auth, members, stats)
- Fastify 표준 에러 응답 패턴 적용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 13:43:26 +09:00
430bf38c91 refactor(backend): 서비스 레이어 분리
- src/services/album.js 생성: getAlbumDetails, getAlbumsWithTracks
- src/services/schedule.js 생성: getMonthlySchedules, getUpcomingSchedules
- albums/index.js, schedules/index.js에서 서비스 사용으로 변경
- schedules/index.js에서 중복 함수 제거 (240줄 감소)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 13:42:01 +09:00
b61bfe93b4 refactor(backend): 설정 통합 및 N+1 쿼리 최적화
- 카테고리 ID 상수를 config/index.js에 CATEGORY_IDS로 통합
- youtube.js, x.js, schedules/index.js에서 하드코딩된 ID를 상수로 교체
- 앨범 목록 조회 시 N+1 쿼리 문제 해결 (트랙 한 번에 조회)
- 리팩토링 작업 문서 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 13:38:25 +09:00
9eb49929c7 YouTube 섹션 스타일 개선 및 문서 업데이트
- PC/모바일 YouTube 상세 페이지 그림자 감소, 배경색 조정
- 모바일 YouTube 섹션을 카드에서 배경 스타일로 변경
- 문서 업데이트: 완료된 마이그레이션 작업 반영, 누락된 API 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 12:57:25 +09:00
a1090e56c0 문서 업데이트: 프론트엔드 구조에 컴포넌트 및 유틸리티 추가
- components/common/ (Lightbox, LightboxIndicator)
- utils/date.js (dayjs 기반 날짜 유틸리티)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 12:11:36 +09:00
8bcd3e881d docs: API 문서 업데이트
- GET /schedules에 startDate 파라미터 추가
- 다가오는 일정 조회 응답 형식 문서화
- PUT /admin/youtube/schedule/:id 문서 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 17:28:50 +09:00
4a4a163abe feat: YouTube 일정 수정 폼 구현
- 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>
2026-01-20 14:06:02 +09:00
bc3f536ec7 feat: X 카테고리 일정 추가 폼 구현
- 백엔드: /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>
2026-01-19 12:57:06 +09:00
0a73149849 feat: 일정 추가 페이지 카테고리별 폼 분리 (YouTube)
- 카테고리 선택 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>
2026-01-19 12:49:29 +09:00
c7b0a51924 feat: YouTube API 할당량 절감을 위한 playlist ID 캐싱
- 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>
2026-01-19 12:32:04 +09:00
d7d0506b83 docs: named volume 제거 반영
- node_modules 호스트 설치 설명 추가
- 완전 재시작 명령어에서 -v 플래그 제거

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 09:59:51 +09:00
a9bdbd1ec2 chore: docker-compose.yml 불필요한 주석 제거
- 배포 모드 관련 주석 제거 (Dockerfile에서 처리)
- VITE_API_URL 환경변수 제거 (Vite 프록시 사용)
- 문서 업데이트

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 09:56:20 +09:00
8a8af275a9 docs: 컨테이너 분리 반영하여 개발 가이드 업데이트
- 컨테이너 구성 표 추가
- 개별 컨테이너 로그/재시작 명령어 추가
- 배포 모드 Dockerfile 예시 분리
- 네트워크 구조 다이어그램 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 09:51:26 +09:00