Commit graph

155 commits

Author SHA1 Message Date
91d4442d30 docs: X 봇 extract_youtube 관련 문서 및 스키마 업데이트
- bot_x.sql에 누락된 컬럼 추가 (text_filters, include_retweets, extract_youtube)
- api.md에 X 봇 API 응답 스키마 및 필드 설명 추가
- architecture.md bot_x 테이블 설명 구체화
- development.md API 클라이언트 함수 목록 보완

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 13:12:00 +09:00
ba7def935c feat(x-bot): YouTube 영상 추출 옵션 추가
X 봇 설정에서 트윗 내 YouTube 링크 자동 추출 기능을 온/오프 가능하게 함:
- bot_x 테이블에 extract_youtube 컬럼 추가 (기본값: false)
- 고급 설정에 "YouTube 영상 추출" 토글 추가
- extractYoutube가 true일 때만 YouTube 일정 자동 생성

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 22:40:52 +09:00
d01f7e60dc fix(schedule): YouTube 일정 상세 조회 쿼리 단순화
- 불필요한 channel_id 선택 제거
- banner_url만 조회하도록 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 22:23:24 +09:00
7d140aa1f3 fix(x-bot): 동기화 결과에 total 필드 추가
- syncNewTweets(), syncAllTweets()에 total 필드 추가
- 프론트엔드 토스트에서 undefined 표시되던 문제 해결

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 09:57:04 +09:00
c86cda00ae fix(meilisearch): 전체 동기화 시 DB에 없는 문서 삭제
- syncAllSchedules()에서 Meilisearch의 모든 문서 ID 조회
- DB에 없는 문서는 Meilisearch에서 삭제
- 삭제된 일정이 검색에 계속 나타나는 문제 해결

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 09:50:54 +09:00
294018c93b refactor(x-bot): x_profiles 테이블 제거, bot_x로 통합
- x_profiles 테이블 삭제 (bot_x에 프로필 정보 포함)
- saveProfile(), getProfile() 함수가 bot_x 테이블 사용하도록 수정
- Redis 캐시는 그대로 유지 (성능)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 09:42:26 +09:00
5d44434e36 feat(x-bot): 리트윗 옵션 및 고정 트윗 제외 기능 추가
- include_retweets 옵션으로 리트윗 포함 여부 설정 가능
- 고정된 트윗(pinned)은 기본적으로 파싱에서 제외
- XBotDialog에서 Twitter 아이콘을 X 아이콘으로 변경
- schedule_x의 username을 source_name으로 활용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 09:37:57 +09:00
9ceef6c656 feat(x-bot): 키워드 필터링 및 전체 동기화 기능 추가
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>
2026-02-08 09:23:45 +09:00
86769f1edc feat(admin): 봇 목록 API에 X 봇 상세 정보 추가
- 스키마에 X 봇 필드 추가 (username, display_name, avatar_url)
- X 봇 응답에 db_id, cron_interval 포함

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 23:56:45 +09:00
25c2b45cf5 feat(scheduler): X 봇 DB 기반 로드 추가
- getXBotsFromDB() 함수 추가
- getAllBots()에서 X 봇도 DB에서 로드
- config/bots.js에서 X 봇 제거 (meilisearch만 남음)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 23:51:38 +09:00
2355068c77 feat(admin): X 봇 CRUD API 추가
- POST /api/admin/x-bots/lookup: 프로필 조회
- GET /api/admin/x-bots: 목록 조회
- GET /api/admin/x-bots/🆔 상세 조회
- POST /api/admin/x-bots: 봇 추가
- PUT /api/admin/x-bots/🆔 봇 수정
- DELETE /api/admin/x-bots/🆔 봇 삭제

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 23:48:58 +09:00
535fbb6768 feat(x): Nitter 프로필 조회 함수 추가
- fetchProfile() 함수 추가: username으로 프로필 정보 조회
- displayName, avatarUrl 반환

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 20:08:59 +09:00
4f11e14b12 refactor(db): 봇 테이블 이름 통일 및 X 봇 스키마 추가
- youtube_bots → bot_youtube, x_bots → bot_x로 테이블 이름 변경
- bot_x 테이블 생성 및 시드 데이터 추가
- 관련 백엔드 코드에서 테이블 참조 업데이트
- X 봇 동적 관리 구현 계획 문서 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 19:52:41 +09:00
2e7fe697fc feat(admin): YouTube 봇 추가/수정/삭제 기능 완성
- 채널 핸들로 채널 정보 조회 API 추가 (POST /youtube-bots/lookup)
- getChannelByHandle 함수 추가 (YouTube API forHandle 사용)
- 봇 추가 시 채널 조회 후 배너 이미지 표시
- 봇 수정 API 스키마에 null 허용 추가
- 삭제 확인 다이얼로그 및 삭제 기능 구현
- 디버깅 로그 제거

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-07 10:51:45 +09:00
ec3839bcc7 feat(admin): YouTube 봇 CRUD API 및 수정 다이얼로그 개선
- 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>
2026-02-07 10:43:06 +09:00
a8c12aa76d feat: YouTube 봇 DB 기반 관리로 마이그레이션
- 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>
2026-02-07 10:15:07 +09:00
730da864a4 fix: YouTube 봇 fetchRecentVideos를 Activities API로 변경
- playlistItems API 대신 Activities API 사용
- playlistItems는 새 영상 반영이 지연되는 문제가 있었음
- Activities API는 새 업로드를 즉시 반영함
- upload 외 다른 활동(좋아요, 플레이리스트 등)도 포함되므로 2배로 조회 후 필터링
- API 할당량 비용은 동일 (1 단위)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 21:58:38 +09:00
46295a5f15 fix: Meilisearch 동기화 시간을 00시로 변경
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 18:06:07 +09:00
f01b2b8054 fix: 유튜브 채널 배너 이미지 고해상도로 변경
- bannerUrl에 =w2560 파라미터 추가하여 2560px 너비로 요청

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:22:45 +09:00
cb184e4fa5 feat: 유튜브 예정 일정에 채널 배너 이미지 표시
- YouTube API에서 채널 정보(배너 이미지) 조회 함수 추가
- 채널 정보 Redis 캐싱 (24시간)
- 일정 상세 API에 bannerUrl 필드 추가
- 예정 일정 placeholder에 배너 이미지 배경 표시

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:20:49 +09:00
b16aa963cd feat: 유튜브 예정 일정 UI 추가
- PC YoutubeSection에 예정 일정 placeholder UI 추가
- 예정 일정일 경우 "예정" 배지 표시
- 영상 준비 중 placeholder 컴포넌트 추가
- 예정 일정에도 channelName 반환하도록 API 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 14:57:58 +09:00
e759d14ed6 feat: 스프 채널 다음 주 예정 일정 자동 생성 기능
- 새 영상(쇼츠 제외) 추가 시 다음 주 같은 요일 예정 일정 자동 생성
- 실제 영상 업로드 시 예정 일정을 실제 정보로 덮어씌움
- 금요일 00시까지 영상 없으면 예정 일정 삭제 + 다음 주 예정 일정 생성
- autoScheduleNext 설정: dayOfWeek, time, title, deadlineDayOfWeek, excludeShorts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 14:51:12 +09:00
48f41c6db0 feat: 장소 검색 API 추가 (카카오/구글)
- 국내: 카카오맵 API (/api/admin/kakao/places)
- 해외: 구글 Places API (/api/admin/google/places)
- YOUTUBE_API_KEY를 GOOGLE_API_KEY로 통합

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 14:06:33 +09:00
65b1d931f3 feat: 콘서트 일정 저장 API 구현
콘서트 폼 데이터를 저장하는 백엔드 API 추가.
multipart/form-data로 포스터, 굿즈 이미지, 회차, 세트리스트를 처리하고
트랜잭션으로 관련 테이블에 일괄 저장 후 Meilisearch 동기화.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 11:48:50 +09:00
83c955f8a9 refactor: Meilisearch 봇을 단순 일일 동기화 방식으로 변경
- Watchtower 제외 라벨 추가하여 자동 업데이트 방지
- 버전 체크 방식 제거, 매일 12시 전체 동기화로 변경
- 봇 관리 UI를 다른 봇들과 동일하게 통일 (버전 → 업데이트 간격)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 11:59:18 +09:00
f97c925fba refactor: 생일 페이지 라우트를 /schedule/:id 형식으로 변경
- /birthday/:memberName/:year → /schedule/birthday-{year}-{nameEn}
- ScheduleDetail에서 특수 ID(birthday, debut, anniversary) 감지
- Birthday 컴포넌트가 props로 year, nameEn 받도록 변경
- 멤버 API가 영문명으로도 조회 가능하도록 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 13:15:04 +09:00
e1ee0b47a0 fix: 특수 일정 ID에 연도 포함
- 생일: birthday-{year}-{name_en} (예: birthday-2025-saerom)
- 데뷔: debut-{year} (예: debut-2018)
- 주년: anniversary-{year} (예: anniversary-2026)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 13:07:39 +09:00
2fec6c552d feat: 봇 일정 추가 시 Meilisearch 실시간 동기화
- syncScheduleById 함수 추가: 개별 일정 동기화
- YouTube 봇: 영상 추가 시 Meilisearch 동기화
- X 봇: 트윗/유튜브 링크 추가 시 Meilisearch 동기화
- description 컬럼 제거 (schedules 테이블에 없음)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 11:26:32 +09:00
ea9922de00 refactor: 일정 정렬 로직을 백엔드로 이동
- 백엔드에서 특수 일정(기념일, 생일) 우선 정렬
- 프론트엔드의 중복 정렬 로직 제거
- 정렬 순서: 날짜 > 특수 일정 > 시간

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 18:30:51 +09:00
5b9d93b37f feat: 데뷔/주년 기념일 카드 및 축하 다이얼로그 추가
- DebutCard 컴포넌트 추가 (PC/모바일)
- DebutCelebrationDialog 축하 다이얼로그 추가
- Fromis9Logo SVG 컴포넌트 추가
- 기념일 카테고리 추가 (ID: 9)
- 데뷔일(2018.01.24) 및 주년 일정 자동 생성
- 폭죽 효과 추가 (fireDebutConfetti)
- 카테고리 정보 DB에서 동적 조회하도록 개선

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 15:04:29 +09:00
5415893f9d 트랙 영상 타입 구분 기능 추가
- 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>
2026-01-24 10:56:12 +09:00
87a69c0cbd refactor: API 응답에서 datetime을 date와 time으로 분리
- datetime 필드를 date와 time 필드로 분리하여 00:00 시간도 정상 표시되도록 수정
- 백엔드: formatSchedule, Meilisearch 검색 결과, 스키마 업데이트
- 프론트엔드: datetime 파싱 로직 제거, date/time 직접 사용
- 문서: API 응답 예시 업데이트

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 10:11:02 +09:00
bdd2dfcd84 feat: 성능 최적화 (Phase 4)
- cache.js: Redis KEYS → SCAN으로 변경 (블로킹 방지)
- suggestions.js: 동기식 파일 I/O → 비동기 변경
  - readFileSync → readFile (fs/promises)
  - writeFileSync → writeFile (fs/promises)
- improvements.md: Phase 4 완료로 업데이트

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 22:04:27 +09:00
85f03cb2d8 타임스탬프 KST 통일 및 Meilisearch 동기화 소요 시간 추가
- 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>
2026-01-23 22:00:58 +09:00
95285634e9 cron 스케줄러 한국 시간대 적용 및 봇 카드 UI 개선
- scheduler.js: cron.schedule에 timezone: 'Asia/Seoul' 옵션 추가
- bots.js: Meilisearch 봇 API에 버전 정보 추가
- BotCard.jsx: Meilisearch 봇 카드에 마지막 동기화 시간, 동기화 수, 버전 표시

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 21:52:01 +09:00
8091f4ac67 feat: Meilisearch 버전 체크 기반 자동 동기화
- 4시~4시 5분간 1분 간격으로 Meilisearch 버전 체크
- watchtower 업데이트로 버전 변경 감지 시 즉시 동기화
- 동기화 오류 시 인덱스 삭제 후 재생성하여 재시도
- 기존 고정 시간(4:05) cron 방식에서 버전 감지 방식으로 변경

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 21:41:05 +09:00
52a655bf76 feat: 외부 서비스 안정성 개선 (Phase 3)
- Nitter 요청에 10초 타임아웃 및 HTTP 상태 코드 검증 추가
- Meilisearch syncAllSchedules에서 불필요한 deleteAllDocuments 제거
  - addDocuments는 같은 ID면 자동 업데이트(upsert)
- 일정 삭제 시 Meilisearch 동기화 코드 정리 (동적 import 제거)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 21:01:35 +09:00
e852f215a3 feat: 보안 강화 및 인증 개선 (Phase 2)
- 로그인 Rate Limit 추가 (5회/분, 마지막 시도 기준 리셋)
- Multipart JSON 파싱 에러 처리 추가
- 로그아웃 시 무한 리다이렉트 버그 수정
- 인증 라우트 가드(RequireAuth) 추가로 비로그인 접근 차단
- Zustand hydration 대기로 페이지 깜빡임 해결
- admin/public 라우트 조건부 렌더링으로 경로 매칭 경고 해결

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:47:05 +09:00
4edef16310 fix: 일정 저장/삭제에 트랜잭션 적용
- youtube/index.js: saveVideo에 withTransaction 적용
- x/index.js: saveTweet, saveYoutubeFromTweet에 withTransaction 적용
- schedules/index.js: DELETE 핸들러에 withTransaction 적용
- 중간 실패 시 자동 롤백으로 데이터 무결성 보장
- docs/improvements.md 문서 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:21:56 +09:00
1c9b30b783 에러 유틸리티 함수를 모든 라우트에 적용
utils/error.js에 정의된 헬퍼 함수들(badRequest, unauthorized, notFound,
conflict, serverError)을 전체 라우트 파일에 적용하여 에러 응답 처리 일관성 확보

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 11:24:42 +09:00
897bdc471c feat: Meilisearch 동기화 봇 추가
- 매일 새벽 4시 5분 자동 재색인 (Watchtower 업데이트 후)
- 봇 관리 페이지에서 수동 동기화 및 시작/정지 가능
- bots.js에 meilisearch 타입 봇 설정 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 11:14:17 +09:00
b8137935c2 refactor: 보안 강화 및 앨범 삭제 로직 개선
- JWT_SECRET 환경변수 필수화 (기본값 제거)
- 앨범 삭제 시 S3 파일(사진, 티저, 비디오) 함께 삭제
- 앨범 삭제 시 관련 DB 테이블 정리 (album_photo_members, album_photos, album_teasers)
- Meilisearch latest 태그로 변경 (v1.6 → latest)
- 코드 리뷰 문서 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 11:00:17 +09:00
2a50a07a29 fix: Meilisearch 검색 결과에서도 전체 멤버 '프로미스나인' 처리
- searchSchedules: 검색 시 현재 활동 멤버 수 캐시
- formatScheduleResponse: 전체 멤버인 경우 '프로미스나인'으로 대체
- syncAllSchedules: 동기화 시 탈퇴 멤버 제외, 멤버 수 캐시 갱신

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 20:56:38 +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
e136f3c74b fix(backend): 검색 결과에서 _rankingScore 제거 및 CORS 설정 추가
변경 사항:
- 검색 API 응답에서 _rankingScore 필드 제거
- @fastify/cors 패키지 추가
- docs.caadiq.co.kr에서 API 테스트 요청 허용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 23:21:24 +09:00
51063a120a refactor(backend): 일정 API 공통 포맷팅 함수로 리팩토링
공통 함수 추가:
- normalizeDate(): 날짜 문자열 정규화
- buildDatetime(): datetime 문자열 생성
- buildSource(): source 객체 생성
- formatSchedule(): 단일 일정 포맷팅
- formatSchedules(): 일정 목록 포맷팅
- buildMemberMap(): 멤버 맵 조회

변경:
- getMonthlySchedules: 공통 함수 사용
- getUpcomingSchedules: 공통 함수 사용
- meilisearch/formatScheduleResponse: buildDatetime 공통 함수 사용

SQL 쿼리도 SCHEDULE_LIST_SQL 상수로 통합

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 23:18:48 +09:00
22ce21f908 refactor(backend): 일정 API 응답 형식을 검색 API와 통일
변경 사항:
- getMonthlySchedules: 날짜별 그룹화 → 플랫 배열
- getUpcomingSchedules: 날짜별 그룹화 → 플랫 배열

새 형식:
{
  "schedules": [
    {
      "id": 123,
      "title": "...",
      "datetime": "2025-01-21T19:00:00",
      "category": { "id": 1, "name": "...", "color": "#..." },
      "source": { "name": "...", "url": "..." },
      "members": ["name1", "name2"]
    }
  ]
}

주요 변경:
- date/time 분리 → datetime 통합
- members: [{ name: "..." }] → ["name1", "name2"]
- categories 카운트 제거
- _rankingScore 없음 (검색 API에만 존재)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 20:47:40 +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
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